בדומה לגרסאות קודמות, Android 15 כולל שינויים בהתנהגות שעשויים להשפיע על האפליקציה שלכם. שינויי ההתנהגות הבאים חלים אך ורק על אפליקציות שמטרגטות ל-Android 15 ואילך. אם האפליקציה שלכם מטרגטת את Android מגרסה 15 ואילך, עליכם לשנות את האפליקציה כך שתתמוך בהתנהגויות האלה בצורה תקינה, במקרים הרלוונטיים.
חשוב גם לעיין ברשימת השינויים בהתנהגות שמשפיעים על כל האפליקציות שפועלות ב-Android 15, ללא קשר ל-targetSdkVersion
של האפליקציה.
פונקציונליות עיקרית
ב-Android 15 יש שינויים או הרחבות של יכולות ליבה שונות במערכת Android.
שינויים בשירותים שפועלים בחזית
We are making the following changes to foreground services with Android 15.
- Data sync foreground service timeout behavior
- New media processing foreground service type
- Restrictions on
BOOT_COMPLETED
broadcast receivers launching foreground services - Restrictions on starting foreground services while an app holds the
SYSTEM_ALERT_WINDOW
permission
Data sync foreground service timeout behavior
Android 15 introduces a new timeout behavior to dataSync
for apps targeting
Android 15 (API level 35) or higher. This behavior also applies to the new
mediaProcessing
foreground service type.
The system permits an app's dataSync
services to run for a total of 6 hours
in a 24-hour period, after which the system calls the running service's
Service.onTimeout(int, int)
method (introduced in Android
15). At this time, the service has a few seconds to call
Service.stopSelf()
. When Service.onTimeout()
is called, the
service is no longer considered a foreground service. If the service does not
call Service.stopSelf()
, the system throws an internal exception. The
exception is logged in Logcat with the following message:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
To avoid problems with this behavior change, you can do one or more of the following:
- Have your service implement the new
Service.onTimeout(int, int)
method. When your app receives the callback, make sure to callstopSelf()
within a few seconds. (If you don't stop the app right away, the system generates a failure.) - Make sure your app's
dataSync
services don't run for more than a total of 6 hours in any 24-hour period (unless the user interacts with the app, resetting the timer). - Only start
dataSync
foreground services as a result of direct user interaction; since your app is in the foreground when the service starts, your service has the full six hours after the app goes to the background. - Instead of using a
dataSync
foreground service, use an alternative API.
If your app's dataSync
foreground services have run for 6 hours in the last
24, you cannot start another dataSync
foreground service unless the user
has brought your app to the foreground (which resets the timer). If you try to
start another dataSync
foreground service, the system throws
ForegroundServiceStartNotAllowedException
with an error message like "Time limit already exhausted for foreground service
type dataSync".
Testing
To test your app's behavior, you can enable data sync timeouts even if your app
is not targeting Android 15 (as long as the app is running on an Android 15
device). To enable timeouts, run the following adb
command:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
You can also adjust the timeout period, to make it easier to test how your
app behaves when the limit is reached. To set a new timeout period, run the
following adb
command:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
New media processing foreground service type
ב-Android 15 מוצג סוג חדש של שירות שפועל בחזית, mediaProcessing
. סוג השירות הזה מתאים לפעולות כמו המרת קידוד של קובצי מדיה. לדוגמה, אפליקציית מדיה עשויה להוריד קובץ אודיו ולהמיר אותו לפורמט אחר לפני ההפעלה. אתם יכולים להשתמש בשירות mediaProcessing
שפועל בחזית כדי לוודא שההמרה תימשך גם כשהאפליקציה ברקע.
המערכת מאפשרת לשירותי mediaProcessing
של אפליקציה לפעול במשך 6 שעות בסך הכול בתקופה של 24 שעות, ולאחר מכן המערכת קוראת ל-method Service.onTimeout(int, int)
של השירות שפועל (הmethod הזה הוצג ב-Android 15). בשלב הזה, לשירות יש כמה שניות לבצע קריאה ל-Service.stopSelf()
. אם השירות לא קורא ל-Service.stopSelf()
, המערכת גורמת לחריגה פנימית. החריג מתועד ביומן Logcat עם ההודעה הבאה:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"
כדי למנוע את החריגה, אפשר לבצע אחת מהפעולות הבאות:
- עליך להטמיע בשירות שלך את השיטה החדשה של
Service.onTimeout(int, int)
. כשהאפליקציה מקבלת את הקריאה החוזרת, חשוב להקפיד להתקשר ל-stopSelf()
תוך מספר שניות. (אם לא מפסיקים את האפליקציה מיד, המערכת יוצרת כשל). - חשוב לוודא ששירותי
mediaProcessing
של האפליקציה לא פועלים במשך יותר מ-6 שעות בסך הכול בכל תקופה של 24 שעות (אלא אם המשתמש יוצר אינטראקציה עם האפליקציה, ומאפס את הטיימר). - כדאי להפעיל שירותים
mediaProcessing
שפועלים בחזית רק כתוצאה מאינטראקציה ישירה של משתמש. מכיוון שהאפליקציה נמצאת בחזית כשהשירות מופעל, השירות מקבל את שש השעות המלאות אחרי שהאפליקציה עוברת לרקע. - במקום להשתמש בשירות שפועל בחזית
mediaProcessing
, צריך להשתמש בAPI חלופי, כמו WorkManager.
אם שירותי mediaProcessing
של האפליקציה פעלו בחזית במשך 6 שעות ב-24 השעות האחרונות, לא תוכלו להפעיל שירות mediaProcessing
נוסף בחזית אלא אם המשתמש העביר את האפליקציה לחזית (פעולה שמאפסת את הטיימר). אם תנסו להפעיל שירות mediaProcessing
שפועל בחזית, המערכת תשליך את הערך ForegroundServiceStartNotAllowedException
עם הודעת שגיאה כמו "Time Limit כבר נשלחת לכל שירות שפועל בחזית מסוג mediaProcessing".
מידע נוסף על סוג השירות mediaProcessing
זמין במאמר שינויים בסוגי שירותים בחזית במהדורת Android 15: עיבוד מדיה.
בדיקה
כדי לבדוק את התנהגות האפליקציה, אפשר להפעיל זמן קצוב לתפוגה של עיבוד מדיה גם אם האפליקציה לא מטרגטת ל-Android 15 (כל עוד האפליקציה פועלת במכשיר עם Android 15). כדי להפעיל זמן קצוב לתפוגה, מריצים את הפקודה הבאה ב-adb
:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
אפשר גם לשנות את משך הזמן של הזמן הקצוב לתפוגה, כדי שיהיה קל יותר לבדוק איך האפליקציה מתנהגת כשמגיעים למגבלה. כדי להגדיר פרק זמן חדש לתפוגה, מריצים את הפקודה הבאה של adb
:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds
Restrictions on BOOT_COMPLETED
broadcast receivers launching foreground services
יש הגבלות חדשות על השקת מקלטי שידור של BOOT_COMPLETED
שירותים שפועלים בחזית. למקלטי BOOT_COMPLETED
אסור להפעיל את
הסוגים הבאים של שירותים שפועלים בחזית:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(ההגבלה הזו חלה עלmicrophone
מאז Android 14)
אם מקלט BOOT_COMPLETED
מנסה להפעיל אחד מהסוגים האלה של חזית
השירותים האלה, המערכת מטילה ForegroundServiceStartNotAllowedException
.
בדיקה
כדי לבדוק את התנהגות האפליקציה, אפשר להפעיל את ההגבלות החדשות האלה גם אם
האפליקציה לא מטרגטת ל-Android 15 (כל עוד האפליקציה פועלת עם Android 15).
במכשיר). מריצים את הפקודה adb
הבאה:
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
כדי לשלוח שידור של BOOT_COMPLETED
בלי להפעיל מחדש את המכשיר:
מריצים את הפקודה הבאה של adb
:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
Restrictions on starting foreground services while an app holds the SYSTEM_ALERT_WINDOW
permission
Previously, if an app held the SYSTEM_ALERT_WINDOW
permission, it could launch
a foreground service even if the app was currently in the background (as
discussed in exemptions from background start restrictions).
If an app targets Android 15, this exemption is now narrower. The app now needs
to have the SYSTEM_ALERT_WINDOW
permission and also have a visible overlay
window. That is, the app needs to first launch a
TYPE_APPLICATION_OVERLAY
window and the window
needs to be visible before you start a foreground service.
If your app attempts to start a foreground service from the background without
meeting these new requirements (and it does not have some other exemption), the
system throws ForegroundServiceStartNotAllowedException
.
If your app declares the SYSTEM_ALERT_WINDOW
permission
and launches foreground services from the background, it may be affected by this
change. If your app gets a ForegroundServiceStartNotAllowedException
, check
your app's order of operations and make sure your app already has an active
overlay window before it attempts to start a foreground service from the
background. You can check if your overlay window is currently visible
by calling View.getWindowVisibility()
, or you
can override View.onWindowVisibilityChanged()
to get notified whenever the visibility changes.
Testing
To test your app's behavior, you can enable these new restrictions even if your
app is not targeting Android 15 (as long as the app is running on an Android 15
device). To enable these new restrictions on starting foreground services
from the background, run the following adb
command:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
שינויים בזמנים שבהם אפליקציות יכולות לשנות את המצב הגלובלי של מצב 'נא לא להפריע'
Apps that target Android 15 (API level 35) and higher can no longer change the
global state or policy of Do Not Disturb (DND) on a device (either by modifying
user settings, or turning off DND mode). Instead, apps must contribute an
AutomaticZenRule
, which the system combines into a global policy with the
existing most-restrictive-policy-wins scheme. Calls to existing APIs that
previously affected global state (setInterruptionFilter
,
setNotificationPolicy
) result in the creation or update of an implicit
AutomaticZenRule
, which is toggled on and off depending on the call-cycle of
those API calls.
Note that this change only affects observable behavior if the app is calling
setInterruptionFilter(INTERRUPTION_FILTER_ALL)
and expects that call to
deactivate an AutomaticZenRule
that was previously activated by their owners.
שינויים ב-OpenJDK API
Android 15 continues the work of refreshing Android's core libraries to align with the features in the latest OpenJDK LTS releases.
Some of these changes can affect app compatibility for apps targeting Android 15 (API level 35):
Changes to string formatting APIs: Validation of argument index, flags, width, and precision are now more strict when using the following
String.format()
andFormatter.format()
APIs:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
For example, the following exception is thrown when an argument index of 0 is used (
%0
in the format string):IllegalFormatArgumentIndexException: Illegal format argument index = 0
In this case, the issue can be fixed by using an argument index of 1 (
%1
in the format string).Changes to component type of
Arrays.asList(...).toArray()
: When usingArrays.asList(...).toArray()
, the component type of the resulting array is now anObject
—not the type of the underlying array's elements. So the following code throws aClassCastException
:String[] elements = (String[]) Arrays.asList("one", "two").toArray();
For this case, to preserve
String
as the component type in the resulting array, you could useCollection.toArray(Object[])
instead:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
Changes to language code handling: When using the
Locale
API, language codes for Hebrew, Yiddish, and Indonesian are no longer converted to their obsolete forms (Hebrew:iw
, Yiddish:ji
, and Indonesian:in
). When specifying the language code for one of these locales, use the codes from ISO 639-1 instead (Hebrew:he
, Yiddish:yi
, and Indonesian:id
).Changes to random int sequences: Following the changes made in https://bugs.openjdk.org/browse/JDK-8301574, the following
Random.ints()
methods now return a different sequence of numbers than theRandom.nextInt()
methods do:Generally, this change shouldn't result in app-breaking behavior, but your code shouldn't expect the sequence generated from
Random.ints()
methods to matchRandom.nextInt()
.
The new SequencedCollection
API can affect your app's compatibility
after you update compileSdk
in your app's build configuration to use
Android 15 (API level 35):
Collision with
MutableList.removeFirst()
andMutableList.removeLast()
extension functions inkotlin-stdlib
The
List
type in Java is mapped to theMutableList
type in Kotlin. Because theList.removeFirst()
andList.removeLast()
APIs have been introduced in Android 15 (API level 35), the Kotlin compiler resolves function calls, for examplelist.removeFirst()
, statically to the newList
APIs instead of to the extension functions inkotlin-stdlib
.If an app is re-compiled with
compileSdk
set to35
andminSdk
set to34
or lower, and then the app is run on Android 14 and lower, a runtime error is thrown:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
The existing
NewApi
lint option in Android Gradle Plugin can catch these new API usages../gradlew lint
MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()To fix the runtime exception and lint errors, the
removeFirst()
andremoveLast()
function calls can be replaced withremoveAt(0)
andremoveAt(list.lastIndex)
respectively in Kotlin. If you're using Android Studio Ladybug | 2024.1.3 or higher, it also provides a quick fix option for these errors.Consider removing
@SuppressLint("NewApi")
andlintOptions { disable 'NewApi' }
if the lint option has been disabled.Collision with other methods in Java
New methods have been added into the existing types, for example,
List
andDeque
. These new methods might not be compatible with the methods with the same name and argument types in other interfaces and classes. In the case of a method signature collision with incompatibility, thejavac
compiler outputs a build-time error. For example:Example error 1:
javac MyList.java
MyList.java:135: error: removeLast() in MyList cannot implement removeLast() in List public void removeLast() { ^ return type void is not compatible with Object where E is a type-variable: E extends Object declared in interface ListExample error 2:
javac MyList.java
MyList.java:7: error: types Deque<Object> and List<Object> are incompatible; public class MyList implements List<Object>, Deque<Object> { both define reversed(), but with unrelated return types 1 errorExample error 3:
javac MyList.java
MyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible; public static class MyList implements List<Object>, MyInterface<Object> { class MyList inherits unrelated defaults for getFirst() from types List and MyInterface where E#1,E#2 are type-variables: E#1 extends Object declared in interface List E#2 extends Object declared in interface MyInterface 1 errorTo fix these build errors, the class implementing these interfaces should override the method with a compatible return type. For example:
@Override public Object getFirst() { return List.super.getFirst(); }
אבטחה
Android 15 כולל שינויים שמקדמים את אבטחת המערכת כדי להגן על האפליקציות והמשתמשים מפני אפליקציות זדוניות.
גרסאות TLS מוגבלות
Android 15 restricts the usage of TLS versions 1.0 and 1.1. These versions had previously been deprecated in Android, but are now disallowed for apps targeting Android 15.
הפעלות מאובטחות של פעילות ברקע
מערכת Android 15 מגינה על המשתמשים מפני אפליקציות זדוניות ומספקת להם יותר שליטה במכשירים שלהם על ידי הוספת שינויים שמונעים מאפליקציות רקע זדוניות הצגת אפליקציות אחרות לחזית, העלאת רמת ההרשאות שלהן וניצול לרעה לאינטראקציה של המשתמשים. ההפעלות של פעילות ברקע הוגבלו מאז Android 10 (רמת API 29).
חסימת האפשרות להפעיל פעילויות של אפליקציות שלא תואמות ל-UID המוביל במקבץ
אפליקציות זדוניות יכולות לבצע פעילות של אפליקציה אחרת במסגרת אותה משימה, ואז
שכבת-על מעל ויוצרת אשליה של להיות האפליקציה. המשימה הזו
פריצה" מתקפה עוקפת את ההגבלות הנוכחיות של הפעלת רקע כי הכול
מתרחשת בתוך אותה משימה גלויה. כדי למזער את הסיכון הזה, Android 15 מוסיפה
דגל שחוסם את ההפעלה של אפליקציות שלא תואמות את ה-UID המוביל בסטאק
פעילויות. כדי להצטרף לכל הפעילויות של האפליקציה, צריך לעדכן את
allowCrossUidActivitySwitchFromBelow
בקובץ AndroidManifest.xml
של האפליקציה:
<application android:allowCrossUidActivitySwitchFromBelow="false" >
אמצעי האבטחה החדשים פעילים אם כל התנאים הבאים יתקיימו:
- האפליקציה שמבצעת את ההשקה מטרגטת את Android 15.
- האפליקציה שנמצאת בראש מקבץ המשימות מטרגטת את Android 15.
- כל הפעילות הגלויה אושרה על ידי המשתמשים במסגרת אמצעי ההגנה החדשים
אם אמצעי האבטחה מופעלים, האפליקציות עשויות לחזור לדף הבית, האפליקציה האחרונה שנראית למשתמש, אם הם משלימים משימה משלהם.
שינויים נוספים
בנוסף להגבלה על ההתאמה של UID, השינויים האלה כלול:
- יש לשנות
PendingIntent
יוצרים כך שלחסום השקות של פעילויות ברקע על ידי ברירת מחדל. זה עוזר למנוע מאפליקציות ליצור בטעותPendingIntent
שעלולים להיות מנוצלים לרעה על ידי גורמים זדוניים. - לא מעבירים אפליקציה לחזית אלא אם השולח של
PendingIntent
מאפשר זאת. השינוי הזה נועד למנוע מאפליקציות זדוניות לנצל לרעה את היכולת להתחיל פעילויות ברקע. כברירת מחדל, מורשים להעביר את מקבץ המשימות לחזית, אלא אם היוצר מאפשר זאת הרשאות השקה של פעילות ברקע או שלשולח יש פעילות ברקע הרשאות השקה. - אתם שולטים באופן שבו הפעילות הראשית במקבץ המשימות יכולה להשלים את המשימה שלה. אם הפעילות המובילה מסתיימת, ו-Android יחזור לאחת מהמשימות שבוצעו פעילות אחרונה. בנוסף, אם משימה שאינה מובילה מסיימת את המשימה, מערכת Android לחזור למסך הבית. היא לא תחסום את הסיומת פעילות.
- למנוע אפשרות להפעיל פעילויות שרירותיות מאפליקציות אחרות במכשיר שלכם משימה זו. השינוי הזה מונע מאפליקציות זדוניות מפני פישינג על ידי יצירת פעילויות שנראות כאילו נשלחו מאפליקציות אחרות.
- חסימת חלונות שאינם נראים לעין כדי שלא יתייחסו לפעילות ברקע השקות. כך ניתן למנוע מאפליקציות זדוניות לנצל לרעה את הרקע מופעלת כדי להציג תוכן לא רצוי או זדוני למשתמשים.
כוונות רכישה בטוחות יותר
ב-Android 15 נוספו אמצעי אבטחה אופציונליים חדשים כדי לשפר את הבטיחות והעמידות של הכוונות. השינויים האלה נועדו למנוע נקודות חולשה פוטנציאליות ושימוש לרעה בכוונות שאפשר לנצל על ידי אפליקציות זדוניות. יש שני שיפורים עיקריים באבטחה של כוונות ב-Android 15:
- התאמה למסנני הכוונה של היעד: כוונות שמטרגטות רכיבים ספציפיים חייבות להתאים במדויק למפרטי מסנני הכוונה של היעד. אם שולחים כוונה להפעלת פעילות של אפליקציה אחרת, רכיב הכוונה ליעד צריך להתאים למסנני הכוונה שהוצהרו בפעילות המקבלת.
- ל-Intents חייבות להיות פעולות: Intents ללא פעולה לא יתאימו יותר למסנני Intent. המשמעות היא שלכוונות שמשמשות להפעלת פעילויות או שירותים צריכה להיות פעולה מוגדרת בבירור.
כדי לבדוק איך האפליקציה מגיבה לשינויים האלה, צריך להשתמש ב-StrictMode
באפליקציה. כדי לראות יומנים מפורטים על הפרות של Intent
, מוסיפים את השיטה הבאה:
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
חוויית משתמש וממשק המשתמש של המערכת
Android 15 כולל כמה שינויים שנועדו ליצור חוויית משתמש עקבית ואינטואיטיבית יותר.
שינויים בהוספת חלון
There are two changes related to window insets in Android 15: edge-to-edge is enforced by default, and there are also configuration changes, such as the default configuration of system bars.
אכיפה מקצה לקצה
אפליקציות מוצגות מקצה לקצה כברירת מחדל במכשירים עם Android 15, אם האפליקציה מטרגטת ל-Android 15 (רמת API 35).

זהו שינוי שעלול להשפיע לרעה על ממשק המשתמש של האפליקציה. השינויים משפיעים על אזורי ממשק המשתמש הבאים:
- סרגל הניווט של תנועת האחיזה
- שקוף כברירת מחדל.
- ההזזה למטה מושבתת, כך שהתוכן מצויר מאחורי סרגל הניווט של המערכת, אלא אם מחילים חתימות.
setNavigationBarColor
ו-R.attr#navigationBarColor
הוצאו משימוש והם לא משפיעים על הניווט באמצעות תנועות.- ל-
setNavigationBarContrastEnforced
ול-R.attr#navigationBarContrastEnforced
אין השפעה על הניווט באמצעות תנועות.
- ניווט ב-3 לחצנים
- כברירת מחדל, השקיפות מוגדרת ל-80%, והצבע עשוי להתאים לרקע החלון.
- ההזזה למטה מושבתת, כך שהתוכן מוצג מאחורי סרגל הניווט של המערכת, אלא אם מחילים חתימות.
- כברירת מחדל,
setNavigationBarColor
ו-R.attr#navigationBarColor
מוגדרים להתאים לרקע החלון. כדי שברירת המחדל הזו תחול, רקע החלון צריך להיות פריט גרפי וקטורי שניתן לשרטוט בצבע. ממשק ה-API הזה הוצא משימוש, אבל הוא עדיין משפיע על הניווט באמצעות 3 לחצנים. - הערכים של
setNavigationBarContrastEnforced
ו-R.attr#navigationBarContrastEnforced
מוגדרים כ-true כברירת מחדל, כך שמתווסף רקע אטום ב-80% במהלך ניווט ב-3 לחצנים.
- שורת סטטוס
- שקוף כברירת מחדל.
- ההזזה למעלה מושבתת, כך שהתוכן מצויר מאחורי סרגל הסטטוס, אלא אם מופעלים שיבוצים.
setStatusBarColor
ו-R.attr#statusBarColor
הוצאו משימוש ואין להם השפעה על Android 15.setStatusBarContrastEnforced
ו-R.attr#statusBarContrastEnforced
הוצאו משימוש, אבל עדיין יש להם השפעה על Android 15.
- חור במסך
- הערך של
layoutInDisplayCutoutMode
בחלונות לא צפים חייב להיותLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. הערכיםSHORT_EDGES
, NEVER
ו-DEFAULT
מפורשים כ-ALWAYS
כדי שהמשתמשים לא יראו פס שחור שנגרם כתוצאה מהחור במסך, והם יוצגו מקצה לקצה.
- הערך של
בדוגמה הבאה מוצגת אפליקציה לפני ואחרי הטירגוט ל-Android 15 (רמת API 35), וגם לפני ואחרי החלת אזורי inset.



מה בודקים אם האפליקציה כבר מוצגת מקצה לקצה
אם האפליקציה שלכם כבר מגיעה לקצה המסך ומשתמשת ברכיבי inset, לא צפויה להיות לכם השפעה משמעותית, מלבד בתרחישים הבאים. עם זאת, גם אם לדעתכם האפליקציה שלכם לא מושפעת, מומלץ לבדוק אותה.
- יש לכם חלון לא צף, כמו
Activity
שמשתמש ב-SHORT_EDGES
, ב-NEVER
או ב-DEFAULT
במקום ב-LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. אם האפליקציה קורסת בזמן ההפעלה, יכול להיות שהסיבה לכך היא מסך הפתיחה. אפשר לשדרג את התלות של core splashscreen ל-1.2.0-alpha01 או לגרסת גרסה מאוחרת יותר, או להגדיר אתwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
. - יכול להיות שיהיו מסכים עם תנועה נמוכה יותר עם ממשק משתמש חסום. מוודאים שהמסכים האלה, שבהם יש פחות ביקורים, לא מכסים את ממשק המשתמש. מסכים עם תנועה נמוכה יותר כוללים:
- מסכי קליטה או כניסה
- דפי הגדרות
מה צריך לבדוק אם האפליקציה עדיין לא מוצגת מקצה לקצה
אם האפליקציה שלכם עדיין לא תואמת למסך מלא, סביר להניח שהיא מושפעת מהשינוי. בנוסף לתרחישים לאפליקציות שכבר מוצגות מקצה לקצה, כדאי לשקול את האפשרויות הבאות:
- אם האפליקציה שלכם משתמשת ברכיבי Material 3 (
androidx.compose.material3
) ב-Compose, כמוTopAppBar
,BottomAppBar
ו-NavigationBar
, סביר להניח שהרכיבים האלה לא מושפעים מהשינוי כי הם מטפלים באופן אוטומטי בהכנסות. - אם באפליקציה שלכם נעשה שימוש ברכיבי Material 2 (
androidx.compose.material
) ב-Compose, הרכיבים האלה לא מטפלים באופן אוטומטי בהכנסות. עם זאת, אפשר לקבל גישה לתמונות הממוזערות ולהחיל אותן באופן ידני. ב-androidx.compose.material 1.6.0 ואילך, משתמשים בפרמטרwindowInsets
כדי להחיל את ה-insets באופן ידני עלBottomAppBar
,TopAppBar
,BottomNavigation
ו-NavigationRail
. באופן דומה, משתמשים בפרמטרcontentWindowInsets
עבורScaffold
. - אם באפליקציה שלכם נעשה שימוש בתצוגות וברכיבי Material (
com.google.android.material
), רוב רכיבי Material שמבוססים על תצוגות, כמוBottomNavigationView
,BottomAppBar
, NavigationRailView
אוNavigationView
, מטפלים בהוספת רכיבים לחלק הפנימי של המסך ולא נדרשת עבודה נוספת. עם זאת, צריך להוסיף אתandroid:fitsSystemWindows="true"
אם משתמשים ב-AppBarLayout
. - ברכיבים מותאמים אישית, מחילים את הרכיבים הפנימיים באופן ידני כמילוי. אם התוכן שלכם נמצא בתוך
Scaffold
, תוכלו להשתמש ב-insets באמצעות ערכי המילוי שלScaffold
. אחרת, מוסיפים את ה-padding באמצעות אחת מהפונקציותWindowInsets
. - אם האפליקציה שלכם משתמשת בתצוגות ובמאגרי תגים מסוג
BottomSheet
, SideSheet
או בהתאמה אישית, צריך להוסיף את הרווח באמצעותViewCompat.setOnApplyWindowInsetsListener
. ב-RecyclerView
, מוסיפים את הקוד של ה-listener הזה ומוסיפים גם אתclipToPadding="false"
.
מה צריך לבדוק אם האפליקציה שלכם חייבת להציע הגנה בהתאמה אישית ברקע
אם האפליקציה שלכם צריכה לספק הגנה בהתאמה אישית לרקע של סרגל הניווט עם 3 הלחצנים או של שורת הסטטוס, צריך להציב בה רכיב או תצוגה מאוחדים מאחורי סרגל המערכת באמצעות WindowInsets.Type#tappableElement()
כדי לקבל את הגובה של סרגל הניווט עם 3 הלחצנים או WindowInsets.Type#statusBars
.
משאבים נוספים מקצה לקצה
במאמרים תצוגות מקצה לקצה ועריכה מקצה לקצה מפורטות הנחיות נוספות לשימוש בפריימים חתוכים.
ממשקי API שהוצאו משימוש
ממשקי ה-API הבאים הוצאו משימוש, אבל לא הושבתו:
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
(לניווט ב-3 לחצנים, עם אלפא של 80%)Window#isStatusBarContrastEnforced
Window#setNavigationBarColor
(לניווט ב-3 לחצנים, עם 80% אלפא)Window#setStatusBarContrastEnforced
ממשקי ה-API הבאים הוצאו משימוש ומושבתים:
R.attr#navigationBarColor
(לניווט באמצעות תנועות)R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#setDecorFitsSystemWindows
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#setNavigationBarColor
(לניווט באמצעות תנועות)Window#setNavigationBarDividerColor
Window#setStatusBarColor
הגדרה יציבה
If your app targets Android 15 (API level 35) or higher, Configuration
no
longer excludes the system bars. If you use the screen size in the
Configuration
class for layout calculation, you should replace it with better
alternatives like an appropriate ViewGroup
, WindowInsets
, or
WindowMetricsCalculator
depending on your need.
Configuration
has been available since API 1. It is typically obtained from
Activity.onConfigurationChanged
. It provides information like window density,
orientation, and sizes. One important characteristic about the window sizes
returned from Configuration
is that it previously excluded the system bars.
The configuration size is typically used for resource selection, such as
/res/layout-h500dp
, and this is still a valid use case. However, using it for
layout calculation has always been discouraged. If you do so, you should move
away from it now. You should replace the use of Configuration
with something
more suitable depending on your use case.
If you use it to calculate the layout, use an appropriate ViewGroup
, such as
CoordinatorLayout
or ConstraintLayout
. If you use it to determine the height
of the system navbar, use WindowInsets
. If you want to know the current size
of your app window, use computeCurrentWindowMetrics
.
The following list describes the fields affected by this change:
Configuration.screenWidthDp
andscreenHeightDp
sizes no longer exclude the system bars.Configuration.smallestScreenWidthDp
is indirectly affected by changes toscreenWidthDp
andscreenHeightDp
.Configuration.orientation
is indirectly affected by changes toscreenWidthDp
andscreenHeightDp
on close-to-square devices.Display.getSize(Point)
is indirectly affected by the changes inConfiguration
. This was deprecated beginning in API level 30.Display.getMetrics()
has already worked like this since API level 33.
ברירת המחדל של המאפיין elegantTextHeight היא true
באפליקציות שמטרגטות את Android 15 (רמת API 35), המאפיין TextView
של elegantTextHeight
הופך ל-true
כברירת מחדל, ומחליף את הגופן הקומפקטי שמשמש כברירת מחדל בסקריפטים מסוימים עם מדדים אנכיים גדולים, בגופן שקל יותר לקרוא אותו.
הגופן הקומפקטי הוצג כדי למנוע הפרעה לפריסות. בגרסה Android 13 (רמת API 33) מונעים הרבה מהפרעות כאלה על ידי מתן אפשרות לפריסת הטקסט להתמתח לגובה האנכי באמצעות המאפיין fallbackLineSpacing
.
ב-Android 15, הגופן הקומפקטי עדיין נשאר במערכת, כך שהאפליקציה יכולה להגדיר את elegantTextHeight
ל-false
כדי לקבל את אותה התנהגות כמו קודם, אבל סביר להניח שהוא לא יקבל תמיכה בגרסאות הבאות. לכן, אם האפליקציה תומכת בסקריפטים הבאים: ערבית, לאוס, מיאנמר, טמילית, גוג'ראטית, קנאדה, מליאלאם, אודיה, טלוגו או תאית, צריך לבדוק את האפליקציה על ידי הגדרת elegantTextHeight
לערך true
.

elegantTextHeight
באפליקציות שמיועדות ל-Android 14 (רמת API 34) וגרסאות ישנות יותר.
elegantTextHeight
באפליקציות שמטרגטות את Android 15.שינויים ברוחב של TextView עבור צורות אותיות מורכבות
בגרסאות קודמות של Android, חלק מגופנים או שפות עם כתב מחובר עם עיצוב מורכב עשויים לצייר את האותיות באזור של התו הקודם או הבא.
במקרים מסוימים, אותיות כאלה נחתכו בנקודת ההתחלה או הסיום.
החל מ-Android 15, TextView
מקצה רוחב לציור מספיק מקום לאותיות כאלה ומאפשר לאפליקציות לבקש תוספת רווח שמימין כדי למנוע חיתוך.
מכיוון שהשינוי הזה משפיע על האופן שבו TextView
מחליט על הרוחב, TextView
מקצה יותר רוחב כברירת מחדל אם האפליקציה מטרגטת ל-Android 15 (רמת API 35) ואילך. אפשר להפעיל או להשבית את ההתנהגות הזו על ידי שליחת קריאה ל-API setUseBoundsForWidth
ב-TextView
.
הוספת רווח פנימי בצד ימין עלולה לגרום לחוסר התאמה של פריסות קיימות, ולכן הוא לא מתווסף כברירת מחדל גם לאפליקציות שמטרגטות את Android מגרסה 15 ואילך.
עם זאת, אפשר להוסיף עוד ריפוד כדי למנוע חיתוך על ידי קריאה ל-setShiftDrawingOffsetForStartOverhang
.
הדוגמאות הבאות מראות איך השינויים האלה יכולים לשפר את פריסת הטקסט בגופנים ובשפות מסוימים.

<TextView android:fontFamily="cursive" android:text="java" />

<TextView android:fontFamily="cursive" android:text="java" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />

<TextView android:text="คอมพิวเตอร์" />

<TextView android:text="คอมพิวเตอร์" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
גובה שורה שמוגדר כברירת מחדל בהתאם לאזור הגיאוגרפי של EditText
בגרסאות קודמות של Android, פריסת הטקסט הגדילה את גובה הטקסט כדי להתאים לגובה השורה של הגופן שתואם לאזור הנוכחי. לדוגמה, אם התוכן היה ביפנית, הגובה של הטקסט השתנה מעט כי גובה השורה של הגופן היפני גדול מעט מזה של גופן לטינית. עם זאת, למרות ההבדלים האלה בגובה השורות, הגודל של הרכיב EditText
היה אחיד, ללא קשר לאזור הזמן שבו נעשה שימוש, כפי שמוצג בתמונה הבאה:

EditText
שיכולים להכיל טקסט באנגלית (en), ביפנית (ja) ובבורמזית (my). הגובה של EditText
זהה, למרות שלשפות האלה יש גובה שורות שונה זו מזו.באפליקציות שמטרגטות את Android 15 (רמת API 35), גובה שורה מינימלי מוקצה עכשיו ל-EditText
כדי להתאים לגופן העזר של האזור הגיאוגרפי שצוין, כפי שמוצג בתמונה הבאה:

EditText
שיכולים להכיל טקסט באנגלית (en), ביפנית (ja) ובבורמזית (my). הגובה של EditText
כולל עכשיו מקום שמתאים לגובה השורה שמוגדר כברירת מחדל לגופנים של השפות האלה.אם צריך, אפשר לשחזר את ההתנהגות הקודמת של האפליקציה על ידי ציון הערך false
למאפיין useLocalePreferredLineHeightForMinimum
. אפשר גם להגדיר באפליקציה מדדים מינימליים מותאמים אישית של מודעות רגילות באמצעות ממשק ה-API setMinimumFontMetrics
ב-Kotlin וב-Java.
מצלמה ומדיה
ב-Android 15 יש שינויים בהתנהגות של המצלמה והמדיה באפליקציות שמטרגטות ל-Android 15 ואילך.
הגבלות על בקשות להתמקד באודיו
Apps that target Android 15 (API level 35) must be the top app or running a
foreground service in order to request audio focus. If an app
attempts to request focus when it does not meet one of these requirements, the
call returns AUDIOFOCUS_REQUEST_FAILED
.
You can learn more about audio focus at Manage audio focus.
עדכון ההגבלות על רכיבים שאינם SDK
מערכת Android 15 כוללת רשימות מעודכנות של ממשקים מוגבלים שאינם ערכות SDK, על סמך שיתוף פעולה עם מפתחי Android והבדיקה הפנימית האחרונה. כשהדבר אפשרי, אנחנו מוודאים שיש חלופות ציבוריות זמינות לפני שאנחנו מגבילים ממשקים שאינם ב-SDK.
אם האפליקציה שלכם לא מטרגטת את Android 15, יכול להיות שחלק מהשינויים האלה לא ישפיעו עליכם באופן מיידי. עם זאת, אמנם אפשר לתת לאפליקציה גישה לממשקים מסוימים שאינם SDK בהתאם לרמת ה-API לטירגוט של האפליקציה, אבל שימוש בשדה או בשיטה שלא שייכים ל-SDK תמיד כרוך בסיכון גבוה לקריסת האפליקציה.
אם אתם לא בטוחים אם באפליקציה שלכם נעשה שימוש בממשקים שאינם SDK, תוכלו לבדוק את האפליקציה כדי לברר זאת. אם האפליקציה שלכם מסתמכת על ממשקים שאינם SDK, כדאי להתחיל לתכנן את המעבר לחלופות ל-SDK. עם זאת, אנחנו מבינים שלאפליקציות מסוימות יש תרחישים ריאליים לשימוש בממשקים שאינם SDK. אם לא מצאתם חלופה לשימוש בממשק שאינו SDK עבור תכונה באפליקציה, עליכם לבקש ממשק API ציבורי חדש.
To learn more about the changes in this release of Android, see Updates to non-SDK interface restrictions in Android 15. To learn more about non-SDK interfaces generally, see Restrictions on non-SDK interfaces.