ב-Android 9 (רמת API 28) יש כמה שינויים במערכת Android. שינויי ההתנהגות הבאים חלים על כל האפליקציות כשהן פועלות בפלטפורמת Android 9, ללא קשר לרמת ה-API שהן מטרגטות. כל המפתחים צריכים לבדוק את השינויים האלה ולשנות את האפליקציות שלהם כדי לתמוך בהם כראוי, במקרים הרלוונטיים.
כדי לקרוא על שינויים שמשפיעים רק על אפליקציות שמטרגטות לרמת API 28 ומעלה, אפשר לעיין במאמר שינויים בהתנהגות: אפליקציות שמטרגטות לרמת API 28 ומעלה.
ניהול צריכת החשמל
ב-Android 9 יש תכונות חדשות לשיפור ניהול צריכת החשמל במכשיר. השינויים האלה, יחד עם תכונות שכבר היו קיימות לפני Android 9, עוזרים לוודא שמשאבי המערכת יהיו זמינים לאפליקציות שהכי זקוקות להם.
פרטים נוספים זמינים במאמר ניהול צריכת האנרגיה.
שינויים בנושא פרטיות
כדי לשפר את פרטיות המשתמשים, ב-Android 9 יש כמה שינויים בהתנהגות, כמו הגבלת הגישה של אפליקציות ברקע לחיישנים של המכשיר, הגבלת המידע שאוחזר מסריקות Wi-Fi וכללי הרשאות וקבוצות הרשאות חדשות שקשורות לשיחות טלפון, למצב הטלפון ולסריקות Wi-Fi.
השינויים האלה משפיעים על כל האפליקציות שפועלות ב-Android 9, ללא קשר לגרסה של SDK היעד.
גישה מוגבלת לחיישנים ברקע
ב-Android 9 יש הגבלה על היכולת של אפליקציות ברקע לגשת לנתוני הקלט ולנתוני החיישנים של המשתמשים. אם האפליקציה שלכם פועלת ברקע במכשיר עם Android 9, המערכת מחילה עליה את ההגבלות הבאות:
- לאפליקציה אין גישה למיקרופון או למצלמה.
- חיישנים שמשתמשים במצב הדיווח רציף, כמו מד התאוצה והג'ירוסקופ, לא מקבלים אירועים.
- חיישנים שמשתמשים במצבי הדיווח on-change או one-shot לא מקבלים אירועים.
אם האפליקציה שלכם צריכה לזהות אירועי חיישנים במכשירים עם Android מגרסה 9 ואילך, צריך להשתמש בשירות בחזית.
גישה מוגבלת ליומני השיחות
ב-Android 9 נוספה קבוצת ההרשאות CALL_LOG
, וההרשאות READ_CALL_LOG
, WRITE_CALL_LOG
ו-PROCESS_OUTGOING_CALLS
הועברו לקבוצה הזו. בגרסאות קודמות של Android, ההרשאות האלה היו בקבוצת ההרשאות PHONE
.
קבוצת ההרשאות CALL_LOG
מעניקה למשתמשים שליטה טובה יותר וגישה טובה יותר לאפליקציות שזקוקות לגישה למידע רגיש לגבי שיחות טלפון, כמו קריאת רשומות של שיחות טלפון וזיהוי מספרי טלפון.
אם לאפליקציה שלכם נדרשת גישה ליומני שיחות או שהיא צריכה לעבד שיחות יוצאות, עליכם לבקש את ההרשאות האלה באופן מפורש מקבוצת ההרשאות CALL_LOG
. אחרת, מתרחשת הודעת השגיאה SecurityException
.
הערה: מכיוון שההרשאות האלה עברו קבוצות והן מוענקות במהלך זמן הריצה, המשתמש יכול לדחות את הגישה של האפליקציה לנתונים של יומני השיחות בטלפון. במקרה כזה, האפליקציה צריכה להתמודד עם חוסר הגישה למידע בצורה חלקה.
אם האפליקציה שלכם כבר פועלת בהתאם לשיטות המומלצות לניהול הרשאות בסביבת זמן הריצה, היא תוכל להתמודד עם השינוי בקבוצת ההרשאות.
גישה מוגבלת למספרי טלפון
אפליקציות שפועלות ב-Android 9 לא יכולות לקרוא מספרי טלפון או את מצב הטלפון בלי לקבל קודם את ההרשאה READ_CALL_LOG
, בנוסף להרשאות האחרות שנדרשות בתרחישי השימוש של האפליקציה.
מספרי הטלפון שמשויכים לשיחות נכנסות ויוצאות גלויים בשידור של מצב הטלפון, למשל בשיחות נכנסות ויוצאות, ואפשר לגשת אליהם מהקלאס PhoneStateListener
.
עם זאת, בלי ההרשאה READ_CALL_LOG
, השדה של מספר הטלפון שמוצג בשידורי PHONE_STATE_CHANGED
ודרך PhoneStateListener
יהיה ריק.
כדי לקרוא מספרי טלפון ממצב הטלפון, צריך לעדכן את האפליקציה כך שתבקש את ההרשאות הנדרשות בהתאם לתרחיש לדוגמה:
- כדי לקרוא מספרים מפעולת הכוונה
PHONE_STATE
, נדרשות גם ההרשאהREAD_CALL_LOG
וגם ההרשאהREAD_PHONE_STATE
. - כדי לקרוא מספרים מ-
onCallStateChanged()
, נדרשת רק ההרשאהREAD_CALL_LOG
. לא נדרשת ההרשאהREAD_PHONE_STATE
.
גישה מוגבלת למיקום ולפרטי החיבור של Wi-Fi
ב-Android 9, דרישות ההרשאות לאפליקציות לבצע סריקות Wi-Fi מחמירות יותר מאשר בגרסאות קודמות. פרטים נוספים זמינים במאמר מגבלות על סריקת רשתות Wi-Fi.
הגבלות דומות חלות גם על השיטה getConnectionInfo()
, שמחזירה אובייקט WifiInfo
שמתאר את חיבור ה-Wi-Fi הנוכחי. אפשר להשתמש בשיטות של האובייקט הזה כדי לאחזר את הערכים של SSID ו-BSSID רק אם לאפליקציה הקוראת יש את ההרשאות הבאות:
- ACCESS_FINE_LOCATION או ACCESS_COARSE_LOCATION
- ACCESS_WIFI_STATE
כדי לאחזר את ה-SSID או ה-BSSID, צריך גם להפעיל את שירותי המיקום במכשיר (בהגדרות > מיקום).
מידע שהוסר משיטות השירות של Wi-Fi
ב-Android 9, האירועים והשידורים הבאים לא מקבלים מידע על המיקום של המשתמש או על מידע אישי שאפשר לזהות באמצעותו:
- השיטות
getScanResults()
ו-getConnectionInfo()
מ-WifiManager
. - השיטות
discoverServices()
ו-addServiceRequest()
מ-WifiP2pManager
. - השידור
NETWORK_STATE_CHANGED_ACTION
.
השידור של המערכת NETWORK_STATE_CHANGED_ACTION
דרך Wi-Fi לא מכיל יותר את השדות SSID (לשעבר EXTRA_SSID), BSSID (לשעבר EXTRA_BSSID) או פרטי החיבור (לשעבר EXTRA_NETWORK_INFO). אם לאפליקציה שלכם דרושים הפרטים האלה, צריך להפעיל במקום זאת את getConnectionInfo()
.
פרטי הטלפון מבוססים עכשיו על הגדרת המיקום של המכשיר
אם המשתמש השבית את המיקום של המכשיר במכשיר עם Android 9, השיטות הבאות לא מספקות תוצאות:
הגבלות על שימוש בממשקים שאינם SDK
כדי לשמור על יציבות ותאימות של האפליקציה, הפלטפורמה מגבילה את השימוש בשיטות ובשדות מסוימים שאינם SDK. ההגבלות האלה חלות גם אם מנסים לגשת לשיטות ולשדות האלה ישירות, דרך רפלקציה או באמצעות JNI. ב-Android 9, האפליקציה יכולה להמשיך לגשת לממשקים המוגבלים האלה. הפלטפורמה משתמשת בהתראות 'טוסט' וברשומות ביומן כדי להסב את תשומת הלב שלכם לכך. אם באפליקציה שלכם מוצגת הודעת טוסט כזו, חשוב שתבחרו באסטרטגיית הטמעה אחרת מלבד ממשק מוגבל. אם לדעתכם אין אסטרטגיה חלופית אפשרית, תוכלו לשלוח דיווח על באג כדי לבקש בדיקה מחדש של ההגבלה.
מידע חשוב נוסף זמין במאמר הגבלות על ממשקים שאינם SDK. כדאי לבדוק אותו כדי לוודא שהאפליקציה ממשיכה לפעול כמו שצריך.
שינויים בהתנהגות האבטחה
שינויים באבטחת המכשיר
ב-Android 9 נוספו כמה יכולות שמשפרות את האבטחה של האפליקציה, ללא קשר לגרסה שאליה האפליקציה מטרגטת.
שינויים בהטמעת TLS
הטמעת ה-TLS במערכת השתנתה בכמה דרכים ב-Android 9:
- אם מכונה של
SSLSocket
לא מצליחה להתחבר במהלך היצירה שלה, המערכת תשליךIOException
במקוםNullPointerException
. - הכיתה
SSLEngine
מטפלת בצורה מסודרת בכל ההתראות מסוגclose_notify
שמתרחשות.
מידע נוסף על שליחת בקשות מאובטחות לאינטרנט באפליקציה ל-Android זמין במאמר דוגמה ל-HTTPS.
מסנן SECCOMP מחמיר יותר
ב-Android 9 יש הגבלה נוספת על קריאות המערכת שזמינות לאפליקציות. ההתנהגות הזו היא תוספת למסנן SECCOMP שכלול ב-Android 8.0 (רמת API 26).
שינויים קריפטוגרפיים
ב-Android 9 יש כמה שינויים בהטמעה ובטיפול באלגוריתמים קריפטוגרפיים.
הטמעות של פרמטרים ואלגוריתמים ב-Conscrypt
ב-Android 9 יש הטמעות נוספות של פרמטרים של אלגוריתמים ב-Conscrypt. הפרמטרים האלה כוללים: AES, DESEDE, OAEP ו-EC. הגרסאות של הפרמטרים האלה ושל הרבה אלגוריתמים ב-Bouncy Castle הוצאו משימוש החל מגרסה 9 של Android.
אם האפליקציה שלכם מטרגטת את Android 8.1 (API ברמה 27) ואילך, תופיע אזהרה כשתבצעו בקשה להטמעה של Bouncy Castle של אחד מהאלגוריתמים האלה שהוצאו משימוש. עם זאת, אם מטרגטים ל-Android 9, כל אחת מהבקשות האלה תגרום להשלכה של NoSuchAlgorithmException
.
שינויים נוספים
ב-Android 9 יש כמה שינויים נוספים שקשורים להצפנה:
- כשמשתמשים במפתחות PBE, אם Bouncy Castle מצפה לוקטור אתחול (IV) והאפליקציה לא מספקת אחד, תופיע אזהרה.
- ההטמעה של Conscrypt למפתח ARC4 מאפשרת לציין את הערכים ARC4/ECB/NoPadding או ARC4/NONE/NoPadding.
- הספק של Crypto Java Cryptography Architecture (JCA) הוסר. כתוצאה מכך, אם האפליקציה קוראת ל-
SecureRandom.getInstance("SHA1PRNG", "Crypto")
, מתרחשת קריאה ל-NoSuchProviderException
. - אם האפליקציה שלכם מפענחת מפתחות RSA ממאגרים גדולים יותר ממבנה המפתח, החריגה לא תתרחש יותר.
למידע נוסף על השימוש ביכולות הקריפטוגרפיות של Android, ראו קריפטוגרפיה.
אין יותר תמיכה בקבצים מוצפנים מאובטחים ב-Android
ב-Android 9 הוסרה לחלוטין התמיכה בקובצי Android מאובטחים מוצפנים (ASEC).
ב-Android 2.2 (רמת API 8), הושק ב-Android קובצי ASEC כדי לתמוך בפונקציונליות של אפליקציות בכרטיס SD. ב-Android 6.0 (רמת API 23), הפלטפורמה הציגה טכנולוגיה של מכשיר אחסון שניתן להתאמה, שבה מפתחים יכולים להשתמש במקום ב-ASEC.
עדכונים בספריות ICU
ב-Android 9 נעשה שימוש בגרסה 60 של ספריית ICU. ב-Android 8.0 (API ברמה 26) וב-Android 8.1 (API ברמה 27) נעשה שימוש ב-ICU 58.
ה-ICU משמש לספק ממשקי API ציבוריים מתחת ל-android.icu package
, ומשמש באופן פנימי בפלטפורמת Android לתמיכה בבינלאומיזציה.
לדוגמה, הוא משמש להטמעת כיתות Android ב-java.util
, ב-java.text
וב-android.text.format
.
העדכון ל-ICU 60 כולל הרבה שינויים קטנים אבל שימושיים, כולל תמיכה בנתוני Emoji 5.0 ופורמטים משופרים של תאריך/שעה, כפי שמתואר במסמכי הערה לגרסה 59 ולגרסה 60 של ICU.
השינויים הבולטים בעדכון הזה:
- האופן שבו הפלטפורמה מטפלת באזורי זמן השתנה.
- הפלטפורמה מטפלת טוב יותר ב-GMT וב-UTC. שעון UTC כבר לא נחשב למונח נרדף ל-GMT.
מעכשיו, ICU מספק שמות תחומים מתורגמים ל-GMT ול-UTC. השינוי הזה משפיע על התנהגות הפורמט והניתוח של
android.icu
באזורים כמו 'GMT', 'Etc/GMT', 'UTC', 'Etc/UTC' ו-'Zulu'. java.text.SimpleDateFormat
משתמש עכשיו ב-ICU כדי לספק שמות תצוגה של UTC /GMT, כלומר:- עיצוב של
zzzz
יוצר מחרוזת ארוכה שמותאמת לשוק המקומי של הרבה לוקאלים. בעבר, הפונקציה החזירה את הערך 'UTC' עבור שעון UTC ומחרוזות כמו 'GMT+00:00' עבור שעון גריניץ'. - ניתוח
zzzz
מזהה מחרוזות כמו 'שעון אוניברסלי מתואם' ו'שעון גריניץ'. - אפליקציות עשויות להיתקל בבעיות תאימות אם הן מניחות שהפלט של
zzzz
בכל השפות הוא 'UTC' או 'GMT+00:00'.
- עיצוב של
- ההתנהגות של
java.text.DateFormatSymbols.getZoneStrings()
השתנתה:- בדומה ל-
SimpleDateFormat
, עכשיו יש לשעון UTC ולשעון גריניץ' שמות ארוכים. וריאציות של שמות אזורי זמן עם שעון קיץ לאזור UTC, כמו 'UTC', 'Etc/UTC' ו-'Zulu', הופכות ל-GMT+00:00, שהוא ברירת המחדל הרגילה כשאין שמות זמינים, במקום המחרוזתUTC
שמוגדרת בקוד. - חלק ממזהי תחומים מזוהים כראוי כמילים נרדפות של תחומים אחרים, כך שמערכת Android מוצאת מחרוזות של מזהי תחומים מיושנים, כמו
Eire
, שלא ניתן היה לפתור בעבר.
- בדומה ל-
- אזור הזמן Asia/Hanoi כבר לא מוכר. לכן, הפונקציה
java.util.TimeZones.getAvailableIds()
לא מחזירה את הערך הזה ו-java.util.TimeZone.getTimeZone()
לא מזהה אותו. ההתנהגות הזו תואמת להתנהגות הקיימת שלandroid.icu
.
- הפלטפורמה מטפלת טוב יותר ב-GMT וב-UTC. שעון UTC כבר לא נחשב למונח נרדף ל-GMT.
- השיטה
android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String)
עשויה להוביל ליצירתParseException
גם כשמנתחים טקסט לגיטימי של מטבע. כדי למנוע את הבעיה הזו, צריך להשתמש ב-NumberFormat.parseCurrency
, שזמין מאז Android 7.0 (רמת API 24), לטקסט של מטבע בסגנוןPLURALCURRENCYSTYLE
.
שינויים ב-Android Test
ב-Android 9 יש כמה שינויים בספרייה ובמבנה הכיתות של Android Test framework. השינויים האלה עוזרים למפתחים להשתמש בממשקי API ציבוריים שנתמכים במסגרת, אבל הם גם מאפשרים גמישות רבה יותר ביצירה ובהרצה של בדיקות באמצעות ספריות של צד שלישי או לוגיקה מותאמת אישית.
ספריות שהוסרו מהמסגרת
ב-Android 9, הכיתות שמבוססות על JUnit מאורגנות מחדש בשלוש ספריות: android.test.base, android.test.runner ו-android.test.mock.
השינוי הזה מאפשר להריץ בדיקות בגרסה של JUnit שתואמת בצורה הטובה ביותר ליחסי התלות של הפרויקט. ייתכן שהגרסה הזו של JUnit תהיה שונה מהגרסה ש-android.jar
מספקת.
במאמר הגדרת פרויקט ל-Android Test מוסבר איך הכיתות שמבוססות על JUnit מאורגנות בספריות האלה, ואיך מכינים את הפרויקט של האפליקציה לכתיבה ולהרצה של בדיקות.
שינויים ב-build של חבילת הבדיקה
השיטה addRequirements()
בכיתה TestSuiteBuilder
הוסרה, והכיתה TestSuiteBuilder
הוצאה משימוש.
השיטה addRequirements()
דרשה מהמפתחים לספק ארגומנטים שהטיפוסים שלהם הם ממשקי API מוסתרים, מה שהופך את ה-API ללא תקין.
מפענח UTF של Java
UTF-8 הוא ברירת המחדל של קוד האותיות ב-Android. אפשר לפענח רצף בייטים של UTF-8 באמצעות קונסטרוקטור של String
, כמו String(byte[] bytes)
.
המפענח של UTF-8 ב-Android 9 פועל לפי תקני Unicode באופן מחמיר יותר מאשר בגרסאות קודמות. השינויים כוללים:
- המערכת מתייחסת לצורה הארוכה ביותר של UTF-8, כמו
<C0, AF>
, כאל צורה לא תקינה. - המערכת מתייחסת לצורה החלופית של UTF-8, כמו
U+D800
..U+DFFF
, כאל תוכן לא תקין. - החלק המשני המקסימלי מוחלף ב-
U+FFFD
יחיד. לדוגמה, ברצף הבייטים41 C0 AF 41 F4 80 80 41
, החלקים המשניים המקסימליים הםC0
,AF
ו-F4 80 80
. הרצףF4 80 80
יכול להיות הרצף המשני הראשוני שלF4 80 80 80
, אבל הרצףC0
לא יכול להיות הרצף המשני הראשוני של אף רצף של יחידות קוד תקינות. לכן, הפלט אמור להיותA\ufffd\ufffdA\ufffdA
. - כדי לפענח רצף UTF-8 או CESU-8 שעבר שינוי ב-Android 9 ואילך, משתמשים ב-method
DataInputStream.readUTF()
או ב-methodNewStringUTF()
JNI.
אימות שם מארח באמצעות אישור
ב-RFC 2818 מתוארות שתי שיטות להתאמת שם דומיין לאישור – באמצעות השמות הזמינים בתוסף subjectAltName
(SAN
), או במקרה של חוסר בתוסף SAN
, באמצעות התוסף commonName
(CN
).
עם זאת, האפשרות של חזרה ל-CN
הוצאה משימוש ב-RFC 2818. לכן, מערכת Android כבר לא עוברת לשימוש ב-CN
. כדי לאמת שם מארח, השרת צריך להציג אישור עם SAN
תואם. אישורים שלא מכילים את השדה SAN
שתואם לשם המארח כבר לא נחשבים מהימנים.
חיפושים של כתובות רשת עלולים לגרום להפרות של מדיניות הרשת
חיפושים של כתובות רשת שדורשים פתרון שמות יכולים לכלול קלט/פלט ברשת, ולכן נחשבים לפעולות חסימה. פעולות חסימה בשרשור הראשי עלולות לגרום להשהיות או לתנודות.
הכיתה StrictMode
היא כלי פיתוח שעוזר למפתחים לזהות בעיות בקוד שלהם.
ב-Android מגרסה 9 ואילך, StrictMode
מזהה הפרות של רשתות שנגרמות על ידי חיפושים של כתובות רשת שדורשים פתרון שמות.
לא מומלץ לשלוח את האפליקציות עם StrictMode
מופעל. אם תעשו זאת, יכול להיות שתבחינו באפליקציות שלכם בחריגות, כמו NetworkOnMainThreadException
כשמשתמשים בשיטות detectNetwork()
או detectAll()
כדי לקבל מדיניות שמזהה הפרות של מדיניות הרשת.
פעולת פתרון של כתובת IP מספרית לא נחשבת לפעולה של חסימה. פתרון של כתובות IP מספריות פועל כמו בגרסאות שלפני Android 9.
תיוג שקעים
בגרסאות פלטפורמה ישנות יותר מ-Android 9, אם משייכים תג לשקע באמצעות השיטה setThreadStatsTag()
, התג יוסר מהשקע כשהוא נשלח לתהליך אחר באמצעות binder IPC עם מאגר ParcelFileDescriptor
.
ב-Android 9 ואילך, תג השקע נשמר כששולחים אותו לתהליך אחר באמצעות binder IPC. השינוי הזה יכול להשפיע על הנתונים הסטטיסטיים של תעבורת הרשת, למשל כשמשתמשים בשיטה queryDetailsForUidTag()
.
אם רוצים לשמור על ההתנהגות של הגרסאות הקודמות, שבהן מתבצע ביטול תג של שקע שנשלח לתהליך אחר, אפשר להפעיל את untagSocket()
לפני שליחת השקע.
כמות הבייטים הזמינים בדיווח ביציאה
השיטה available()
מחזירה את הערך 0
כשקוראים לה אחרי שמפעילים את השיטה shutdownInput()
.
דיווח מפורט יותר על יכולות הרשת של VPN
ב-Android 8.1 (API ברמה 27) ובגרסאות ישנות יותר, הכיתה NetworkCapabilities
מדווחת רק על קבוצה מוגבלת של מידע לגבי רשתות VPN, כמו TRANSPORT_VPN
, אבל לא על NET_CAPABILITY_NOT_VPN
. המידע המוגבל הזה הקשה עלינו לקבוע אם השימוש ב-VPN יוביל לחיוב של משתמש האפליקציה. לדוגמה, בדיקה של NET_CAPABILITY_NOT_METERED
לא תאפשר לקבוע אם הרשתות הבסיסיות נמדדו או לא.
ב-Android 9 ואילך, כש-VPN קורא לשיטה setUnderlyingNetworks()
, מערכת Android משלבת את אמצעי התעבורה והיכולות של כל הרשתות הבסיסיות ומחזירה את התוצאה כיכולות הרשת האפקטיביות של רשת ה-VPN.
ב-Android 9 ואילך, אפליקציות שכבר בודקות את הערך של NET_CAPABILITY_NOT_METERED
מקבלות את יכולות הרשת של ה-VPN והרשתות הבסיסיות.
קבצים בתיקייה xt_qtaguid כבר לא זמינים לאפליקציות
החל מגרסה 9 של Android, לאפליקציות אסור לקבל גישת קריאה ישירה לקבצים בתיקייה /proc/net/xt_qtaguid
. הסיבה לכך היא כדי לשמור על עקביות במכשירים מסוימים שבהם הקבצים האלה לא נמצאים בכלל.
ממשקי ה-API הציבוריים שמסתמכים על הקבצים האלה, TrafficStats
ו-NetworkStatsManager
, ממשיכים לפעול כמצופה.
עם זאת, יכול להיות שפונקציות cutils שלא נתמכות, כמו qtaguid_tagSocket()
, לא יפעלו כצפוי או בכלל במכשירים שונים.
הדרישות של FLAG_ACTIVITY_NEW_TASK נאכפות עכשיו
בגרסה 9 של Android, אי אפשר להפעיל פעילות מהקשר שאינו פעילות, אלא אם מעבירים את הדגל של הכוונה FLAG_ACTIVITY_NEW_TASK
.
אם מנסים להפעיל פעילות בלי להעביר את הדגל הזה, הפעילות לא מתחילה והמערכת מדפיסה הודעה ביומן.
שינויים בסיבוב המסך
החל מ-Android 9, יש שינויים משמעותיים במצב הסיבוב לאורך. ב-Android 8.0 (רמת API 26), המשתמשים יכלו לעבור בין המצבים סיבוב אוטומטי ודיוקן באמצעות משבצת בהגדרות המהירות או בהגדרות התצוגה. שם המצב 'פורטרט' השתנה לנעילת סיבוב, והוא פעיל כשהסיבוב האוטומטי מושבת. אין שינויים במצב הסיבוב האוטומטי.
כשהמכשיר נמצא במצב נעילה לפי כיוון המסך, המשתמשים יכולים לנעול את המסך לכל כיוון שתומכת בו הפעילות הגלויה בחלק העליון. אסור להניח שפעילות תמיד תוצג בפורמט לאורך. אם אפשר ליצור עיבוד של הפעילות העליונה במספר כיווני צילום במצב 'כיוון אוטומטי', אותן אפשרויות אמורות להיות זמינות במצב 'נעילה בכיוון מסוים', עם כמה יוצאים מן הכלל בהתאם להגדרה screenOrientation
של הפעילות (ראו בטבלה שבהמשך).
פעילויות שמבקשות כיוון ספציפי (לדוגמה, screenOrientation=landscape
) מתעלמות מהעדפת המשתמש לנעילת המסך ופועלות באותו אופן כמו ב-Android 8.0.
אפשר להגדיר את העדפת כיוון המסך ברמת הפעילות ב-Android Manifest, או באופן פרוגרמטי באמצעות setRequestedOrientation().
מצב נעילת הסיבוב פועל על ידי הגדרת העדפת הסיבוב של המשתמש, שבה WindowManager משתמש כשמטפל בסיבוב של פעילות. העדפת הסיבוב של המשתמש עשויה להשתנות במקרים הבאים. חשוב לזכור שיש נטייה לחזור לסיבוב הטבעי של המכשיר, שבדרך כלל הוא לרוחב במכשירים בפורמט של טלפון:
- כשהמשתמש מאשר הצעה לסיבוב, העדפת הסיבוב משתנה בהתאם להצעה.
- כשהמשתמש עובר לאפליקציה שמוגדרת להכרח תצוגה לאורך (כולל מסך הנעילה או מרכז האפליקציות), העדפת הסיבוב משתנה לתצוגה לאורך.
בטבלה הבאה מפורט סיכום של התנהגות הסיבוב בכיווני המסך הנפוצים:
כיוון מסך | התנהגות |
---|---|
לא צוין, משתמש | כשהסיבוב האוטומטי והנעילה של הסיבוב פועלים, אפשר להציג את הפעילות בפורמט לאורך או לרוחב (ולהפך). צפויה תמיכה גם בפריסות אנכיות וגם בפריסות אופקיות. |
userLandscape | כשהתכונות 'סיבוב אוטומטי' ו'נעילה בסיבוב' מופעלות, הפעילות יכולה להיות מוצגת בפריסה לרוחב או בפריסה לרוחב הפוך. התמיכה תהיה רק בפריסות לרוחב. |
userPortrait | כשהתכונות 'סיבוב אוטומטי' ו'נעילה בסיבוב' מופעלות, הפעילות יכולה להופיע בתצוגת דיוקן או בתצוגת דיוקן הפוך. צפויה תמיכה רק בפריסות לרוחב. |
fullUser | כשהסיבוב האוטומטי והנעילה של הסיבוב פועלים, אפשר להציג את הפעילות בפורמט לאורך או לרוחב (וההפך). כדאי לתמוך גם בפריסות לרוחב וגם בפריסות לאורך. משתמשים עם נעילה לסיבוב יקבלו אפשרות לנעול לכיוון לאורך הפוך, לרוב 180º. |
sensor, fullSensor, sensorPortrait, sensorLandscape | המערכת מתעלמת מהעדפה של מצב נעילת הסיבוב ומתייחסת למצב כאילו התכונה 'סיבוב אוטומטי' פעילה. מומלץ להשתמש באפשרות הזו רק בנסיבות חריגות, תוך התחשבות רבה ב-UX. |
ההוצאה משימוש של לקוח ה-HTTP של Apache משפיעה על אפליקציות עם ClassLoader לא סטנדרטי
בגרסה 6.0 של Android, הסרנו את התמיכה בלקוח ה-HTTP של Apache.
השינוי הזה לא משפיע על רוב האפליקציות שלא מטרגטות את Android מגרסה 9 ואילך. עם זאת, השינוי עשוי להשפיע על אפליקציות מסוימות שמשתמשות במבנה ClassLoader
לא סטנדרטי, גם אם האפליקציות לא מטרגטות ל-Android 9 ואילך.
אפליקציה עשויה להיות מושפעת אם היא משתמשת ב-ClassLoader
לא סטנדרטי שמעניק גישה ל-ClassLoader
של המערכת באופן מפורש. כשמחפשים כיתות ב-org.apache.http.*
, האפליקציות האלה צריכות להעביר את הגישה לאפליקציה
ClassLoader
. אם הן יעבירו את הגישה למערכת ClassLoader
, האפליקציות יכשלו ב-Android 9 ואילך עם הודעת השגיאה NoClassDefFoundError
, כי הכיתות האלה כבר לא ידועות למערכת ClassLoader
. כדי למנוע בעיות דומות בעתיד, מומלץ לאפליקציות לטעון כיתות דרך האפליקציה ClassLoader
במקום לגשת ישירות למערכת ClassLoader
.
ספירת המצלמות
אפליקציות שפועלות במכשירי Android 9 יכולות לזהות כל מצלמה זמינה באמצעות קריאה ל-getCameraIdList()
.
אפליקציה לא צריכה להניח שיש במכשיר רק מצלמה אחורית אחת או רק מצלמה קדמית אחת.
לדוגמה, אם באפליקציה יש לחצן למעבר בין המצלמה הקדמית למצלמה האחורית, יכול להיות שיש יותר ממצלמה קדמית אחת או יותר ממצלמה אחורית אחת לבחירה. כדאי לעבור על רשימת המצלמות, לבדוק את המאפיינים של כל מצלמה ולהחליט אילו מצלמות לחשוף למשתמש.