Supporto di più finestre

La modalità multi-finestra consente a più app di condividere lo stesso schermo contemporaneamente. Le app possono essere affiancate o una sopra l'altra (modalità schermo diviso), un'app in una piccola finestra sovrapposta ad altre app (modalità Picture in picture) o singole app in finestre ridimensionabili e rimovibili separate (modalità in formato libero).

Figura 1. Visualizza due app affiancate in modalità schermo diviso.

L'esperienza utente dipende dalla versione del sistema operativo Android e dal tipo di dispositivo:

  • Android 7.0 (livello API 24) introduce la modalità schermo diviso sui dispositivi con schermo piccolo e la modalità Picture in picture su alcuni dispositivi.

    La modalità schermo diviso riempie lo schermo con due app, che le mostrano affiancate o una sopra l'altra. Gli utenti possono trascinare il divisore che separa le due app per ingrandire una e ridurre l'altra.

    La modalità Picture in picture consente agli utenti di continuare la riproduzione dei video durante l'interazione con un'altra app (consulta la sezione Supporto della funzionalità Picture in picture).

    I produttori di dispositivi con schermi di grandi dimensioni possono attivare la modalità in formato libero, in cui gli utenti possono ridimensionare liberamente ogni attività.

    Puoi configurare il modo in cui l'app gestisce la modalità multi-finestra specificando le dimensioni minime consentite dell'attività. Puoi anche disattivare la modalità multi-finestra per l'app impostando resizeableActivity="false" per assicurarti che il sistema mostri sempre l'app a schermo intero.

  • Android 8.0 (livello API 26) estende la modalità Picture in picture ai dispositivi con schermo piccolo.
  • Android 12 (livello API 31) applica il comportamento standard in modalità multi-finestra.

    Su schermi di grandi dimensioni (sw >= 600 dp), la piattaforma supporta tutte le app in modalità multi-finestra, indipendentemente dalla loro configurazione. Se resizeableActivity="false", l'app viene attivata in modalità di compatibilità quando necessario per adattarsi alle dimensioni del display.

    Su schermi di piccole dimensioni (sw < 600 dp), il sistema controlla minWidth e minHeight di un'attività per determinare se può essere eseguita in modalità multi-finestra. Se resizeableActivity="false", l'app non può essere eseguita in modalità multi-finestra, indipendentemente dall'altezza e dalla larghezza minime.

    Nota:i produttori dei dispositivi possono ignorare questi comportamenti.

Modalità schermo diviso

Gli utenti possono attivare la modalità schermo diviso procedendo nel seguente modo:

  1. Apri la schermata Recenti.
  2. Fai scorrere un'app per visualizzarla
  3. Premi l'icona dell'app nella barra del titolo dell'app
  4. Seleziona l'opzione di menu schermo diviso
  5. Seleziona un'altra app dalla schermata Recenti oppure chiudi la schermata Recenti ed esegui un'altra app

Gli utenti possono uscire dalla modalità schermo diviso trascinando il divisore di finestra sul bordo dello schermo, verso l'alto o verso il basso, verso sinistra o verso destra.

Lancia adiacente

Se la tua app deve accedere ai contenuti tramite un intent, puoi utilizzare FLAG_ACTIVITY_LAUNCH_ADJACENT per aprire i contenuti in una finestra a schermo diviso adiacente.

FLAG_ACTIVITY_LAUNCH_ADJACENT è stato introdotto in Android 7.0 (livello API 24) per consentire alle app eseguite in modalità schermo diviso di avviare attività nella finestra adiacente.

Android 12L (livello API 32) e versioni successive hanno esteso la definizione del flag per consentire alle app in esecuzione a schermo intero di attivare la modalità schermo diviso e avviare attività nella finestra adiacente.

Per avviare un'attività adiacente, utilizza FLAG_ACTIVITY_LAUNCH_ADJACENT in combinazione con FLAG_ACTIVITY_NEW_TASK, ad esempio:

Kotlin

fun openUrlInAdjacentWindow(url: String) {
    Intent(Intent.ACTION_VIEW).apply {
        data = Uri.parse(url)
        addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT or
                           Intent.FLAG_ACTIVITY_NEW_TASK)
    }.also { intent ->
        startActivity(intent)
    }
}

Java

public void openUrlInAdjacentWindow(String url) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(Uri.parse(url));
    intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}

Ciclo di vita dell'attività in modalità multi-finestra

La modalità multi-finestra non modifica il ciclo di vita dell'attività. Tuttavia, lo stato ripristinato delle app in più finestre varia a seconda delle versioni di Android.

Riprendi

Android 10 (livello API 29) e versioni successive supportano il ripristino multiplo: tutte le attività rimangono nello stato RESUMED quando il dispositivo è in modalità multi-finestra. Un'attività può essere messa in pausa se un'attività trasparente si trova sopra l'attività o se l'attività non è attivabile, ad esempio modalità Picture in picture. È inoltre possibile che non ci sia alcuna attività in primo piano in un determinato momento, ad esempio se il riquadro a scomparsa delle notifiche è aperto. Il metodo onStop funziona come di consueto; viene richiamato ogni volta che un'attività viene rimossa dallo schermo.

La ripresa multipla è disponibile anche su alcuni dispositivi con Android 9 (livello API 28). Per attivare la ripresa multipla sui dispositivi Android 9, aggiungi i seguenti metadati del file manifest:

<meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" />

Per verificare che un determinato dispositivo supporti i metadati del file manifest, fai riferimento alle specifiche del dispositivo.

Android 9

Nella modalità multi-finestra su Android 9 (livello API 28) e versioni precedenti, in un determinato momento è attiva solo l'attività con cui l'utente ha interagito più di recente. Questa attività è considerata più alta ed è l'unica attività nello stato RESUMED. Tutte le altre attività visibili sono STARTED, ma non RESUMED. Tuttavia, il sistema assegna una priorità maggiore a queste attività visibili ma non ripristinate rispetto a quelle non visibili. Se l'utente interagisce con una delle attività visibili, questa viene ripresa e l'attività che in precedenza era quella di livello più alto entra nello stato STARTED.

Quando sono presenti più attività all'interno di un singolo processo di app attivo, l'attività con l'ordine Z più alto viene ripresa, mentre le altre vengono messe in pausa.

Modifiche alla configurazione

Quando l'utente imposta un'app in modalità multi-finestra, il sistema notifica l'attività di una modifica alla configurazione, come specificato in Gestire le modifiche alla configurazione. Questo accade anche quando l'utente ridimensiona l'app o la riporta in modalità a schermo intero.

Essenzialmente, questa modifica ha le stesse implicazioni del ciclo di vita delle attività di quando il sistema avvisa l'app che il dispositivo è passato dall'orientamento verticale a quello orizzontale, ad eccezione del fatto che le dimensioni del dispositivo vengono modificate anziché semplicemente scambiate. Come discusso nella sezione Gestire le modifiche alla configurazione, la tua attività può gestire autonomamente la modifica alla configurazione o consentire al sistema di eliminare l'attività e ricrearla con le nuove dimensioni.

Se l'utente sta ridimensionando una finestra e la ingrandisce in una delle due dimensioni, il sistema ridimensiona l'attività in base all'azione dell'utente e causa modifiche alla configurazione secondo necessità. Se l'app è in ritardo nel disegno nelle nuove aree esposte, il sistema riempie temporaneamente queste aree con il colore specificato dall'attributo windowBackground o con l'attributo stile windowBackgroundFallback predefinito.

Accesso esclusivo alle risorse

Per supportare la funzionalità di recupero multiplo, è disponibile un nuovo callback del ciclo di vita, onTopResumedActivityChanged().

Questo metodo viene richiamato quando un'attività acquisisce o perde la prima posizione di attività ripresa. Questo è importante per sapere quando un'attività utilizza una risorsa singola condivisa, come il microfono o la videocamera.

Kotlin

override fun onTopResumedActivityChanged(topResumed: Boolean) {
    if (topResumed) {
        // Top resumed activity
        // Can be a signal to re-acquire exclusive resources
    } else {
        // No longer the top resumed activity
    }
}

Java

@Override
public void onTopResumedActivityChanged(boolean topResumed) {
    if (topResumed) {
        // Top resumed activity
        // Can be a signal to re-acquire exclusive resources
    } else {
        // No longer the top resumed activity
    }
}

Tieni presente che un'app può perdere risorse per altri motivi, ad esempio la rimozione di un componente hardware condiviso.

In ogni caso, un'app deve gestire agevolmente gli eventi e le modifiche di stato che interessano le risorse disponibili.

Per le app che utilizzano una fotocamera, CameraManager.AvailabilityCallback#onCameraAccessPrioritiesChanged() indica che potrebbe essere un buon momento per provare ad accedere alla fotocamera. Questo metodo è disponibile a partire da Android 10 (livello API 29).

Ricorda che resizeableActivity=false non garantisce l'accesso esclusivo alla fotocamera, poiché altre app che utilizzano la fotocamera possono essere aperte su altri display.

Videocamera in modalità multi-finestra.

Figura 2. Videocamera in modalità multi-finestra.

Non è necessario rilasciare la fotocamera dell'app quando l'app perde la messa a fuoco. Ad esempio, potresti voler continuare l'anteprima della fotocamera mentre l'utente interagisce con l'app ripresa più in alto appena messa a fuoco. L'app può continuare a far funzionare la fotocamera quando non è l'app ripresa più in alto, ma deve gestire correttamente la richiesta di disconnessione. Quando l'app ripresa più in alto vuole usare la fotocamera, può aprirla e l'app perderà l'accesso. L'app può riaprire la fotocamera quando l'app torna a mettere a fuoco.

Dopo che un'app riceve una chiamata CameraDevice.StateCallback#onDisconnected(), le chiamate successive sul dispositivo della videocamera generano un CameraAccessException.

Display multiplo

Android 10 (livello API 29) supporta le attività su display secondari. Se un'attività è in esecuzione su un dispositivo con più display, gli utenti possono spostarla da un display all'altro. La ripresa multipla si applica anche agli scenari multischermo; diverse attività possono ricevere l'input dell'utente contemporaneamente.

Un'app può specificare su quale display deve essere eseguita all'avvio o quando crea un'altra attività. Questo comportamento dipende dalla modalità di avvio dell'attività definita nel file manifest, nonché dalle opzioni e dai flag di intent impostati dall'entità che avvia l'attività. Per ulteriori dettagli, consulta ActivityOptions.

Quando un'attività passa a un display secondario, può essere sottoposta ad aggiornamento di contesto, ridimensionamento di finestre e modifiche alla configurazione e alle risorse. Se l'attività gestisce la modifica della configurazione, l'attività viene notificata in onConfigurationChanged(); in caso contrario, l'attività viene riavviata.

Un'attività deve controllare la visualizzazione corrente in onCreate e onConfigurationChanged se gestisce la modifica della configurazione. Assicurati di aggiornare le risorse e i layout quando il display cambia.

Se la modalità di avvio selezionata per un'attività consente più istanze, l'avvio su uno schermo secondario può creare una nuova istanza dell'attività. Entrambe le attività verranno riprese contemporaneamente.

Istanze multiple di un&#39;attività su più display.

Figura 3. Istanze multiple di un'attività su più display.

Puoi anche leggere ulteriori informazioni sulle API multi-display introdotte in Android 8.0.

Attività e contesto dell'applicazione

Utilizzare il giusto contesto è fondamentale per le campagne su più display. Quando si accede alle risorse, il contesto dell'attività (visualizzato) è diverso da quello dell'applicazione (che non lo è).

Il contesto dell'attività contiene informazioni sulla visualizzazione ed è sempre modificato in base all'area di visualizzazione in cui viene visualizzata l'attività. Ciò ti consente di ottenere le informazioni corrette sulle metriche relative alla densità o alla finestra della visualizzazione attualmente presenti nella tua app. Devi sempre utilizzare il contesto dell'attività (o un altro contesto basato sull'UI) per ottenere informazioni sulla finestra o sulla visualizzazione corrente. Questo riguarda anche alcune API di sistema che utilizzano informazioni provenienti dal contesto (ad esempio, consulta la panoramica dei toast).

La configurazione della finestra delle attività e la visualizzazione padre definiscono le risorse e il contesto. Ottieni la visualizzazione corrente come segue:

Kotlin

val activityDisplay = activity.getDisplay()

Java

Display activityDisplay = activity.getDisplay();

Visualizza le metriche della finestra delle attività correnti:

Kotlin

val windowMetrics = activity.getWindowManager().getCurrentWindowMetrics()

Java

WindowMetrics windowMetrics = activity.getWindowManager().getCurrentWindowMetrics();

Visualizza le metriche massime delle finestre per la configurazione di sistema attuale:

Kotlin

val maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics()

Java

WindowMetrics maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics();

Le metriche relative alla finestra massima consentono di effettuare calcoli, scegliere il layout o determinare le dimensioni delle risorse da recuperare in anticipo. Se questa opzione è disponibile in onCreate(), puoi prendere queste decisioni prima che il primo layout venga superato. Queste metriche non devono essere utilizzate per definire elementi di visualizzazione specifici; utilizza invece le informazioni dell'oggetto Configuration.

Ritagli display

I dispositivi pieghevoli potrebbero avere una geometria di taglio diversa quando sono piegati e aperti. Per evitare problemi di ritaglio, leggi le Best practice per il supporto dei ritagli display.

Display secondari

Puoi ottenere i display disponibili dal servizio di sistema DisplayManager:

Kotlin

val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = displayManager.getDisplays()

Java

DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
Display[] displays = displayManager.getDisplays();

Utilizza la classe Display per ottenere informazioni su un determinato display, come le dimensioni del display o i flag che indicano se un display è sicuro. Tuttavia, non dare per scontato che le dimensioni di visualizzazione saranno le stesse dell'area di visualizzazione assegnata all'applicazione. Ricorda che nella modalità multi-finestra, l'applicazione occupa una parte del display.

Stabilisci se un'attività può essere avviata su un display:

Kotlin

val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val activityAllowed = activityManager.isActivityStartAllowedOnDisplay(context, displayId, intent)

Java

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
boolean activityAllowed = activityManager.isActivityStartAllowedOnDisplay(context, displayId, intent);

Dopodiché avvia l'attività sul display:

Kotlin

val options = ActivityOptions.makeBasic()
options.setLaunchDisplayId(targetDisplay.displayId)
startActivity(intent, options.toBundle())

Java

ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(targetDisplay.displayId);
startActivity(intent, options.toBundle());

Supporto di più display

Android offre supporto multi-display per tastiere software, sfondi e Avvio app.

Tastiera software

Una tastiera può essere visualizzata su uno schermo secondario se il display è configurato per supportare le decorazioni del sistema. L'editor del metodo di immissione viene visualizzato automaticamente se un campo di testo richiede l'input.

Tastiera su un display secondario.

Figura 4. Tastiera su un display secondario.

Sfondo

In Android 10 (livello API 29), le schermate secondarie possono avere uno sfondo. Il framework crea un'istanza separata di WallpaperService.Engine per ogni display. Assicurati che la superficie di ogni motore sia tracciata in modo indipendente. Gli sviluppatori possono caricare gli asset utilizzando il contesto di visualizzazione in WallpaperService.Engine#getDisplayContext(). Inoltre, assicurati che i tuoi set di file WallpaperInfo.xml android:supportsMultipleDisplays="true".

Sfondo su telefono e display secondario.

Figura 5. Sfondo su telefono e display secondario.

Avvio app

Una nuova categoria di filtro per intent, SECONDARY_HOME, fornisce un'attività dedicata per le schermate secondarie. Le istanze dell'attività vengono utilizzate su tutti i display che supportano le decorazioni del sistema, una per ogni display.

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

L'attività deve avere una modalità di avvio che non impedisca la presenza di più istanze e possa adattarsi a diverse dimensioni dello schermo. La modalità di avvio non può essere singleInstance o singleTask.

Ad esempio, l'implementazione AOSP di Launcher3 supporta un'attività SECONDARY_HOME.

Avvio app Material Design su uno smartphone.

Figura 6. Avvio app Material Design su uno smartphone.

Avvio app di Material Design su un display secondario.

Figura 7. Avvio app di Material Design su un display secondario.

Metriche finestra

Android 11 (livello API 30) ha introdotto i seguenti metodi WindowManager per fornire i limiti delle app in esecuzione in modalità multi-finestra:

I metodi della libreria Jetpack WindowManager computeCurrentWindowMetrics() e computeMaximumWindowMetrics() offrono rispettivamente funzionalità simili, ma con compatibilità con le versioni precedenti al livello API 14.

Per ottenere metriche per visualizzazioni diverse da quella corrente:

  • Creare un contesto di visualizzazione
  • Crea un contesto della finestra per la visualizzazione
  • Ottieni il WindowManager del contesto della finestra
  • Ottieni WindowMetrics dell'area di visualizzazione massima disponibile per l'app

Kotlin

val windowMetrics = context.createDisplayContext(display)
                    .createWindowContext(WindowManager.LayoutParams.TYPE_APPLICATION, null)
                    .getSystemService(WindowManager::class.java)
                    .maximumWindowMetrics

Java

WindowMetrics windowMetrics = context.createDisplayContext(display)
                              .createWindowContext(WindowManager.LayoutParams.TYPE_APPLICATION, null)
                              .getSystemService(WindowManager.class)
                              .getMaximumWindowMetrics();

Metodi deprecati

I metodi Display getSize() e getMetrics() sono stati deprecati nel livello API 30 a favore dei nuovi metodi WindowManager.

Android 12 (livello API 31) ritira i metodi Display getRealSize() e getRealMetrics() e ne aggiorna il comportamento per rispecchiare meglio il comportamento di getMaximumWindowMetrics().

Configurazione della modalità multi-finestra

Se la tua app ha come target Android 7.0 (livello API 24) o versioni successive, puoi configurare se le attività dell'app supportano la modalità multi-finestra e se. Puoi impostare attributi nel file manifest per controllare dimensioni e layout. Le impostazioni degli attributi di un'attività principale si applicano a tutte le attività nel relativo stack. Ad esempio, se l'attività principale ha android:resizeableActivity="true", tutte le attività nello stack di attività sono ridimensionabili. Su alcuni dispositivi più grandi, come i Chromebook, l'app potrebbe essere eseguita in una finestra ridimensionabile anche se specifichi android:resizeableActivity="false". Se questa operazione compromette la disponibilità dell'app, puoi utilizzare i filtri per limitarne la disponibilità su questi dispositivi.

Per impostazione predefinita, Android 12 (livello API 31) è in modalità multi-finestra. Su schermi di grandi dimensioni (sw >= 600 dp), tutte le app vengono eseguite in modalità multi-finestra, indipendentemente dalla loro configurazione. Su schermi di piccole dimensioni, il sistema controlla le impostazioni di minWidth, minHeight e resizeableActivity di un'attività per determinare se l'attività può essere eseguita in modalità multi-finestra.

dimensionableActivity

Imposta questo attributo nell'elemento <activity> o <application> del tuo manifest per attivare o disattivare la modalità multi-finestra per il livello API 30 e livelli precedenti:

<application
  android:name=".MyActivity"
  android:resizeableActivity=["true" | "false"] />

Se questo attributo è impostato su true, l'attività può essere avviata in modalità schermo diviso e in formato libero. Se l'attributo è impostato su false, l'attività non supporta la modalità multi-finestra. Se questo valore è false e l'utente cerca di avviare l'attività in modalità multi-finestra, l'attività assume il controllo della modalità a schermo intero.

Se la tua app ha come target il livello API 24 o un livello successivo, ma non specifichi un valore per questo attributo, il valore predefinito dell'attributo sarà true.

Se la tua app ha come target il livello API 31 o superiore, questo attributo funziona in modo diverso su schermi piccoli e grandi:

  • Schermi grandi (sw >= 600 dp): tutte le app supportano la modalità multi-finestra. L'attributo indica se un'attività può essere ridimensionata. Se resizeableActivity="false", l'app viene attivata in modalità di compatibilità quando necessario per conformarsi alle dimensioni del display.
  • Schermi piccoli (sw < 600 dp): se resizeableActivity="true" e la larghezza minima e l'altezza minima dell'attività rientrano nei requisiti multi-finestra, l'attività supporta la modalità multi-finestra. Se resizeableActivity="false", l'attività non supporta la modalità multi-finestra, indipendentemente dall'altezza e dalla larghezza minime dell'attività.

supportaPictureInPicture

Imposta questo attributo nel nodo <activity> del tuo file manifest per indicare se l'attività supporta la modalità Picture in picture.

<activity
  android:name=".MyActivity"
  android:supportsPictureInPicture=["true" | "false"] />

configChanges

Per gestire autonomamente le modifiche alla configurazione multi-finestra, ad esempio quando un utente ridimensiona una finestra, aggiungi l'attributo android:configChanges al nodo manifest dell'app <activity> specificando almeno i seguenti valori:

<activity
  android:name=".MyActivity"
  android:configChanges="screenSize | smallestScreenSize
      | screenLayout | orientation" />

Dopo aver aggiunto android:configChanges, l'attività e i frammenti ricevono un callback a onConfigurationChanged() anziché essere eliminati e ricreati. Quindi, puoi aggiornare manualmente le visualizzazioni, ricaricare le risorse ed eseguire altre operazioni in base alle tue esigenze.

<layout>

Su Android 7.0 (livello API 24) e versioni successive, l'elemento manifest <layout> supporta diversi attributi che influiscono sul comportamento di un'attività in modalità multi-finestra:

android:defaultHeight, android:defaultWidth
Altezza e larghezza predefinite dell'attività quando viene avviata in modalità in formato libero.
android:gravity
Posizionamento iniziale dell'attività quando viene avviata in modalità in formato libero. Consulta Gravity per i valori adatti.
android:minHeight, android:minWidth
Altezza e larghezza minima per l'attività sia in modalità schermo diviso che in formato libero. Se l'utente sposta il divisore in modalità schermo diviso per ridurre un'attività rispetto al minimo specificato, il sistema taglia l'attività in base alle dimensioni richieste dall'utente.

Il seguente codice mostra come specificare la dimensione e la località predefinite di un'attività, nonché le dimensioni minime quando l'attività viene visualizzata in modalità in formato libero:

<activity android:name=".MyActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end|..."
          android:minHeight="450dp"
          android:minWidth="300dp" />
</activity>

Modalità multi-finestra in fase di runtime

A partire da Android 7.0, il sistema offre funzionalità che supportano le app che possono essere eseguite in modalità multi-finestra.

Funzionalità disattivate in modalità multi-finestra

Nella modalità multi-finestra, Android potrebbe disattivare o ignorare le funzionalità non applicabili a un'attività che condivide lo schermo del dispositivo con altre attività o app.

Inoltre, alcune opzioni di personalizzazione dell'interfaccia utente di sistema sono disattivate. Ad esempio, le app non possono nascondere la barra di stato se sono in esecuzione in modalità multi-finestra (consulta Controllare la visibilità dell'UI di sistema).

Il sistema ignora le modifiche all'attributo android:screenOrientation.

Query e callback in modalità multi-finestra

La classe Activity offre i seguenti metodi per supportare la modalità multi-finestra:

isInMultiWindowMode()
Indica se l'attività è in modalità multi-finestra.
isInPictureInPictureMode()

Indica se l'attività è in modalità Picture in picture.

Nota: la modalità Picture in picture è un caso speciale della modalità multi-finestra. Se myActivity.isInPictureInPictureMode() restituisce true, anche myActivity.isInMultiWindowMode() restituisce true.

onMultiWindowModeChanged()
Il sistema chiama questo metodo ogni volta che l'attività entra o esce dalla modalità multi-finestra. Il sistema trasmette al metodo il valore true se l'attività entra in modalità multi-finestra o false se l'attività esce dalla modalità multi-finestra.
onPictureInPictureModeChanged()
Il sistema chiama questo metodo ogni volta che l'attività entra o esce dalla modalità Picture in picture. Il sistema trasmette al metodo il valore true se l'attività entra in modalità Picture in picture o false se l'attività sta uscendo dalla modalità Picture in picture.

La classe Fragment espone le versioni di molti di questi metodi, ad esempio Fragment.onMultiWindowModeChanged().

Modalità Picture in picture

Per attivare la modalità Picture in picture, chiama il numero enterPictureInPictureMode() Questo metodo non ha effetto se il dispositivo non supporta la modalità Picture in picture. Per ulteriori informazioni, consulta la pagina Supporto della funzione Picture in picture.

Nuove attività in modalità multi-finestra

Quando avvii una nuova attività, puoi indicare che la nuova attività deve essere visualizzata accanto a quella corrente, se possibile. Utilizza il flag di intent FLAG_ACTIVITY_LAUNCH_ADJACENT, che indica al sistema di provare a creare la nuova attività in una finestra adiacente, in modo che le due attività condividano lo schermo. Il sistema fa il possibile per farlo, ma non è garantito che ciò accada.

Se un dispositivo è in modalità in formato libero e stai avviando una nuova attività, puoi specificare le dimensioni della nuova attività e la posizione dello schermo chiamando ActivityOptions.setLaunchBounds(). Questo metodo non ha effetto se il dispositivo non è in modalità multi-finestra.

A livello API 30 e livelli precedenti, se avvii un'attività in uno stack di attività, l'attività sostituisce l'attività sullo schermo, ereditando tutte le relative proprietà multi-finestra. Per avviare la nuova attività come finestra separata in modalità multi-finestra, devi avviarla in un nuovo stack di attività.

Android 12 (livello API 31) consente alle app di suddividere la finestra delle attività di un'applicazione tra più attività. Puoi determinare in che modo la tua app visualizza le sue attività (a schermo intero, affiancate o in pila) creando un file di configurazione XML o effettuando chiamate API Jetpack WindowManager.

Trascina

Gli utenti possono trascinare i dati da un'attività all'altra mentre le due attività condividono lo schermo. Prima di Android 7.0, gli utenti potevano trascinare i dati solo all'interno di una singola attività. Per aggiungere rapidamente il supporto per l'accettazione di contenuti persi, consulta l'API DropHelper. Per una guida completa al trascinamento, consulta Trascinamento.

Multiistanza

Ogni attività root ha la propria attività, che viene eseguita in un processo separato e viene visualizzata in una propria finestra. Per avviare una nuova istanza della tua app in una finestra separata, puoi avviare nuove attività con il flag FLAG_ACTIVITY_NEW_TASK. Puoi combinare questa operazione con alcuni degli attributi multi-finestra per richiedere una località specifica per la nuova finestra. Ad esempio, un'app per gli acquisti può mostrare più finestre per confrontare i prodotti.

Android 12 (livello API 31) ti consente di avviare due istanze di un'attività una accanto all'altra nella stessa finestra delle attività.

Se vuoi consentire agli utenti di avviare un'altra istanza della tua applicazione da Avvio applicazioni o dalla barra delle applicazioni, assicurati che l'Attività di avvio imposti android:resizeableActivity="true" e non utilizzi una modalità di avvio che impedisca più istanze. Ad esempio, è possibile creare un'istanza di un'attività singleInstancePerTask più volte in attività diverse se è impostata l'opzione FLAG_ACTIVITY_MULTIPLE_TASK o FLAG_ACTIVITY_NEW_DOCUMENT.

Non confondere le istanze multiple con un layout a più riquadri, ad esempio una presentazione con i dettagli dell'elenco in cui viene usato SlidingPaneLayout, in esecuzione all'interno di una singola finestra.

Tieni presente che quando più istanze sono in esecuzione in finestre separate su un dispositivo pieghevole, se la posizione cambia, una o più istanze potrebbero essere inviate in background. Ad esempio, supponiamo che un dispositivo sia aperto e che abbia due istanze di app in esecuzione in due finestre su entrambi i lati del fold. Se il dispositivo è chiuso, una delle istanze potrebbe essere terminata invece di provare a adattarsi alle finestre per entrambe le istanze su uno schermo più piccolo.

Verifica modalità multi-finestra

Indipendentemente dal fatto che la tua app abbia come target il livello API 24 o versioni successive, devi verificare il suo comportamento in modalità multi-finestra nel caso in cui un utente provi ad avviarla in modalità multi-finestra su un dispositivo con Android 7.0 o versioni successive.

Dispositivi di test

I dispositivi con Android 7.0 (livello API 24) o versioni successive supportano la modalità multi-finestra.

Livello API 23 o precedente

Quando gli utenti tentano di utilizzare l'app in modalità multi-finestra, il sistema ridimensiona forzatamente l'app, a meno che l'app non dichiari un orientamento fisso.

Se la tua app non dichiara un orientamento fisso, devi avviarla su un dispositivo con Android 7.0 o versioni successive e provare a impostare l'app in modalità schermo diviso. Verifica che l'esperienza utente sia accettabile con il ridimensionamento forzato dell'app.

Se l'app dichiara un orientamento fisso, devi provare a impostare l'app in modalità multi-finestra. Verifica che in questo caso l'app rimanga in modalità a schermo intero.

Livelli API da 24 a 30

Se la tua app ha come target i livelli API 24-30 e non disabilita il supporto multi-finestra, verifica il seguente comportamento sia in modalità schermo diviso che in formato libero:

  • Avvia l'app a schermo intero, quindi passa alla modalità multi-finestra premendo a lungo il pulsante Recenti. Verifica che l'app passi correttamente.
  • Avvia l'app direttamente in modalità multi-finestra e verifica che si avvii correttamente. Puoi avviare un'app in modalità multi-finestra premendo il pulsante Recenti, quindi premendo a lungo la barra del titolo dell'app e trascinandola in una delle aree evidenziate sullo schermo.
  • Ridimensiona l'app in modalità schermo diviso trascinando il divisore dello schermo. Verifica che l'app venga ridimensionata senza arresti anomali e che gli elementi UI necessari siano visibili.
  • Se hai specificato dimensioni minime per la tua app, prova a ridimensionare l'app al di sotto di queste dimensioni. Verifica di non poter ridimensionare l'app in modo che non superi le dimensioni minime specificate.
  • Con tutti i test, verifica che le prestazioni della tua app siano accettabili. Ad esempio, verifica che non sia troppo lungo per aggiornare l'UI dopo il ridimensionamento dell'app.

Livello API 31 o superiore

Se la tua app ha come target il livello API 31 o versioni successive e l'altezza minima e la larghezza minima dell'attività principale sono inferiori o uguali alle rispettive dimensioni dell'area di visualizzazione disponibile, verifica tutti i comportamenti elencati per i livelli API da 24 a 30.

Elenco di controllo per il test

Per verificare le prestazioni della tua app in modalità multi-finestra, prova le seguenti operazioni. Ti consigliamo di provare queste operazioni sia in modalità schermo diviso sia in formato libero, se non diversamente indicato.

  • Attiva ed esci dalla modalità multi-finestra.
  • Passa dalla tua app a un'altra app e verifica che si comporti correttamente mentre è visibile, ma non attiva. Ad esempio, se la tua app sta riproducendo video, verifica che la riproduzione del video continui mentre l'utente interagisce con un'altra app.
  • In modalità schermo diviso, prova a spostare il divisore dello schermo per ingrandire e ridurre l'app. Prova queste operazioni affiancate e una sopra le altre configurazioni. Verifica che l'app non abbia un arresto anomalo, che la funzionalità essenziale sia visibile e che l'operazione di ridimensionamento non richieda troppo tempo.
  • Esegui diverse operazioni di ridimensionamento in rapida successione. Verifica che l'app non abbia arresti anomali o perdite di memoria. Memory Profiler di Android Studio fornisce informazioni sulla memoria utilizzata dall'app (consulta la sezione Controllare l'utilizzo della memoria da parte dell'app con Memory Profiler).
  • Utilizza la tua app normalmente in una serie di configurazioni di finestre diverse e verifica che funzioni correttamente. Verifica che il testo sia leggibile e che gli elementi dell'interfaccia utente non siano troppo piccoli per interagire.

Supporto multi-finestra disattivato

Sui livelli API da 24 a 30, se hai disabilitato il supporto della modalità multi-finestra impostando android:resizeableActivity="false", devi avviare l'app su un dispositivo con Android 7.0-11 e provare a impostare l'app in modalità schermo diviso e in formato libero. Verifica che, in questo caso, l'app rimanga in modalità a schermo intero.

Risorse aggiuntive

Per ulteriori informazioni sul supporto della modalità multi-finestra in Android, vedi: