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

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.

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:

  1. Fai in modo che il servizio implementi il nuovo metodo Service.onTimeout(int, int). Quando la tua app riceve il callback, assicurati di chiamare stopSelf() entro pochi secondi. Se non interrompi subito l'app, il sistema genera un guasto.
  2. 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).
  3. 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.
  4. 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 deve convertirlo in un formato diverso prima di riprodurlo. Puoi utilizzare un servizio in primo piano mediaProcessing per assicurarti che la conversione continui 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 di tempo per chiamare Service.stopSelf(). Se il servizio non chiama Service.stopSelf(), il sistema genera un'eccezione interna. L'eccezione 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 riceve la richiamata, assicurati di chiamare il numero stopSelf() entro pochi secondi. Se non interrompi subito l'app, il sistema genera un errore.
  2. Assicurati che i servizi mediaProcessing dell'app non vengano eseguiti per 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 a seguito dell'interazione diretta dell'utente. Poiché la tua app è in primo piano all'avvio del servizio, il tuo servizio ha a disposizione tutte le sei ore dopo il passaggio dell'app in background.
  4. Anziché utilizzare un servizio in primo piano mediaProcessing, utilizza 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 portato la tua app in primo piano (operazione che reimposta il timer). Se provi ad avviare un altro servizio in primo piano mediaProcessing, il sistema visualizza ForegroundServiceStartNotAllowedException con un messaggio di errore simile a "Il limite di tempo è già esaurito per il tipo di servizio in primo piano mediaProcessing".

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

Test

Per testare il comportamento della tua app, puoi attivare i timeout dell'elaborazione dei contenuti multimediali anche se l'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 modificare il periodo di timeout per testare più facilmente il comportamento della tua app quando viene raggiunto il limite. Per impostare un nuovo periodo di timeout, esegui questo comando adb:

adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds

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:

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 principali di Android per allineare con le funzionalità delle ultime release di OpenJDK LTS.

Una di queste modifiche può incidere 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().

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 un PendingIntent 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

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).

Un'app che ha come target Android 14 e non è edge-to-edge su un Dispositivo Android 15.


Un'app che ha come target Android 15 (livello API 35) ed è edge-to-edge su un dispositivo Android 15. Questa app utilizza principalmente i componenti Compose Material 3 che applicano automaticamente i riquadri. Questa schermata non è influenzata negativamente dal Applicazione edge-to-edge di Android 15.

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 e R.attr#navigationBarColor sono è deprecata e non influisce sulla navigazione tramite gesti.
    • setNavigationBarContrastEnforced e R.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 e R.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 e R.attr#statusBarColor sono è deprecata e non ha alcun effetto su Android 15.
    • setStatusBarContrastEnforced e I R.attr#statusBarContrastEnforced sono deprecati, ma hanno ancora un su Android 15.
  • Staglio display
      .
    • Il layoutInDisplayCutoutMode di finestre non mobili deve essere LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS. SHORT_EDGES, NEVER e DEFAULT vengono interpretati come ALWAYS in modo che gli utenti non vedano un colore nero causata dal ritaglio display e appare edge-to-edge.

L'esempio seguente mostra un'app prima e dopo il targeting Android 15 (livello API 35) e prima e dopo l'applicazione dei riquadri.

Un'app che ha come target Android 14 e non è edge-to-edge su un Dispositivo Android 15.
Un'app che ha come target Android 15 (livello API 35) ed è edge-to-edge su un dispositivo Android 15. Tuttavia, molti elementi sono ora nascosti dallo stato barra, barra di navigazione con tre pulsanti o ritaglio display a causa di Android 15 delle applicazioni edge-to-edge. L'UI nascosta include Material 2 barra delle app in alto, pulsanti di azione fluttuanti ed elementi dell'elenco.
Un'app che ha come target Android 15 (livello API 35) è edge-to-edge un dispositivo Android 15 e applica i riquadri in modo che l'UI nascosti.
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 utilizza SHORT_EDGES, NEVER o DEFAULT invece di LAYOUT_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 imposta window.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. Nel 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 esempio TopAppBar, BottomAppBar e NavigationBar, è 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 parametro windowInsets per applicare manualmente i riquadri BottomAppBar, TopAppBar, BottomNavigation e NavigationRail. Allo stesso modo, utilizza il parametro contentWindowInsets per Scaffold.
  • Se la tua app utilizza viste e componenti Material (com.google.android.material), la maggior parte dei materiali basati sulle visualizzazioni Componenti come BottomNavigationView, BottomAppBar, NavigationRailView o NavigationView, che gestiscono i riquadri e non richiedono lavoro aggiuntivo. Tuttavia, devi aggiungere android:fitsSystemWindows="true" se utilizzi AppBarLayout.
  • 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 il Scaffold valori di spaziatura interna. In caso contrario, applica la spaziatura interna utilizzando uno dei WindowInsets.
  • Se la tua app utilizza visualizzazioni e BottomSheet, SideSheet o personalizzate dei container, applica la spaziatura interna ViewCompat.setOnApplyWindowInsetsListener. Per RecyclerView, applica la spaziatura interna utilizzando questo listener e aggiungi anche clipToPadding="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:

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:

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 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.

Layout standard per il testo in inglese in corsivo. Alcune lettere sono troncate. Ecco il codice XML corrispondente:

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

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

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

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

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:

Tre riquadri che rappresentano gli elementi EditText che possono contenere testo in inglese (en), giapponese (ja) e birmano (my). L'altezza dell'elemento EditText è la stessa, anche se queste lingue hanno righe di altezza diverse l'una dall'altra.

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:

Tre riquadri che rappresentano gli elementi EditText che possono contenere testo in inglese (en), giapponese (ja) e birmano (my). L'altezza di EditText ora include lo spazio per adattarsi all'altezza della riga predefinita per i caratteri di queste lingue.

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 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.