Come nelle release precedenti, Android 15 include modifiche del comportamento che potrebbero interessare la tua app. Le seguenti modifiche del comportamento si applicano esclusivamente alle app destinate ad Android 15 o versioni successive. Se la tua app ha come target Android 15 o versioni successive, devi modificare l'app in modo da supportare correttamente questi comportamenti, ove applicabile.
Assicurati di esaminare anche l'elenco delle modifiche del comportamento che interessano tutte le app
in esecuzione 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 o versioni successive. Questo comportamento vale anche per le nuove 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:
- 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 numerostopSelf()
entro un per alcuni secondi. Se non interrompi subito l'app, il sistema genera errore). - 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). - 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. - 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:
- 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 numerostopSelf()
entro un per alcuni secondi. Se non interrompi subito l'app, il sistema genera errore). - 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). - 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. - 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 il lancio di BOOT_COMPLETED
broadcast receiver
e i servizi in primo piano. BOOT_COMPLETED
di destinatari non sono autorizzati ad avviare il
i seguenti tipi di servizi in primo piano:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(questa limitazione è in vigore permicrophone
dal giorno Android 14)
Se un ricevitore BOOT_COMPLETED
tenta di avviare uno di questi tipi di oggetti in primo piano
automaticamente, il sistema genera 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 questo 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 将继续更新 Android 的核心库, 最新 OpenJDK LTS 版本中的功能。
其中一些变更可能会影响应用定位的应用兼容性 Android 15(API 级别 35):
字符串格式设置 API 变更:验证参数索引、标志、 现在,使用
String.format()
和Formatter.format()
API:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
例如,当参数索引为 0 时,会抛出以下异常 (格式字符串中的
%0
):IllegalFormatArgumentIndexException: Illegal format argument index = 0
在这种情况下,可以使用参数索引为 1 (
%1
)。对
Arrays.asList(...).toArray()
组件类型的更改:使用Arrays.asList(...).toArray()
,则所得数组的组件类型为 现在是Object
,而不是底层数组元素的类型。因此, 以下代码会抛出ClassCastException
:String[] elements = (String[]) Arrays.asList("one", "two").toArray();
在本例中,在结果中将
String
保留为组件类型 数组,您可以改用Collection.toArray(Object[])
:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
语言代码处理方式变更:使用
Locale
API 时, 不再转换希伯来语、意第绪语和印度尼西亚语的语言代码 对应的过时形式(希伯来语:iw
、意第绪语:ji
和印度尼西亚语:in
)。 在为其中某个语言区域指定语言代码时,请使用代码 改为 ISO 639-1(希伯来语:he
,意第绪语:yi
,印度尼西亚语:id
)。对随机整数序列的更改: https://bugs.openjdk.org/browse/JDK-8301574,下面
Random.ints()
方法现在返回的数值序列与Random.nextInt()
方法的用途如下:一般来说,此变更不会导致应用中断行为,但您的 代码不应期望
Random.ints()
方法生成的序列 匹配Random.nextInt()
。
新的 SequencedCollection
API 可能会影响应用的兼容性
当您在应用的 build 配置中更新 compileSdk
以使用
Android 15(API 级别 35):
与
MutableList.removeFirst()
和kotlin-stdlib
中的MutableList.removeLast()
扩展函数Java 中的
List
类型会映射到 Kotlin 中的MutableList
类型。 由于使用List.removeFirst()
和List.removeLast()
API 已在 Android 15(API 级别 35)中引入,Kotlin 编译器 将函数调用(例如list.removeFirst()
)静态解析为 新的List
API,而不是对 API 中的扩展函数kotlin-stdlib
。重新编译应用时,如果
compileSdk
设为35
,并且minSdk
设为34
或更低版本,那么应用会在 Android 14 及更低版本(运行时)上运行 错误:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
Android Gradle 插件中的现有
NewApi
lint 选项可以捕获这些 新的 API 用法。./gradlew lint
MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()如需修复运行时异常和 lint 错误,
removeFirst()
和removeLast()
函数调用可替换为removeAt(0)
,removeAt(list.lastIndex)
(在 Kotlin 中分别对应)。如果您使用的是 Android Studio Ladybug |2024.1.3 或更高版本,也提供快速修复 处理这些错误的选项如果 lint 选项已停用,请考虑移除
@SuppressLint("NewApi")
和lintOptions { disable 'NewApi' }
。与 Java 中的其他方法冲突
向现有类型中添加了新方法,例如,
List
和Deque
。这些新方法 其他接口中使用相同名称和参数类型的方法 和类。如果与 不兼容,javac
编译器会输出构建时错误。例如:错误 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错误 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错误 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要修复这些构建错误,实现这些接口的类应 使用兼容的返回值类型替换该方法。例如:
@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 da app dannose.
Lanci di attività in background protette
Android 15 protegge gli utenti da app dannose e offre loro un maggiore controllo i propri dispositivi aggiungendo modifiche che impediscano ad app in background dannose di mettere in primo piano altre app, aumentare i loro privilegi e abusare interazione dell'utente. I lanci di attività in background sono stati limitati dal giorno Android 10 (livello API 29).
Impedisci alle app che non corrispondono all'UID principale nell'impilare di avviare attività
Le app dannose possono avviare l'attività di un'altra app nell'ambito della stessa attività, quindi
sovrapposti, creando l'illusione di essere quell'app. Questa "attività
"compromissione" l'attacco aggira le attuali restrizioni di avvio in background perché
avviene all'interno della stessa attività visibile. Per ridurre questo rischio, Android 15 aggiunge un
un flag che impedisce l'avvio delle app che non corrispondono all'UID principale nello stack
attività. Per attivare tutte le attività delle app, aggiorna le
allowCrossUidActivitySwitchFromBelow
nel file AndroidManifest.xml
dell'app:
<application android:allowCrossUidActivitySwitchFromBelow="false" >
Le nuove misure di sicurezza sono attive se tutte le seguenti condizioni sono vere:
- L'app che esegue il lancio ha come target Android 15.
- L'app nella parte superiore dello stack di attività ha come target Android 15.
- Per qualsiasi attività visibile sono state attivate le nuove protezioni
Se le misure di sicurezza sono attive, le app potrebbero tornare alla schermata Home, anziché l'ultima app visibile, se completano la propria attività.
Altre modifiche
Oltre alla limitazione per la corrispondenza dell'UID, anche queste altre modifiche vengono inclusi:
- Cambia
PendingIntent
creator per bloccare i lanci di attività in background entro il giorno predefinita. In questo modo è possibile impedire alle app di creare accidentalmente unPendingIntent
che potrebbero essere utilizzati in modo illecito da malintenzionati. - Non mettere un'app in primo piano a meno che il mittente
PendingIntent
lo consente. Questa modifica ha lo scopo di impedire alle app dannose di utilizzare in modo illecito possibilità di avviare attività in background. Per impostazione predefinita, le app non sono possono portare lo stack di attività in primo piano a meno che l'autore non lo consenta privilegi di avvio attività in background o il mittente ha attività in background privilegi di avvio. - Controlla il modo in cui l'attività principale di uno stack di attività può completarne le attività. Se attività principale completa un'attività, Android torna all'attività precedente l'ultima attività. Inoltre, se un'attività non principale completa la propria attività, Android torna alla home page; non bloccherà la finitura di questa parte non superiore attività.
- Impedisci di avviare attività arbitrarie da altre app alla tua. un'attività. Questa modifica impedisce alle app dannose di applicare phishing agli utenti creando attività che sembrano provenire da altre app.
- Impedire che le finestre non visibili vengano prese in considerazione per l'attività in background Google Cloud. In questo modo è possibile evitare che app dannose utilizzino in modo illecito lo sfondo. viene avviata un'attività per mostrare agli utenti contenuti indesiderati o dannosi.
Intent più sicuri
Android 15 introduce nuove misure di sicurezza per rendere gli intent più sicuri e non solo robusto. Questi cambiamenti hanno lo scopo di prevenire potenziali vulnerabilità e uso improprio di intent che possono essere sfruttati da app dannose. Esistono due tipi principali miglioramenti alla sicurezza degli intent in Android 15:
- Associa i filtri per intent di destinazione: gli intent che hanno come target componenti specifici devono che corrispondano esattamente alle specifiche del filtro per intent del target. Se invii un per avviare l'attività di un'altra app, il componente intent deve sono in linea con i filtri per intent dichiarati dell'attività ricevente.
- Gli intent devono avere azioni:gli intent senza un'azione non corrisponderanno più i filtri di intent. Ciò significa che gli intent usati per avviare attività devono avere un'azione chiaramente definita.
- Intent in attesa: il creator dell'intent in sospeso è trattato come il mittente dell'intento di inclusione, non il mittente dell'intent in sospeso intenzione
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'esperienza utente più coerente e 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 perimetrale
Le app sono edge-to-edge per impostazione predefinita sui dispositivi con Android 15, se sono che hanno come target Android 15 (livello API 35).
![](https://developer.android.google.cn/static/about/versions/15/images/edge-to-edge-1.png?authuser=9&hl=it)
Si tratta di una modifica che provoca un errore che potrebbe influire negativamente sull'UI della tua app. La interessano le seguenti aree dell'interfaccia utente:
- Barra di navigazione con gestione dei gesti
- Trasparente per impostazione predefinita.
- L'offset inferiore è disattivato, quindi i contenuti vengono spostati dietro la navigazione del sistema barra, a meno che non vengano applicati inserti.
setNavigationBarColor
eR.attr#navigationBarColor
sono è deprecata e non influisce sulla navigazione tramite gesti.setNavigationBarContrastEnforced
eR.attr#navigationBarContrastEnforced
continuano a non avere alcun effetto navigazione tramite gesti.
- Navigazione con tre pulsanti
- Opacità impostata su 80% per impostazione predefinita, con un colore che potrebbe corrispondere alla finestra sfondo.
- Offset inferiore disattivato in modo che i contenuti vengano visualizzati dietro la barra di navigazione del sistema a meno che non vengano applicati inserti.
setNavigationBarColor
eR.attr#navigationBarColor
sono impostato in modo che corrisponda allo sfondo della finestra per impostazione predefinita. Lo sfondo della finestra deve essere un colore disegnabile per applicare questo valore predefinito. Questa API è è deprecata, ma continua a influire sulla navigazione con tre pulsanti.setNavigationBarContrastEnforced
e Per impostazione predefinita,R.attr#navigationBarContrastEnforced
è impostato su true e aggiunge un Sfondo opaco all'80% nella navigazione con tre pulsanti.
- Barra di stato
- Trasparente per impostazione predefinita.
- L'offset superiore è disattivato, quindi i contenuti vengono disegnati dietro la barra di stato a meno che i riquadri.
setStatusBarColor
eR.attr#statusBarColor
sono è deprecata e non ha alcun effetto su Android 15.setStatusBarContrastEnforced
e IR.attr#statusBarContrastEnforced
sono deprecati, ma hanno ancora un su Android 15.
- Staglio display
- Il
layoutInDisplayCutoutMode
di finestre non mobili deve essereLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
.SHORT_EDGES
,NEVER
eDEFAULT
vengono interpretati comeALWAYS
in modo che gli utenti non vedano un colore nero causata dal ritaglio display e appare edge-to-edge.
- Il
L'esempio seguente mostra un'app prima e dopo il targeting Android 15 (livello API 35) e prima e dopo l'applicazione dei riquadri.
![](https://developer.android.google.cn/static/about/versions/15/images/edge-to-edge-4.png?authuser=9&hl=it)
![](https://developer.android.google.cn/static/about/versions/15/images/edge-to-edge-6.png?authuser=9&hl=it)
![](https://developer.android.google.cn/static/about/versions/15/images/edge-to-edge-2.png?authuser=9&hl=it)
Cosa controllare se la tua app è già edge-to-edge
Se la tua app è già edge-to-edge e applica inserti, in gran parte non interessate, tranne che nei seguenti scenari. Tuttavia, anche se pensi non sei interessato, ti consigliamo di testare l'app.
- Hai una finestra non mobile, ad esempio una
Activity
che utilizzaSHORT_EDGES
,NEVER
oDEFAULT
invece diLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. Se l'app ha un arresto anomalo all'avvio, potrebbe essere dovuto alla schermata iniziale. Puoi eseguire l'upgrade delle dipendenza della schermata iniziale a 1.2.0-alpha01 o una data successiva oppure impostawindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
. - Potrebbero esserci schermate con traffico ridotto con UI nascosta. Verifica questi
gli schermi meno visitati non hanno un'interfaccia utente nascosta. Le schermate con traffico ridotto includono:
- Schermate di onboarding o di accesso
- Pagine Impostazioni
Cosa controllare se la tua app non è già edge-to-edge
Se la tua app non è già edge-to-edge, è molto probabile che il problema riguardi il tuo. Nella oltre agli scenari per le app già edge-to-edge, dovresti tieni in considerazione quanto segue:
- Se la tua app utilizza i componenti Material 3 (
androidx.compose.material3
) nella modalità di scrittura, ad esempioTopAppBar
,BottomAppBar
eNavigationBar
, è probabile che questi componenti non interessati perché gestiscono automaticamente gli inserti. - Se la tua app utilizza componenti Material 2 (
androidx.compose.material
) in Compose, questi componenti non gestiscono automaticamente gli inserti. Tuttavia, puoi accedere ai riquadri e applicarle manualmente. In androidx.compose.material 1.6.0 e in seguito, usa il parametrowindowInsets
per applicare manualmente i riquadriBottomAppBar
,TopAppBar
,BottomNavigation
eNavigationRail
. Allo stesso modo, utilizza il parametrocontentWindowInsets
perScaffold
- Se la tua app utilizza viste e componenti Material
(
com.google.android.material
), la maggior parte dei materiali basati sulle visualizzazioni Componenti comeBottomNavigationView
,BottomAppBar
,NavigationRailView
oNavigationView
, che gestiscono i riquadri e non richiedono lavoro aggiuntivo. Tuttavia, devi aggiungereandroid:fitsSystemWindows="true"
se utilizziAppBarLayout
. - Per gli elementi componibili personalizzati, applica i riquadri manualmente come spaziatura interna. Se le tue
i contenuti si trovano all'interno di un
Scaffold
, puoi utilizzare i riquadri utilizzando ilScaffold
valori di spaziatura interna. In caso contrario, applica la spaziatura interna utilizzando uno deiWindowInsets
- Se la tua app utilizza visualizzazioni e
BottomSheet
,SideSheet
o personalizzate dei container, applica la spaziatura internaViewCompat.setOnApplyWindowInsetsListener
PerRecyclerView
, applica la spaziatura interna utilizzando questo listener e aggiungi ancheclipToPadding="false"
.
Cosa controllare se l'app deve offrire una protezione in background personalizzata
Se la tua app deve offrire una protezione personalizzata in background per la navigazione con tre pulsanti oppure
la barra di stato, devi posizionare una visualizzazione componibile o dietro la barra di sistema
utilizzando WindowInsets.Type#tappableElement()
per ottenere i tre pulsanti
altezza della barra di navigazione o WindowInsets.Type#statusBars
.
Risorse edge-to-edge aggiuntive
Vedi le sezioni Visualizzazioni edge to Edge e Scrittura Edge to Edge guide per ulteriori considerazioni sull'applicazione dei riquadri.
API deprecate
Le seguenti API sono state ritirate:
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#isStatusBarContrastEnforced
Window#setDecorFitsSystemWindows
Window#setNavigationBarColor
Window#setNavigationBarDividerColor
Window#setStatusBarColor
Window#setStatusBarContrastEnforced
Configurazione stabile
Se la tua app ha come target Android 15 (livello API 35) o versioni successive, Configuration
non
escludendo più le barre di sistema. Se utilizzi le dimensioni dello schermo
Classe Configuration
per il calcolo del layout, devi sostituirla con una migliore
alternative come ViewGroup
, WindowInsets
WindowMetricsCalculator
a seconda delle tue esigenze.
Configuration
è disponibile a partire dall'API 1. In genere viene ottenuto
Activity.onConfigurationChanged
. Fornisce informazioni come la densità della finestra,
orientamento e dimensioni. Una caratteristica importante delle dimensioni delle finestre
restituito da Configuration
significa che in precedenza le barre di sistema sono state escluse.
Le dimensioni della configurazione vengono in genere utilizzate per la selezione delle risorse, ad esempio
/res/layout-h500dp
e questo è ancora un caso d'uso valido. Tuttavia, utilizzarlo per
il calcolo del layout è sempre stato sconsigliato. In questo caso, devi spostare
lontano da lì. Devi sostituire l'utilizzo di Configuration
con qualcosa
più adatti a seconda del caso d'uso.
Se lo utilizzi per calcolare il layout, usa un valore ViewGroup
appropriato, come
CoordinatorLayout
o ConstraintLayout
. Se la utilizzi per determinare l'altezza
della barra di navigazione del sistema, utilizza WindowInsets
. Se vuoi conoscere la dimensione attuale
della finestra dell'app, usa computeCurrentWindowMetrics
.
Di seguito sono elencati i campi interessati da questa modifica:
- Le dimensioni
Configuration.screenWidthDp
escreenHeightDp
non sono più disponibili escludi le barre di sistema. Configuration.smallestScreenWidthDp
è interessata indirettamente dalle modifiche ascreenWidthDp
escreenHeightDp
.Configuration.orientation
è interessata indirettamente dalle modifiche allescreenWidthDp
escreenHeightDp
su dispositivi simili al quadrato.Display.getSize(Point)
è indirettamente interessata dalle modifiche inConfiguration
. Questa funzionalità è stata ritirata a partire dal livello API 30.Display.getMetrics()
ha già funzionato in questo modo dal livello API 33.
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
.
![](https://developer.android.google.cn/static/about/versions/15/images/elegant-text-height-before.png?authuser=9&hl=it)
elegantTextHeight
per le app che hanno come target Android 14 (livello API 34) e versioni precedenti.![](https://developer.android.google.cn/static/about/versions/15/images/elegant-text-height-after.png?authuser=9&hl=it)
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 o versioni successive. Puoi
abilita o disabilita questo comportamento chiamando l'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.
![](https://developer.android.google.cn/static/about/versions/15/images/cursive-clipped.png?authuser=9&hl=it)
<TextView android:fontFamily="cursive" android:text="java" />
![](https://developer.android.google.cn/static/about/versions/15/images/cursive-noclipping.png?authuser=9&hl=it)
<TextView android:fontFamily="cursive" android:text="java" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
![](https://developer.android.google.cn/static/about/versions/15/images/thai-clipped.png?authuser=9&hl=it)
<TextView android:text="คอมพิวเตอร์" />
![](https://developer.android.google.cn/static/about/versions/15/images/thai-noclipping.png?authuser=9&hl=it)
<TextView android:text="คอมพิวเตอร์" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
Altezza della riga predefinita sensibile alle impostazioni internazionali per EditText
在以前的 Android 版本中,文本布局拉伸了文本的高度,使其适应与当前语言区域匹配的字体的行高。例如,如果内容是日语,由于日语字体的行高比拉丁字体的行高略大,因此文本的高度就略大了。不过,尽管行高存在这些差异,但无论使用何种语言区域,EditText
元素的大小都是一致的,如下图所示:
![](https://developer.android.google.cn/static/about/versions/15/images/locale-aware-line-height-before.png?authuser=9&hl=it)
EditText
元素的框,这些框可以包含英语 (en)、日语 (ja) 和缅甸语 (my) 的文本。EditText
的高度相同,即使这两种语言的行高不同。对于以 Android 15 为目标平台的应用,系统现在会为 EditText
预留最小行高,以匹配指定语言区域的参考字体,如下图所示:
![](https://developer.android.google.cn/static/about/versions/15/images/locale-aware-line-height-after.png?authuser=9&hl=it)
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 destinate ad 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 hai la certezza che la tua app utilizzi interfacce non SDK, puoi testa la tua app per scoprirlo. Se la tua app si basa su modelli non SDK dovresti iniziare a pianificare una migrazione alle alternative SDK. Tuttavia, sappiamo che alcune app hanno casi d'uso validi per l'utilizzo 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.