Schermata Recenti

La schermata Recenti, chiamata anche schermata Panoramica, elenco delle attività recenti o schermata delle app recenti, è un'interfaccia utente a livello di sistema che elenca le attività a cui è stato eseguito l'accesso di recente e . L'utente può navigare nell'elenco, selezionare un'attività da riprendere o rimuovere un'attività dall'elenco scorrendola.

La schermata Recenti utilizza un modello incentrato sui documenti, introdotto in Android 5.0 (livello API 21), in cui più istanze della stessa attività contenenti documenti diversi possono essere visualizzate come attività nella schermata Recenti. Ad esempio, Google Drive potrebbe avere un'attività per ognuno dei diversi documenti Google. Ogni documento viene visualizzato come attività nella schermata Recenti:

La schermata Recenti che mostra due documenti di Google Drive documenti, ognuno rappresentato come un'attività separata.

Un altro esempio comune è quando l'utente utilizza il browser e tocca Condividi > Gmail. Viene visualizzata la schermata Scrivi dell'app Gmail. Se tocchi il pulsante Recenti in quel momento, Chrome e Gmail vengono eseguiti come attività separate:

La schermata Recenti che mostra Chrome e Gmail in esecuzione come attività separate.

In genere, lasci che il sistema definisca la modalità di rappresentazione delle attività nella schermata Recenti. Non è necessario modificare questo comportamento. Tuttavia, la tua app può determinare come e quando le attività vengono visualizzate nella schermata Recenti.

La ActivityManager.AppTask classe consente di gestire le attività, mentre i flag delle attività della Intent classe consentono di specificare quando un' attività viene aggiunta o rimossa dalla schermata Recenti. Inoltre, gli attributi <activity> consentono di impostare il comportamento nel manifest.

Aggiungere attività alla schermata Recenti

L'utilizzo dei flag della classe Intent per aggiungere un'attività offre un maggiore controllo su quando e come un documento viene aperto o riaperto nella schermata Recenti. Quando utilizzi gli attributi <activity>, puoi scegliere se aprire sempre il documento in una nuova attività o riutilizzare un'attività esistente per il documento.

Utilizzare il flag Intent per aggiungere un'attività

Quando crei un nuovo documento per la tua attività, chiami il startActivity() metodo, passandogli l'intent che avvia l'attività. Per inserire un'interruzione logica in modo che il sistema tratti la tua attività come una nuova attività nella schermata Recenti, passa il FLAG_ACTIVITY_NEW_DOCUMENT flag nel addFlags() metodo del Intent che avvia l'attività.

Se imposti il FLAG_ACTIVITY_MULTIPLE_TASK flag quando crei il nuovo documento, il sistema crea sempre una nuova attività con l'attività di destinazione come radice. Questa impostazione consente di aprire lo stesso documento in più attività. Il seguente codice mostra come l'attività principale esegue questa operazione e avvia la nuova attività dal tuo elemento componibile:

private fun newDocumentIntent(context: Context): Intent =
    Intent(context, NewDocumentActivity::class.java).apply {
        addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT or Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)
        putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, documentCounter++)
    }

@Composable
fun CreateDocumentButton() {
    val context = LocalContext.current
    Button(
        onClick = {
            val intent = newDocumentIntent(context)
            // Add FLAG_ACTIVITY_MULTIPLE_TASK if needed based on state
            context.startActivity(intent)
        }
    ) {
        Text("Create New Document")
    }
}

Quando l'attività principale avvia una nuova attività, il sistema cerca tra le attività esistenti quella il cui intent corrisponde al nome del componente intent e ai dati intent dell'attività. Se l'attività non viene trovata o l'intent contiene il flag FLAG_ACTIVITY_MULTIPLE_TASK, viene creata una nuova attività con l'attività come radice.

Se il sistema trova un'attività il cui intent corrisponde al nome del componente intent e ai dati intent, porta l'attività in primo piano e passa il nuovo intent a onNewIntent(). La nuova attività riceve l'intent e crea un nuovo documento nella schermata Recenti, come mostrato nell'esempio seguente:

class DocumentCentricActivity : ComponentActivity() {
    private var documentState by mutableStateOf(
        DocumentState(
            count = 0,
            textResId = R.string.hello_new_document_counter
        )
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val initialCount = intent.getIntExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0)

        documentState = documentState.copy(count = initialCount)

        setContent {
            MaterialTheme {
                DocumentScreen(
                    count = documentState.count,
                    textResId = documentState.textResId
                )
            }
        }
    }

    override fun onNewIntent(newIntent: Intent) {
        super.onNewIntent(newIntent)
        // If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this Activity is reused.
        documentState = documentState.copy(
            textResId = R.string.reusing_document_counter
        )
    }

    data class DocumentState(val count: Int, @StringRes val textResId: Int)

    companion object {
        const val KEY_EXTRA_NEW_DOCUMENT_COUNTER = "KEY_EXTRA_NEW_DOCUMENT_COUNTER"
    }
}

@Composable
fun DocumentScreen(count: Int, @StringRes textResId: Int) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.Center
    ) {
        // UI reacts to whichever string resource ID was passed down
        Text(text = stringResource(id = textResId))
        Spacer(modifier = Modifier.height(8.dp))
        Text(text = "Counter: $count")
    }
}

Nel codice precedente, l'attività gestisce il routing a livello di sistema operativo (onCreate e onNewIntent), mentre la funzione @Composable è responsabile solo del rendering dell'interfaccia utente in base allo stato fornito.

Utilizzare l'attributo activity per aggiungere un'attività

Un'attività può anche specificare nel manifest che viene sempre avviata in una nuova attività utilizzando l'<activity> attributo android:documentLaunchMode. Questo attributo ha quattro valori, che producono i seguenti effetti quando l'utente apre un documento con l'applicazione:

intoExisting
L'attività riutilizza un'attività esistente per il documento. È come impostare il FLAG_ACTIVITY_NEW_DOCUMENT flag senza impostare il FLAG_ACTIVITY_MULTIPLE_TASK flag, come descritto nella sezione Utilizzare il flag Intent per aggiungere un'attività.
always
L'attività crea una nuova attività per il documento, anche se il documento è già aperto. L'utilizzo di questo valore equivale all'impostazione dei flag FLAG_ACTIVITY_NEW_DOCUMENT e FLAG_ACTIVITY_MULTIPLE_TASK.
none
L'attività non crea una nuova attività per il documento. La schermata Recenti tratta l'attività come farebbe per impostazione predefinita. Visualizza una singola attività per l'app, che riprende dall'ultima attività richiamata dall'utente.
never
L'attività non crea una nuova attività per il documento. L'impostazione di questo valore sostituisce il comportamento dei flag FLAG_ACTIVITY_NEW_DOCUMENT e FLAG_ACTIVITY_MULTIPLE_TASK. Se uno di questi è impostato nell'intent e la schermata Recenti mostra una singola attività per l'app, riprende dall'ultima attività richiamata dall'utente.

Rimuovere le attività

Per impostazione predefinita, un'attività di documento esce automaticamente dalla schermata Recenti al termine dell'attività. Puoi sostituire questo comportamento con la ActivityManager.AppTask classe, con un Intent flag, o con un <activity> attributo.

Puoi sempre escludere completamente un'attività dalla schermata Recenti impostando l'attributo <activity> android:excludeFromRecents su true.

Puoi impostare il numero massimo di attività che la tua app può includere nella schermata Recenti impostando l' <activity> attributo android:maxRecents su un valore intero. Quando viene raggiunto il numero massimo di attività, l'attività utilizzata meno di recente scompare dalla schermata Recenti. Il valore predefinito è 16 e il valore massimo è 50 (25 sui dispositivi con poca memoria). I valori inferiori a 1 non sono validi.

Utilizzare la classe AppTask per rimuovere le attività

Nell'attività che crea una nuova attività nella schermata Recenti, puoi specificare quando rimuovere l'attività e terminare tutte le attività associate chiamando il finishAndRemoveTask() metodo:

@Composable
fun RemoveTaskButton() {
    val context = LocalContext.current
    Button(
        onClick = {
            // It is good practice to remove a document from the overview stack if not needed anymore.
            (context as? Activity)?.finishAndRemoveTask()
        }
    ) {
        Text("Remove from Recents")
    }
}

Conservare le attività completate

Se vuoi conservare un'attività nella schermata Recenti, anche se l'attività è terminata, passa il FLAG_ACTIVITY_RETAIN_IN_RECENTS flag nel addFlags() metodo dell' intent che avvia l'attività.

private fun newDocumentIntent() =
        Intent(this, NewDocumentActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT or
                    android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)
            putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, getAndIncrement())
        }

Per ottenere lo stesso effetto, imposta l'attributo <activity> android:autoRemoveFromRecents su false. Il valore predefinito è true per le attività di documento e false per le attività normali. L'utilizzo di questo attributo sostituisce il flag FLAG_ACTIVITY_RETAIN_IN_RECENTS.

Attivare la condivisione degli URL recenti (solo Pixel)

Sui dispositivi Pixel con Android 12 o versioni successive, gli utenti possono condividere i link ai contenuti web visualizzati di recente direttamente dalla schermata Recenti. Dopo aver visitato i contenuti in un'app, l'utente può scorrere fino alla schermata Recenti e trovare l'app in cui ha visualizzato i contenuti, quindi toccare il pulsante del link per copiare o condividere l'URL.

La schermata Recenti con un link per condividere i contenuti web visualizzati di recente.

Qualsiasi app può attivare il collegamento Recenti per gli utenti fornendo un'interfaccia utente web e sostituendo onProvideAssistContent(), come mostrato nell'esempio seguente:

class MainActivity : ComponentActivity() {

    // Track the current URL as state so the UI can update it during navigation
    private var currentWebUri by mutableStateOf("https://example.com/home")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            AppTheme {
                // Pass a lambda to your Compose UI so it can update the URL state
                // as the user navigates through your app.
                MainScreen(
                    onPageChanged = { newUrl -> currentWebUri = newUrl }
                )
            }
        }
    }

    override fun onProvideAssistContent(outContent: AssistContent) {
        super.onProvideAssistContent(outContent)

        // The system calls this when the user enters the Recents screen.
        // Provide the active URI tracked by the Compose state.
        outContent.webUri = Uri.parse(currentWebUri)
    }
}