Modifiche del comportamento: app destinate ad Android 15 o versioni successive

Come le release precedenti, Android 15 include modifiche del comportamento che potrebbero interessare la tua app. Le seguenti modifiche del comportamento si applicano esclusivamente alle app che: che hanno come target Android 15 o versioni successive. Se la tua app ha come target Android 15 o versioni successive, devi modificare l'app per supportare correttamente questi comportamenti, dove applicabile.

Assicurati di esaminare anche l'elenco delle modifiche del comportamento che interessano tutte le app. su Android 15 indipendentemente dall'targetSdkVersion dell'app.

Funzionalità di base

Android 15 modifica o espande varie funzionalità di base del sistema Android.

Modifiche ai servizi in primo piano

我们将在 Android 15 中对前台服务进行以下更改。

数据同步前台服务超时行为

Android 15 introduce un nuovo comportamento di timeout in dataSync per il targeting per app Android 15 (livello API 35) o versioni successive. Questo comportamento vale anche per i nuovi mediaProcessing tipo di servizio in primo piano.

Il sistema consente l'esecuzione dei servizi dataSync di un'app per un totale di 6 ore in un periodo di 24 ore, dopodiché il sistema chiama Metodo Service.onTimeout(int, int) (introdotto su Android 15). Al momento, il servizio ha alcuni secondi di tempo per chiamare Service.stopSelf() Quando viene chiamato Service.onTimeout(), il parametro non è più considerato un servizio in primo piano. Se il servizio non chiama Service.stopSelf(), il sistema genera un'eccezione interna. La viene registrata in Logcat con il seguente messaggio:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"

Per evitare problemi con questa modifica del comportamento, puoi eseguire una o più delle seguenti operazioni seguenti:

  1. Fai in modo che il tuo servizio implementi il nuovo metodo Service.onTimeout(int, int). Quando la tua app viene richiamata, assicurati di chiamare il numero stopSelf() entro un per alcuni secondi. Se non interrompi subito l'app, il sistema genera errore).
  2. Assicurati che i servizi dataSync della tua app non vengano eseguiti per un totale di più di 6 ore in un periodo di 24 ore (a meno che l'utente non interagisca con l'app, reimpostare il timer).
  3. Avvia dataSync servizi in primo piano solo da un utente diretto interazione; poiché l'app è in primo piano all'avvio del servizio, il servizio ha tutte le sei ore dopo che l'app è passata in background.
  4. Anziché utilizzare un servizio in primo piano dataSync, usa un'istanza API alternativa.

Se i servizi in primo piano dataSync della tua app sono stati eseguiti per 6 ore nelle ultime 6 ore 24, non puoi avviare un altro servizio in primo piano dataSync a meno che l'utente ha messo la tua app in primo piano (operazione che reimposta il timer). Se provi a avviare un altro servizio in primo piano dataSync, il sistema genera ForegroundServiceStartNotAllowedException con un messaggio di errore del tipo "Limite di tempo già esaurito per il servizio in primo piano digita dataSync".

Test

Per verificare il comportamento della tua app, puoi attivare i timeout per la sincronizzazione dei dati anche se l'app non abbia come target Android 15 (purché l'app sia installata su un dispositivo Android 15) dispositivo). Per abilitare i timeout, esegui questo comando adb:

adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name

Puoi anche regolare il periodo di timeout per verificare più facilmente come l'app si comporta quando viene raggiunto il limite. Per impostare un nuovo periodo di timeout, esegui il comando seguente comando adb:

adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds

新建媒体处理前台服务类型

Android 15 introduce un nuovo tipo di servizio in primo piano, mediaProcessing. Questo è appropriato per operazioni come la transcodifica di file multimediali. Per Ad esempio, un'app multimediale può scaricare un file audio e deve convertirlo in un un formato diverso prima di riprodurlo. Puoi utilizzare un primo piano mediaProcessing per assicurarti che la conversione continui anche mentre l'app è sfondo.

Il sistema consente l'esecuzione dei servizi mediaProcessing di un'app per un totale di 6 in un periodo di 24 ore, dopodiché il sistema chiama Metodo Service.onTimeout(int, int) (introdotto su Android 15). Al momento, il servizio ha alcuni secondi di tempo per chiamare Service.stopSelf() Se il servizio non chiama Service.stopSelf(), il sistema genera un'eccezione interna. La viene registrata in Logcat con il seguente messaggio:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"

Per evitare questa eccezione, puoi procedere in uno dei seguenti modi:

  1. Fai in modo che il tuo servizio implementi il nuovo metodo Service.onTimeout(int, int). Quando la tua app viene richiamata, assicurati di chiamare il numero stopSelf() entro un per alcuni secondi. Se non interrompi subito l'app, il sistema genera errore).
  2. Assicurati che i servizi mediaProcessing della tua app non vengano eseguiti per più di un totale di 6 ore in un periodo di 24 ore (a meno che l'utente non interagisca con l'app, reimpostando il timer).
  3. Avvia mediaProcessing servizi in primo piano solo dall'utente diretto interazione; poiché l'app è in primo piano all'avvio del servizio, il servizio ha tutte le sei ore dopo che l'app è passata in background.
  4. Anziché utilizzare un servizio in primo piano mediaProcessing, usa una alternativa API, come WorkManager.

Se i servizi in primo piano mediaProcessing della tua app sono stati eseguiti da 6 ore in ultimi 24, non puoi avviare un altro mediaProcessing servizio in primo piano a meno che l'utente ha messo in primo piano la tua app (operazione che reimposta il timer). Se provare ad avviare un altro servizio in primo piano mediaProcessing, il sistema restituisce ForegroundServiceStartNotAllowedException con un messaggio di errore del tipo "Limite di tempo già esaurito per il servizio in primo piano tipo mediaProcessing".

Per ulteriori informazioni sul tipo di servizio mediaProcessing, consulta l'articolo Modifiche a tipi di servizi in primo piano per Android 15: elaborazione dei contenuti multimediali.

Test

Per testare il comportamento della tua app, puoi attivare i timeout per l'elaborazione dei contenuti multimediali anche se la tua app non ha come target Android 15 (purché l'app sia in esecuzione su un dispositivo Android 15). Per abilitare i timeout, esegui questo comando adb:

adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name

Puoi anche regolare il periodo di timeout per verificare più facilmente come l'app si comporta quando viene raggiunto il limite. Per impostare un nuovo periodo di timeout, esegui il comando seguente comando adb:

adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds

对启动前台服务的 BOOT_COMPLETED 广播接收器实施限制

Esistono nuove limitazioni per i BOOT_COMPLETED ricevitori di trasmissione che avviano servizi in primo piano. BOOT_COMPLETED di destinatari non sono autorizzati ad avviare il i seguenti tipi di servizi in primo piano:

Se un receiver BOOT_COMPLETED tenta di avviare uno di questi tipi di servizi in primo piano, il sistema genera un'eccezione ForegroundServiceStartNotAllowedException.

Test

Per verificare il comportamento della tua app, puoi attivare queste nuove limitazioni anche se le tue L'app non ha come target Android 15 (purché l'app sia installata su un Android 15) dispositivo). Esegui il seguente comando adb:

adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name

Per inviare un annuncio BOOT_COMPLETED senza riavviare il dispositivo: esegui questo comando adb:

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name

限制在应用拥有 SYSTEM_ALERT_WINDOW 权限时启动前台服务

In precedenza, se un'app aveva l'autorizzazione SYSTEM_ALERT_WINDOW, poteva avviarsi un servizio in primo piano anche se l'app era attualmente in background (ad esempio, discusso in Esenzioni dalle limitazioni relative all'avvio in background.

Se un'app ha come target Android 15, l'esenzione è ora più limitata. L'app ora deve per avere l'autorizzazione SYSTEM_ALERT_WINDOW e avere anche un overlay visibile finestra. Questo significa che l'app deve prima avviare TYPE_APPLICATION_OVERLAY finestra e finestra deve essere visibile prima di avviare un servizio in primo piano.

Se la tua app tenta di avviare un servizio in primo piano in background senza che soddisfano questi nuovi requisiti (e non prevede altre esenzioni), i genera ForegroundServiceStartNotAllowedException.

Se la tua app dichiara l'autorizzazione SYSTEM_ALERT_WINDOW e avvia i servizi in primo piano in background, potrebbe essere interessato da questa modifica. Se la tua app riceve un ForegroundServiceStartNotAllowedException, controlla l'ordine di operazioni dell'app e assicurati che abbia già un indirizzo prima che tenti di avviare un servizio in primo piano dall' sfondo. Puoi verificare se la finestra dell'overlay è attualmente visibile chiamando il numero View.getWindowVisibility() oppure può eseguire l'override di View.onWindowVisibilityChanged() di ricevere una notifica ogni volta che la visibilità cambia.

Test

Per verificare il comportamento della tua app, puoi attivare queste nuove limitazioni anche se le tue L'app non ha come target Android 15 (purché l'app sia installata su un Android 15) dispositivo). Per attivare queste nuove limitazioni all'avvio dei servizi in primo piano: in background, esegui questo comando adb:

adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name

Modifiche relative a quando le app possono modificare lo stato globale della modalità Non disturbare

Le app destinate ad Android 15 non possono più modificare lo stato o il criterio globale della modalità Non disturbare su un dispositivo (modificando le impostazioni utente o disattivando la modalità DND). Le app devono però fornire un codice AutomaticZenRule, che il sistema combina in un criterio globale con lo schema con il criterio più restrittivo e vincente. Le chiamate alle API esistenti che in precedenza influenzavano lo stato globale (setInterruptionFilter, setNotificationPolicy) comportano la creazione o l'aggiornamento di un elemento AutomaticZenRule implicito, che viene attivato e disattivato a seconda del ciclo di chiamata di queste chiamate API.

Tieni presente che questa modifica influisce solo sul comportamento osservabile se l'app chiama setInterruptionFilter(INTERRUPTION_FILTER_ALL) e si aspetta che quella chiamata disattivi un AutomaticZenRule che era stato precedentemente attivato dai rispettivi proprietari.

Modifiche all'API OpenJDK

Android 15 continua il lavoro di aggiornamento delle librerie principali di Android per allineare con le funzionalità delle ultime release di OpenJDK LTS.

Alcune di queste modifiche possono influire sulla compatibilità delle app per il targeting per app Android 15 (livello API 35):

  • Modifiche alle API di formattazione delle stringhe: convalida di indice di argomenti, flag la larghezza e la precisione sono ora più rigide quando si utilizza API String.format() e Formatter.format():

    Ad esempio, la seguente eccezione viene generata quando un indice di argomento è 0 (%0 nella stringa di formato):

    IllegalFormatArgumentIndexException: Illegal format argument index = 0
    

    In questo caso, il problema può essere risolto utilizzando un indice di argomento pari a 1 (%1 nella stringa di formato).

  • Modifiche al tipo di componente di Arrays.asList(...).toArray(): quando si utilizza Arrays.asList(...).toArray(), il tipo di componente dell'array risultante è ora Object, non il tipo di elementi dell'array sottostante. Quindi, seguente codice genera un ClassCastException:

    String[] elements = (String[]) Arrays.asList("one", "two").toArray();
    

    In questo caso, per mantenere String come tipo di componente nel risultato puoi utilizzare Collection.toArray(Object[]):

    String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
    
  • Modifiche alla gestione del codice lingua: quando utilizzi l'API Locale, i codici lingua per ebraico, yiddish e indonesiano non vengono più convertiti alle loro forme obsolete (ebraico: iw, yiddish: ji e indonesiano: in). Quando specifichi il codice lingua per una di queste lingue, utilizza i codici ISO 639-1 (ebraico: he, Yiddish: yi e indonesiano: id).

  • Modifiche alle sequenze int casuali: l'applicazione delle modifiche apportate in https://bugs.openjdk.org/browse/JDK-8301574, i seguenti I metodi Random.ints() ora restituiscono una sequenza di numeri diversa rispetto a i metodi Random.nextInt():

    In genere, questa modifica non deve portare a un comportamento in grado di rompere gli utenti, ma nel codice non deve aspettarsi che la sequenza generata dai metodi Random.ints() corrispondono a Random.nextInt().

La nuova API SequencedCollection può influire sulla compatibilità della tua app dopo aver aggiornato compileSdk nella configurazione della build dell'app per utilizzare Android 15 (livello API 35):

  • Collisione con MutableList.removeFirst() e Funzioni dell'estensione MutableList.removeLast() in kotlin-stdlib

    Il tipo List in Java è mappato al tipo MutableList in Kotlin. Poiché le API List.removeFirst() e List.removeLast() sono state introdotte in Android 15 (livello API 35), il compilatore Kotlin risolve le chiamate di funzione, ad esempio list.removeFirst(), in modo statico le nuove API List anziché le funzioni di estensione in kotlin-stdlib.

    Se un'app viene ricompilata con compileSdk impostato su 35 e minSdk impostato su 34 o versioni precedenti, quindi l'app viene eseguita su Android 14 e versioni precedenti, viene visualizzato un errore:

    java.lang.NoSuchMethodError: No virtual method
    removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
    

    L'opzione lint NewApi esistente nel plug-in Android Gradle può rilevare questi nuovi utilizzi dell'API.

    ./gradlew lint
    
    MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi]
          list.removeFirst()
    

    Per correggere l'eccezione di runtime e gli errori di lint, i valori removeFirst() e Le chiamate di funzione removeLast() possono essere sostituite con removeAt(0) e removeAt(list.lastIndex) rispettivamente a Kotlin. Se utilizzi Android Studio Ladybug | 2024.1.3 o versioni successive, fornisce anche una correzione rapida per questi errori.

    Valuta la possibilità di rimuovere @SuppressLint("NewApi") e lintOptions { disable 'NewApi' } se l'opzione lint è stata disattivata.

  • Collisione con altri metodi in Java

    Nei tipi esistenti sono stati aggiunti nuovi metodi, ad esempio List e Deque. Questi nuovi metodi potrebbero non essere compatibili con i metodi con lo stesso nome e tipi di argomento in altre interfacce e corsi. Nel caso di una collisione tra firme di metodo e incompatibilità, il compilatore javac restituisce un errore in fase di build. Per esempio:

    Esempio di errore 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 List
    

    Esempio di errore 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 error
    

    Esempio di errore 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 error
    

    Per correggere questi errori di generazione, il corso che implementa queste interfacce deve sostituisci il metodo con un tipo restituito compatibile. Ad esempio:

    @Override
    public Object getFirst() {
        return List.super.getLast();
    }
    

Sicurezza

Android 15 include modifiche che promuovono la sicurezza del sistema per contribuire a proteggere le app e gli utenti di app dannose.

Lanci di attività in background protette

Android 15 可保护用户免受恶意应用的侵害,并让用户更好地控制 来防止恶意后台应用 将其他应用置于前台、提升其权限以及滥用 用户互动自以下时间以来,后台活动启动一直受到限制 Android 10(API 级别 29)。

禁止与堆栈中的顶部 UID 不匹配的应用启动 activity

恶意应用可以在同一任务中启动另一个应用的 activity,然后 叠加在上面,营造出像该应用一样的错觉。这个“任务” 劫持"攻击绕过了当前的后台启动限制, 会发生在同一个可见任务中。为了降低这种风险,Android 15 新增了 用于阻止与堆栈中的顶层 UID 不匹配的应用启动的标志 活动。如需选择启用应用的所有活动,请更新 allowCrossUidActivitySwitchFromBelow 属性:AndroidManifest.xml

<application android:allowCrossUidActivitySwitchFromBelow="false" >

如果满足以下所有条件,则启用新的安全措施:

  • 执行启动的应用以 Android 15 为目标平台。
  • 任务堆栈顶部的应用以 Android 15 为目标平台。
  • 所有可见活动都已选择启用新保护措施

如果启用了安全措施,应用可能会返回主屏幕,而不是返回 最后一个可见应用(如果他们自行完成任务)。

其他变更

除了限制 UID 匹配之外,这些其他变更也 包括:

  • 更改 PendingIntent 创作者,以阻止后台活动启动,具体方法是: 默认。这有助于防止应用意外创建 可能被恶意操作者滥用的 PendingIntent
  • 请勿将应用调到前台,除非 PendingIntent 发送者 允许它。此变更旨在防止恶意应用滥用 在后台启动 activity 的功能。默认情况下,应用 允许将任务堆栈转到前台,除非创建者允许 后台活动启动权限或发送者有后台活动 启动权限
  • 控制任务堆栈的顶层 activity 完成其任务的方式。如果 顶层 activity 完成一项任务后,Android 会返回到之前执行的 上次活动时间。此外,如果非顶层 activity 完成其任务,Android 将 返回主屏幕;因此不会阻碍这个非顶层的 活动。
  • 防止将其他应用中的任意 activity 启动到您自己的 activity 任务。这项变更旨在防止恶意应用 看起来像是来自其他应用的活动
  • 禁止将不可见窗口视为后台活动 发布。这有助于防止恶意应用滥用后台 activity 来向用户显示不需要或恶意的内容。

Intent più sicuri

Android 15 引入了新的安全措施,可让 intent 更加安全且更安全 稳健。这些变更旨在防范潜在的漏洞和 可能会被恶意应用利用的 intent 滥用。有两个主要的 Android 15 中对 intent 安全性的改进:

  • 匹配目标 intent 过滤器:针对特定组件的 intent 准确匹配目标的 intent 过滤器规范。如果您发送 intent 来启动另一个应用的 activity,则目标 intent 组件需要 与接收 activity 声明的 intent 过滤器保持一致。
  • intent 必须具有操作:没有操作的 intent 将不再匹配 任何 intent 过滤器。也就是说,用于启动 activity 或 服务都必须有明确定义的操作。
  • 待处理 intent:待处理 intent 的创建者被视为封装 intent 的发送者,而非待处理 intent 的发送者 意图

Kotlin


fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        .detectUnsafeIntentLaunch()
        .build()
    )
}

Java


public void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
            .detectUnsafeIntentLaunch()
            .build());
}

Esperienza utente e UI di sistema

Android 15 include alcune modifiche volte a creare un un'esperienza utente intuitiva.

Modifiche agli riquadri delle finestre

Esistono due modifiche relative ai riquadri di finestre in Android 15: edge-to-edge è applicato per impostazione predefinita e esistono anche modifiche alla configurazione, ad esempio la configurazione predefinita delle barre di sistema.

Applicazione edge-to-edge

在搭载 Android 15 的设备上,应用会默认采用全屏 以 Android 15(API 级别 35)为目标平台。

<ph type="x-smartling-placeholder">
</ph>
一款以 Android 14 为目标平台且在 Android 设备上未处于无边框的应用 Android 15 设备。


<ph type="x-smartling-placeholder">
</ph>
一款以 Android 15(API 级别 35)为目标平台且采用无边框的应用 在 Android 15 设备上。此应用主要使用 Material 3 Compose 组件 自动应用边衬区此屏幕不会受到 Android 15 全屏强制执行。

这是一项可能会对应用的界面产生负面影响的破坏性更改。通过 更改会影响以下界面区域:

  • 手势手柄导航栏 <ph type="x-smartling-placeholder">
      </ph>
    • 默认透明。
    • 底部偏移量已停用,因此内容绘制在系统导航栏后面 栏。
    • setNavigationBarColorR.attr#navigationBarColor 已弃用,不会影响手势导航。
    • setNavigationBarContrastEnforcedR.attr#navigationBarContrastEnforced不会对 手势导航。
  • “三按钮”导航 <ph type="x-smartling-placeholder">
      </ph>
    • 默认不透明度设为 80%,颜色可能与窗口一致 背景。
    • 底部偏移值已停用,因此内容绘制在系统导航栏后面 除非应用了边衬区。
    • setNavigationBarColorR.attr#navigationBarColor 默认设置为与窗口背景匹配。窗口背景 必须是颜色可绘制对象,才能应用此默认值。此 API 是 但会继续影响“三按钮”导航。
    • setNavigationBarContrastEnforcedR.attr#navigationBarContrastEnforced 默认为 true,这会添加一个 “三按钮”导航模式显示 80% 不透明的背景。
  • 状态栏 <ph type="x-smartling-placeholder">
      </ph>
    • 默认透明。
    • 顶部偏移量已停用,因此除非 边衬区。
    • setStatusBarColorR.attr#statusBarColor 已废弃,对 Android 15 没有任何影响。
    • setStatusBarContrastEnforcedR.attr#statusBarContrastEnforced 已弃用,但仍具有 对 Android 15 的影响。
  • 刘海屏 <ph type="x-smartling-placeholder">
      </ph>
    • layoutInDisplayCutoutMode 的非浮动窗口必须是 LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYSSHORT_EDGESNEVER和 系统会将 DEFAULT 解释为 ALWAYS,这样用户就不会看到黑色图标 长条形尺寸,显示为无边框。

以下示例显示了定位前后的应用 Android 15(API 级别 35)以及应用边衬区之前和之后。

<ph type="x-smartling-placeholder">
</ph>
一款以 Android 14 为目标平台且在 Android 设备上未处于无边框的应用 Android 15 设备。
。 <ph type="x-smartling-placeholder">
</ph>
一款以 Android 15(API 级别 35)为目标平台且为无边框应用 在 Android 15 设备上。不过,许多元素 栏、“三按钮”导航栏或刘海屏(由于 Android 15) 全屏强制措施。隐藏界面包含 Material 2 顶部应用栏、悬浮操作按钮和列表项。
。 <ph type="x-smartling-placeholder">
</ph>
如果应用以 Android 15(API 级别 35)为目标平台, Android 15 设备并应用边衬区,这样界面就不会 已隐藏。
检查应用是否已采用全屏的检查步骤

如果您的应用已经采用无边框且应用了边衬区, 基本未受影响,但下列情况除外。但即使您认为 您不会受到影响,但我们建议您测试自己的应用。

  • 您的非浮动窗口(例如 Activity)使用 SHORT_EDGESNEVERDEFAULT,而不是 LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS。如果您的应用在启动时崩溃 可能是启动画面所致您可以升级核心 初始屏幕依赖项更改为 1.2.0-alpha01 或更高版本,或者设置 window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
  • 可能会有流量较低的屏幕显示被遮挡的界面。验证这些 访问较少的屏幕也不会显示被遮挡的界面。流量较低的屏幕包括: <ph type="x-smartling-placeholder">
      </ph>
    • 初始配置或登录屏幕
    • “设置”页面
如何检查应用尚未实现无边框

如果您的应用还没有全面屏,那么您很可能会受到影响。在 除了针对已经采用无边框的应用的情况之外, 请考虑以下事项:

  • 如果您的应用使用 Material 3 组件 ( androidx.compose.material3),例如 TopAppBarBottomAppBarNavigationBar,那么这些组件可能 会受到影响,因为它们会自动处理边衬区。
  • 如果您的应用使用 Material 2 组件 ( androidx.compose.material),那么这些组件 不会自动处理边衬区。不过,您可以使用边衬区 并手动应用这些设置在 androidx.compose.material 1.6.0 中 然后使用 windowInsets 参数手动应用边衬区 BottomAppBarTopAppBarBottomNavigationNavigationRail。 同样,对以下内容使用 contentWindowInsets 形参: Scaffold
  • 如果您的应用使用视图和 Material 组件 (com.google.android.material),大多数基于 View 的 Material 如 BottomNavigationViewBottomAppBarNavigationRailViewNavigationView,处理边衬区,不需要 额外工作。但是,您需要将 android:fitsSystemWindows="true" 如果使用 AppBarLayout,则会发生此错误。
  • 对于自定义可组合项,请手动将边衬区作为内边距应用。如果您的 内容位于 Scaffold 内,因此您可以使用 Scaffold 来使用边衬区 内边距值。否则,使用 WindowInsets
  • 如果您的应用使用的是视图和 BottomSheetSideSheet 或自定义 使用 ViewCompat.setOnApplyWindowInsetsListener。对于 RecyclerView,使用此监听器应用内边距,同时添加 clipToPadding="false"
检查应用是否必须提供自定义后台保护的注意事项

如果您的应用必须为“三按钮”导航或 状态栏,则应用应将可组合项或视图放在系统栏后面 使用 WindowInsets.Type#tappableElement() 获取三按钮 导航栏高度或 WindowInsets.Type#statusBars

其他无边框资源

请参阅无边框视图无边框 Compose 了解应用边衬区的其他注意事项。

已弃用的 API

以下 API 现已弃用:

Configurazione stabile

如果您的应用以 Android 15(API 级别 35)或更高版本为目标平台,Configuration 否 不再包含系统栏。如果您使用 Configuration 类,您应将其替换为更好的 相应的 ViewGroupWindowInsetsWindowMetricsCalculator,具体取决于您的需求。

Configuration 从 API 1 开始提供。它通常从 Activity.onConfigurationChanged。它提供窗口密度、 屏幕方向和尺寸窗口大小的一个重要特征 Configuration 之前会排除系统栏。

配置大小通常用于选择资源,例如 /res/layout-h500dp,这仍然是一个有效的用例。但将其用于 但一直不建议进行布局计算。如果需要,您应该将 现在离它远去。您应该使用 Configuration 具体取决于您的应用场景。

如果使用它来计算布局,请使用适当的 ViewGroup,例如 CoordinatorLayoutConstraintLayout。如果使用该属性确定高度 ,请使用 WindowInsets。如果您想知道当前尺寸 ,请使用 computeCurrentWindowMetrics

以下列表介绍了受此变更影响的字段:

L'attributo eleganteTextHeight è impostato su true per impostazione predefinita

Per le app che hanno come target Android 15, l'attributo elegantTextHeight TextView diventa true per impostazione predefinita, sostituendo il carattere compatto usato per impostazione predefinita con alcuni script che hanno metriche verticali di grandi dimensioni con una molto più leggibile. Il carattere compatto è stato introdotto per evitare interruzioni nei layout. Android 13 (livello API 33) impedisce molte di queste interruzioni consentendo al layout del testo di estendere l'altezza verticale utilizzando l'attributo fallbackLineSpacing.

In Android 15, il carattere compatto rimane ancora nel sistema, pertanto la tua app può impostare elegantTextHeight su false per avere lo stesso comportamento di prima, ma è improbabile che sia supportato nelle prossime release. Pertanto, se la tua app supporta i seguenti script: arabo, laotiano, Myanmar, tamil, gujarati, kannada, malayalam, Odia, telugu o thailandese, testa l'app impostando elegantTextHeight su true.

Comportamento di elegantTextHeight per le app che hanno come target Android 14 (livello API 34) e versioni precedenti.
Comportamento di elegantTextHeight per le app destinate ad Android 15.

Cambia la larghezza di TextView per forme di lettere complesse

Nelle versioni precedenti di Android, alcuni caratteri o linguaggi corsivi con una forma complessa può tracciare le lettere nell'area del carattere precedente o successivo. In alcuni casi, queste lettere venivano tagliate nella posizione iniziale o finale. A partire da Android 15, TextView alloca la larghezza per disegnare spazio sufficiente tali caratteri e consente alle app di richiedere spaziature interne aggiuntive a sinistra evitare il ritaglio.

Poiché questa modifica influisce sul modo in cui TextView decide la larghezza, TextView alloca più larghezza per impostazione predefinita se l'app ha come target Android 15 (livello API 35) oppure in alto. Puoi abilitare o disabilitare questo comportamento richiamando il metodo API setUseBoundsForWidth su TextView.

Poiché l'aggiunta di una spaziatura interna a sinistra potrebbe causare un disallineamento per i layout esistenti, La spaziatura interna non viene aggiunta per impostazione predefinita anche per le app destinate ad Android 15 o versioni successive. Tuttavia, puoi aggiungere spaziatura interna extra per evitare il ritaglio chiamando setShiftDrawingOffsetForStartOverhang.

I seguenti esempi mostrano come queste modifiche possono migliorare il layout del testo per alcuni caratteri e lingue.

Layout standard per il testo inglese con carattere corsivo. Alcuni dei le lettere sono tagliate. Ecco il codice XML corrispondente:

<TextView
    android:fontFamily="cursive"
    android:text="java" />
Layout per lo stesso testo in inglese con larghezza e spaziatura interna. Ecco il codice XML corrispondente:

<TextView
    android:fontFamily="cursive"
    android:text="java"
    android:useBoundsForWidth="true"
    android:shiftDrawingOffsetForStartOverhang="true" />
Layout standard per testo tailandese. Alcune lettere sono tagliate. Ecco il codice XML corrispondente:

<TextView
    android:text="คอมพิวเตอร์" />
Layout per lo stesso testo in tailandese con larghezza e spaziatura interna. Ecco il codice XML corrispondente:

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

Altezza della riga predefinita sensibile alle impostazioni internazionali per EditText

在以前的 Android 版本中,文本布局拉伸了文本的高度,使其适应与当前语言区域匹配的字体的行高。例如,如果内容是日语,由于日语字体的行高比拉丁字体的行高略大,因此文本的高度就略大了。不过,尽管行高存在这些差异,但无论使用何种语言区域,EditText 元素的大小都是一致的,如下图所示:

三个表示 EditText 元素的框,这些框可以包含英语 (en)、日语 (ja) 和缅甸语 (my) 的文本。EditText 的高度相同,即使这两种语言的行高不同。

对于以 Android 15 为目标平台的应用,系统现在会为 EditText 预留最小行高,以匹配指定语言区域的参考字体,如下图所示:

三个表示 EditText 元素的框,这些框可以包含英语 (en)、日语 (ja) 和缅甸语 (my) 的文本。EditText 的高度现在包含空间,可适应这些语言字体的默认行高。

如果需要,您的应用可以通过将 useLocalePreferredLineHeightForMinimum 属性设置为 false 来恢复之前的行为,并且可以通过 Kotlin 和 Java 中的 setMinimumFontMetrics API 设置自定义最小行业指标。

Fotocamera e contenuti multimediali

Android 15 apporta le seguenti modifiche al comportamento della fotocamera e dei contenuti multimediali per le app che hanno come target Android 15 o versioni successive.

Limitazioni relative alla richiesta di focus audio

Le app destinate ad Android 15 devono essere quelle di primo livello o avere un servizio in primo piano per poter richiedere lo stato attivo dell'audio. Se un'app tenta di richiedere lo stato attivo quando non soddisfa uno di questi requisiti, la chiamata restituisce AUDIOFOCUS_REQUEST_FAILED.

Puoi scoprire di più sulla messa a fuoco audio su Gestire il focus audio.

Limitazioni non SDK aggiornate

Android 15 include elenchi aggiornati di elementi non SDK soggetti a restrizioni basate sulla collaborazione con gli sviluppatori Android e le applicazioni per i test interni. Quando possibile, facciamo in modo che le alternative pubbliche siano disponibili prima che vengano limitate le interfacce non SDK.

Se la tua app non ha come target Android 15, alcune di queste modifiche potrebbero non riguardarti immediatamente. Tuttavia, sebbene la tua app possa Accedere ad alcune interfacce non SDK a seconda del livello API target dell'app, utilizzando qualsiasi SDK metodo o campo comporta sempre un rischio elevato di danneggiare l'app.

Se non sai con certezza se la tua app utilizza interfacce non SDK, puoi testarla per scoprirlo. Se la tua app si basa su modelli non SDK dovresti iniziare a pianificare una migrazione alle alternative SDK. Tuttavia, siamo consapevoli che alcune app hanno casi d'uso validi per l'utilizzo di interfacce non SDK. Se non riesci a trovare un'alternativa all'utilizzo di una versione non SDK per una funzionalità dell'app, devi richiedere una nuova API pubblica.

Per scoprire di più sulle modifiche in questa release di Android, consulta Aggiornamenti alle limitazioni relative alle interfacce non SDK in Android 15. Per scoprire di più sulle interfacce non SDK in generale, consulta Restrizioni sulle interfacce non SDK.