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
Stiamo apportando le seguenti modifiche ai servizi in primo piano con Android 15.
- Nuovo tipo di servizio in primo piano di elaborazione di contenuti multimediali
- Limitazioni sui ricevitori di trasmissione
BOOT_COMPLETED
che avviano servizi in primo piano
Comportamento di timeout del servizio in primo piano di sincronizzazione dei dati
Android 15 introduce un nuovo comportamento di timeout per dataSync
per le app destinate ad Android 15 o versioni successive. Questo comportamento si applica anche al nuovo tipo di servizio in primo piano mediaProcessing
.
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 il metodo Service.onTimeout(int, int)
del servizio in esecuzione (introdotto in Android 15). Al momento, il servizio ha alcuni secondi per chiamare
Service.stopSelf()
. Quando viene chiamato Service.onTimeout()
, il servizio non è più considerato un servizio in primo piano. Se il servizio non chiama Service.stopSelf()
, si verificherà un errore con il seguente messaggio di errore: "Un servizio in primo piano di <fgs_type> non è stato interrotto entro il suo timeout: <component_name>". Nella versione beta 2, il messaggio di errore viene mostrato come errore ANR, ma in una release beta futura questo messaggio di errore genererà un'eccezione personalizzata.
Per evitare problemi con questa modifica del comportamento, puoi eseguire una o più delle seguenti operazioni:
- Fai in modo che il servizio implementi il nuovo metodo
Service.onTimeout(int, int)
. Quando la tua app riceve il callback, assicurati di chiamarestopSelf()
entro pochi secondi. Se non interrompi subito l'app, il sistema genera un guasto. - Assicurati che i servizi
dataSync
della tua app non vengano eseguiti per più di 6 ore totali in 24 ore (a meno che l'utente non interagisca con l'app reimpostando il timer). - Avvia
dataSync
servizi in primo piano solo a seguito di un'interazione diretta dell'utente; poiché la tua app è in primo piano all'avvio del servizio, quest'ultimo ha tutte le sei ore dopo che l'app è passata in background. - Anziché utilizzare un servizio in primo piano
dataSync
, usa un'API alternativa.
Se i servizi in primo piano dataSync
della tua app sono stati eseguiti per 6 ore negli ultimi 24, non puoi avviare un altro servizio in primo piano dataSync
a meno che l'utente non abbia messo in primo piano la tua app (operazione che reimposta il timer). Se provi ad avviare un altro servizio in primo piano dataSync
, il sistema genera ForegroundServiceStartNotAllowedException
con un messaggio di errore come "Limite di tempo già esaurito per dataSync del tipo di servizio in primo piano".
Nuovo tipo di servizio in primo piano di elaborazione di contenuti multimediali
Android 15 introduce un nuovo tipo di servizio in primo piano, mediaProcessing
. Questo tipo di servizio è appropriato per operazioni come la transcodifica di file multimediali. Ad esempio, un'app multimediale potrebbe scaricare un file audio e dover convertirlo in un formato diverso prima di riprodurlo. Puoi utilizzare un servizio mediaProcessing
in primo piano per assicurarti che la conversione prosegua anche mentre l'app è in background.
Il sistema consente l'esecuzione dei servizi mediaProcessing
di un'app per un totale di 6 ore in un periodo di 24 ore, dopodiché il sistema chiama il metodo Service.onTimeout(int, int)
del servizio in esecuzione (introdotto in Android 15). Al momento, il servizio ha alcuni secondi per chiamare
Service.stopSelf()
. Se il servizio non chiama Service.stopSelf()
, si verificherà un errore con il messaggio: "Un servizio in primo piano di <fgs_type> non è stato interrotto entro il suo timeout: <component_name>". Nella versione beta 2, il messaggio di errore viene mostrato come errore ANR, ma in una release beta futura questo messaggio di errore genererà un'eccezione personalizzata.
Per evitare di ricevere un errore ANR, puoi eseguire una delle seguenti operazioni:
- Fai in modo che il servizio implementi il nuovo metodo
Service.onTimeout(int, int)
. Quando la tua app riceve il callback, assicurati di chiamarestopSelf()
entro pochi secondi. Se non interrompi subito l'app, il sistema genera un guasto. - Assicurati che i servizi
mediaProcessing
della tua app non vengano eseguiti per più di 6 ore totali in 24 ore (a meno che l'utente non interagisca con l'app reimpostando il timer). - Avvia
mediaProcessing
servizi in primo piano solo a seguito di un'interazione diretta dell'utente; poiché la tua app è in primo piano all'avvio del servizio, quest'ultimo ha tutte le sei ore dopo che l'app è passata in background. - Anziché utilizzare un servizio in primo piano
mediaProcessing
, usa un'API alternativa, come WorkManager.
Se i servizi in primo piano mediaProcessing
della tua app sono stati eseguiti per 6 ore negli ultimi 24, non puoi avviare un altro servizio in primo piano mediaProcessing
a meno che l'utente non abbia messo in primo piano la tua app (operazione che reimposta il timer). Se
provi ad avviare un altro servizio in primo piano mediaProcessing
, il sistema genera
ForegroundServiceStartNotAllowedException
con un messaggio di errore come "Limite di tempo già esaurito per il tipo di servizio in primo piano mediaProcess".
Per ulteriori informazioni sul tipo di servizio mediaProcessing
, consulta Modifiche ai tipi di servizi in primo piano per Android 15: elaborazione di contenuti multimediali.
Limitazioni sui ricevitori di trasmissioni BOOT_COMPLETED
che avviano servizi in primo piano
Sono state applicate nuove limitazioni ai ricevitori di trasmissione BOOT_COMPLETED
che lanciano
servizi in primo piano. I ricevitori BOOT_COMPLETED
non sono autorizzati ad avviare i seguenti tipi di servizi in primo piano:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(questa limitazione è in vigore permicrophone
da Android 14)
Se un ricevitore BOOT_COMPLETED
tenta di avviare uno di questi tipi di servizi in primo piano, il sistema genera ForegroundServiceStartNotAllowedException
.
Limitazioni relative all'avvio di servizi in primo piano quando un'app conserva l'autorizzazione SYSTEM_ALERT_WINDOW
In precedenza, se un'app aveva l'autorizzazione SYSTEM_ALERT_WINDOW
, poteva avviare un servizio in primo piano anche se l'app era attualmente in background (come spiegato nelle 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 avere l'autorizzazione SYSTEM_ALERT_WINDOW
e anche avere una finestra overlay visibile. In altre parole, l'app deve avviare una finestra TYPE_APPLICATION_OVERLAY
e la 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 soddisfare questi nuovi requisiti (e non ha altre esenzione), il sistema genera ForegroundServiceStartNotAllowedException
.
Se la tua app dichiara l'autorizzazione SYSTEM_ALERT_WINDOW
e avvia i servizi in primo piano in background, questa modifica potrebbe essere interessata. Se la tua app riceve un ForegroundServiceStartNotAllowedException
, controlla l'ordine delle operazioni dell'app e assicurati che abbia già una finestra di overlay attiva prima che provi ad avviare un servizio in primo piano in background. Puoi verificare se la finestra dell'overlay è attualmente visibile
chiamando il numero View.getWindowVisibility()
oppure
eseguire l'override di View.onWindowVisibilityChanged()
per ricevere una notifica ogni volta che la visibilità cambia.
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 a OpenJDK 17
Android 15 continua il lavoro di aggiornamento delle librerie di base di Android per allinearsi alle funzionalità delle ultime release di OpenJDK LTS.
Una di queste modifiche potrebbe incidere sulla compatibilità delle app destinate ad Android 15:
Modifiche alle API di formattazione delle stringhe: la convalida di indice, flag, larghezza e precisione degli argomenti è ora più rigorosa quando si utilizzano le seguenti API
String.format()
eFormatter.format()
:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
Ad esempio, viene generata la seguente eccezione quando viene utilizzato un indice di argomento pari a 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
Arrays.asList(...).toArray()
: quando utilizziArrays.asList(...).toArray()
, il tipo di componente dell'array risultante è ora unObject
, non il tipo degli elementi dell'array sottostante. Di conseguenza, il seguente codice genera un erroreClassCastException
:String[] elements = (String[]) Arrays.asList("one", "two").toArray();
In questo caso, per conservare
String
come tipo di componente nell'array risultante, puoi utilizzare inveceCollection.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 di ebraico, yiddish e indonesiano non vengono più convertiti nelle forme obsolete (ebraico:iw
, yiddish:ji
e indonesiano:in
). Quando specifichi il codice lingua per una di queste impostazioni internazionali, utilizza invece i codici da ISO 639-1 (ebraico:he
, Yiddish e indonesiano:yi
/indonesiano).id
Modifiche alle sequenze di numeri interi casuali: dopo le modifiche apportate in https://bugs.openjdk.org/Sfoglia/JDK-8301574, i seguenti metodi
Random.ints()
restituiscono ora una sequenza di numeri diversa rispetto ai metodiRandom.nextInt()
:In genere, questa modifica non dovrebbe comportare comportamenti in grado di interrompere l'app, ma il tuo codice non dovrebbe aspettarsi che la sequenza generata dai metodi
Random.ints()
corrisponda aRandom.nextInt()
.
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 dalle app dannose e offre loro un maggiore controllo sui loro dispositivi aggiungendo modifiche che impediscono alle app dannose in background di portare altre app in primo piano, elevando i loro privilegi e abusando dell'interazione dell'utente. I lanci delle attività in background sono stati limitati a partire da Android 10 (livello API 29).
Impedisci alle app che non corrispondono all'UID principale dello stack di avviare attività
Le app dannose possono avviare l'attività di un'altra app nell'ambito della stessa attività per poi sovrapporsi alla parte superiore, creando l'illusione di essere quell'app. Questo attacco di "dirottamento dell'attività" bypassa le attuali limitazioni di avvio in background perché tutto avviene all'interno della stessa attività visibile. Per ridurre questo rischio, Android 15 aggiunge un flag che impedisce alle app che non corrispondono all'UID principale dello stack di avviare le attività. Per attivare tutte le attività della tua app, aggiorna l'attributo allowCrossUidActivitySwitchFromBelow
nel file AndroidManifest.xml
dell'app:
<application android:allowCrossUidActivitySwitchFromBelow="false" >
Le nuove misure di sicurezza sono attive se si verificano tutte le seguenti condizioni:
- L'app che esegue il lancio ha come target Android 15.
- L'app in cima allo stack di attività ha come target Android 15.
- Le nuove protezioni sono state attivate per tutte le attività visibili
Se le misure di sicurezza sono attivate, le app potrebbero tornare alla schermata Home anziché all'ultima app visibile, se completano la propria attività.
Altre modifiche
Oltre alla limitazione per la corrispondenza UID, sono incluse anche queste altre modifiche:
- Modifica
PendingIntent
creator in modo da bloccare il lancio delle attività in background per impostazione predefinita. Ciò contribuisce a impedire che le app creino accidentalmente unPendingIntent
che potrebbe essere utilizzato in modo illecito da malintenzionati. - Non portare un'app in primo piano a meno che il mittente
PendingIntent
non lo consenta. Questa modifica ha lo scopo di impedire ad app dannose di abusare della capacità di avviare attività in background. Per impostazione predefinita, alle app non è consentito portare in primo piano lo stack di attività, a meno che l'autore non autorizzi i privilegi di avvio per le attività in background o il mittente non disponga di privilegi di avvio per attività in background. - Controlla in che modo l'attività principale di una serie di attività può completarne l'attività. Se l'attività principale termina un'attività, Android torna all'attività più recente. Inoltre, se un'attività non principale completa la sua attività, Android torna alla schermata Home senza bloccare il completamento di questa attività non principale.
- Impedisci di avviare attività arbitrarie da altre app nella tua attività. Questa modifica impedisce che le app dannose finiscano di phishing per gli utenti creando attività che sembrano provenire da altre app.
- Impedisci che le finestre non visibili vengano prese in considerazione per l'avvio di attività in background. in modo da impedire che app dannose usino in modo illecito gli avvii delle attività in background 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 solidi. Lo scopo di queste modifiche è prevenire le potenziali vulnerabilità e l'uso improprio di intent che possono essere sfruttati da app dannose. Ci sono due miglioramenti principali alla sicurezza degli intent in Android 15:
- Associa i filtri per intent del target: gli intent che hanno come target componenti specifici devono corrispondere con precisione alle specifiche del filtro per intent del target. Se invii un intent per avviare l'attività di un'altra app, il componente per intent di destinazione deve essere in linea con i filtri per intent dichiarati dell'attività ricevente.
- Gli intent devono avere azioni: gli intent senza un'azione non corrisponderanno più ai filtri per intent. Ciò significa che gli intent utilizzati per avviare attività o servizi devono avere un'azione chiaramente definita.
- Intent in attesa: il creator dell'intent in sospeso viene trattato come il mittente dell'intent che include, non il mittente dell'intent in sospeso
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
Per impostazione predefinita, le app sono edge-to-edge sui dispositivi con Android 15 se hanno come target Android 15 (livello API 35).
Si tratta di una modifica che provoca un errore che potrebbe influire negativamente sull'UI della tua app. Le modifiche interessano le seguenti aree della UI:
- Barra di navigazione della gestione dei gesti
- Trasparente per impostazione predefinita.
- L'offset inferiore è disattivato, quindi i contenuti vengono disegnati dietro la barra di navigazione del sistema, a meno che non vengano applicati riquadri.
setNavigationBarColor
eR.attr#navigationBarColor
sono deprecati e non influiscono sulla navigazione tramite gesti.setNavigationBarContrastEnforced
eR.attr#navigationBarContrastEnforced
continuano a non avere alcun effetto sulla navigazione tramite gesti.
- Navigazione con tre pulsanti
- L'opacità è impostata sull'80% per impostazione predefinita, con un colore che potrebbe corrispondere allo sfondo della finestra.
- Offset inferiore disattivato, in modo che i contenuti vengano visualizzati dietro la barra di navigazione del sistema, a meno che non vengano applicati riquadri.
setNavigationBarColor
eR.attr#navigationBarColor
sono impostati per impostazione predefinita in modo che corrispondano allo sfondo della finestra. Per applicare questo valore predefinito, lo sfondo della finestra deve essere di un colore disegnabile. Questa API è stata ritirata, ma continua a influire sulla navigazione con tre pulsanti.- I campi
setNavigationBarContrastEnforced
eR.attr#navigationBarContrastEnforced
sono impostati su true per impostazione predefinita e aggiungono uno sfondo opaco dell'80% alla 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 non vengano applicati inserti.
setStatusBarColor
eR.attr#statusBarColor
sono deprecati e non hanno alcun effetto su Android 15.setStatusBarContrastEnforced
eR.attr#statusBarContrastEnforced
sono deprecati, ma hanno comunque un effetto su Android 15.
- Staglio display
- Il
layoutInDisplayCutoutMode
delle finestre non mobili deve essereLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
.SHORT_EDGES
,NEVER
eDEFAULT
sono interpretati comeALWAYS
in modo che gli utenti non vedano una barra nera causata dal ritaglio display e non siano visibili da un bordo all'altro.
- Il
L'esempio seguente mostra un'app prima e dopo aver scelto come target Android 15 (livello API 35) e prima e dopo l'applicazione dei riquadri.
Cosa controllare se la tua app è già edge-to-edge
Se la tua app è già edge-to-edge e applica i riquadri, nella maggior parte dei casi non hai impatto, ad eccezione dei seguenti scenari. Tuttavia, anche se pensi che non ci siano conseguenze per te, ti consigliamo di testare la tua app.
- Hai una finestra non mobile, ad esempio
Activity
che utilizzaSHORT_EDGES
,NEVER
oDEFAULT
anzichéLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
. Se l'app ha un arresto anomalo al momento del lancio, è possibile che la causa sia la schermata iniziale. Puoi eseguire l'upgrade della dipendenza della schermata iniziale principale a 1.2.0-alpha01 o una versione successiva oppure impostarewindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
. - Potrebbero esserci schermate con traffico ridotto con UI nascosta. Verifica che queste schermate meno visitate non abbiano 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. Oltre agli scenari per le app già edge-to-edge, devi considerare quanto segue:
- Se la tua app utilizza componenti Material 3 (
androidx.compose.material3
) in modalità di scrittura, ad esempioTopAppBar
,BottomAppBar
eNavigationBar
, è probabile che questi componenti non siano interessati perché gestiscono automaticamente i riquadri. - Se la tua app utilizza componenti Material 2 (
androidx.compose.material
) in Compose, questi componenti non gestiscono automaticamente i riquadri. Tuttavia, puoi accedere ai riquadri e applicarli manualmente. In androidx.compose.material 1.6.0 e versioni successive, utilizza il parametrowindowInsets
per applicare manualmente i riquadri perBottomAppBar
,TopAppBar
,BottomNavigation
eNavigationRail
. In modo simile, utilizza il parametrocontentWindowInsets
perScaffold
. - Se la tua app utilizza viste e componenti
materiali (
com.google.android.material
), la maggior parte dei componenti materiali basati sulle visualizzazioni, comeBottomNavigationView
,BottomAppBar
,NavigationRailView
oNavigationView
, gestisce i riquadri e non richiede lavori aggiuntivi. Tuttavia, devi aggiungereandroid:fitsSystemWindows="true"
se utilizziAppBarLayout
. - Per gli elementi componibili personalizzati, applica i riquadri manualmente come spaziatura interna. Se i contenuti si trovano all'interno di un elemento
Scaffold
, puoi utilizzare i riquadri utilizzando i valori di spaziatura interna diScaffold
. In caso contrario, applica la spaziatura interna utilizzando una delleWindowInsets
. - Se la tua app utilizza viste e
BottomSheet
,SideSheet
o contenitori personalizzati, applica la spaziatura interna utilizzandoViewCompat.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 dello sfondo personalizzata per la navigazione con tre pulsanti o
la barra di stato, l'app deve posizionare una visualizzazione componibile o dietro la barra di sistema
utilizzando WindowInsets.Type#tappableElement()
per ottenere l'altezza
della barra di navigazione con tre pulsanti o
WindowInsets.Type#statusBars
.
Risorse edge-to-edge aggiuntive
Consulta le guide Vista Edge to Edge e Scrittura Edge to Edge 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 o versioni successive, Configuration
non esclude più le barre di sistema. Se utilizzi le dimensioni dello schermo nella classe Configuration
per il calcolo del layout, devi sostituirle con alternative migliori, come ViewGroup
, WindowInsets
o WindowMetricsCalculator
appropriate, a seconda delle tue esigenze.
Configuration
è disponibile dall'API 1. In genere viene ottenuto da
Activity.onConfigurationChanged
. Fornisce informazioni come densità,
orientamento e dimensioni delle finestre. Una caratteristica importante delle dimensioni delle finestre
restituite da Configuration
è che in precedenza le barre di sistema sono state escluse.
La dimensione della configurazione viene in genere utilizzata per la selezione delle risorse, ad esempio /res/layout-h500dp
, e questo è ancora un caso d'uso valido. Tuttavia, è sempre stato sconsigliato
utilizzare l'IA per il calcolo del layout. Se lo fai, dovresti
abbandonarlo ora. Dovresti sostituire l'utilizzo di Configuration
con qualcosa
più adatto al tuo caso d'uso.
Se lo usi per calcolare il layout, usa un valore ViewGroup
appropriato, come CoordinatorLayout
o ConstraintLayout
. Se lo utilizzi per determinare l'altezza
della barra di navigazione del sistema, usa WindowInsets
. Se vuoi conoscere le dimensioni attuali
della finestra dell'app, usa computeCurrentWindowMetrics
.
Nell'elenco che segue sono descritti i campi interessati da questa modifica:
- Le dimensioni
Configuration.screenWidthDp
escreenHeightDp
non escludono più le barre di sistema. - L'app
Configuration.smallestScreenWidthDp
è indirettamente interessata dalle modifiche ascreenWidthDp
escreenHeightDp
. - L'app
Configuration.orientation
è indirettamente interessata dalle modifiche apportate ascreenWidthDp
escreenHeightDp
sui dispositivi vicini a quadrati. - L'attività
Display.getSize(Point)
è indirettamente interessata dalle modifiche apportate aConfiguration
. Questa funzionalità è stata ritirata a partire dal livello API 30. Display.getMetrics()
funziona già 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
.
Cambia la larghezza di TextView per forme di lettere complesse
Nelle versioni precedenti di Android, alcuni caratteri corsivi o alcune lingue con una modellazione complessa potrebbero tracciare le lettere nell'area del carattere precedente o successivo.
In alcuni casi, tali lettere venivano tagliate nella posizione iniziale o finale.
A partire da Android 15, un elemento TextView
alloca la larghezza per ricavare spazio sufficiente per queste lettere e consente alle app di richiedere spaziatura interna extra a sinistra per evitare il ritaglio.
Poiché questa modifica influisce sul modo in cui un elemento TextView
decide la larghezza, TextView
assegna una maggiore larghezza per impostazione predefinita se l'app ha come target Android 15 o versioni successive. Puoi
abilitare o disabilitare questo comportamento chiamando l'API setUseBoundsForWidth
su
TextView
.
Poiché l'aggiunta di 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 ulteriore spaziatura interna per evitare il ritaglio chiamando
setShiftDrawingOffsetForStartOverhang
.
I seguenti esempi mostrano come queste modifiche possono migliorare il layout del testo per alcuni caratteri e lingue.
Altezza della riga predefinita sensibile alle impostazioni internazionali per EditText
Nelle versioni precedenti di Android, il layout del testo estendeva l'altezza del testo per adattarlo all'altezza della riga del carattere corrispondente alle impostazioni internazionali correnti. Ad esempio, se i contenuti erano in giapponese, poiché l'altezza della riga del carattere giapponese è leggermente più grande di quella di un carattere latino, l'altezza del testo è aumentata leggermente. Tuttavia, nonostante queste differenze di altezza delle righe, le dimensioni dell'elemento EditText
sono state uniformi, indipendentemente dall'impostazione internazionale utilizzata, come illustrato nell'immagine seguente:
Per le app che hanno come target Android 15, ora viene riservata un'altezza minima della riga per EditText
affinché corrisponda al carattere di riferimento per le impostazioni internazionali specificate, come mostrato nella seguente immagine:
Se necessario, la tua app può ripristinare il comportamento precedente specificando l'attributo useLocalePreferredLineHeightForMinimum
su false
e la tua app può impostare metriche verticali minime personalizzate utilizzando l'API setMinimumFontMetrics
in Kotlin e Java.
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 l'app principale o eseguire un servizio in primo piano relativo all'audio per 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
.
Un servizio in primo piano è considerato correlato all'audio se il tipo è mediaPlayback
, camera
, microphone
o phoneCall
.
Per scoprire di più sul focus audio, consulta Gestire il focus audio.
Limitazioni non SDK aggiornate
Android 15 include elenchi aggiornati di interfacce non SDK limitate in base alla collaborazione con gli sviluppatori Android e ai test interni più recenti. Quando possibile, ci assicuriamo che siano disponibili alternative pubbliche prima di limitare le interfacce non SDK.
Se la tua app non è destinata ad Android 15, alcune di queste modifiche potrebbero non essere applicate immediatamente. Tuttavia, sebbene sia possibile per la tua app accedere ad alcune interfacce non SDK a seconda del livello API target dell'app, l'utilizzo di metodi o campi non SDK comporta sempre un rischio elevato di danneggiare la tua app.
Se non hai la certezza che la tua app utilizzi interfacce non SDK, puoi testare l'app per scoprirlo. Se la tua app si basa su interfacce non SDK, devi iniziare a pianificare una migrazione alle alternative SDK. Ciononostante, 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 un'interfaccia non SDK per una funzionalità nella tua 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.