Pantalla de Recientes

La pantalla Recientes, también llamada pantalla Recientes, lista de tareas recientes o pantalla de apps recientes, es una IU en el nivel del sistema que enumera las actividades y las tareas a las que se accedió recientemente. El usuario puede navegar por la lista, seleccionar una tarea para reanudarla o deslizarla para quitarla de la lista.

La pantalla Recientes usa un modelo centrado en documentos, que se introdujo en Android 5.0 (nivel de API 21), en el que varias instancias de la misma actividad que contiene diferentes documentos pueden aparecer como tareas en la pantalla Recientes. Por ejemplo, Google Drive podría tener una tarea para cada uno de varios documentos de Google. Cada documento aparece como una tarea en la pantalla Recientes:

En la pantalla Recientes, se muestran dos documentos de Google Drive, cada uno representado como una tarea independiente.

Otro ejemplo común es cuando el usuario usa su navegador y presiona Compartir > Gmail. Aparece la pantalla Redactarde la app de Gmail. Si presionas el botón Recientes en ese momento, Chrome y Gmail se ejecutan como tareas separadas:

La pantalla Recientes, que muestra Chrome y Gmail ejecutándose como tareas independientes.

Por lo general, permites que el sistema defina cómo se representan tus tareas y actividades en la pantalla Recientes. No es necesario modificar este comportamiento. Sin embargo, tu app puede determinar cómo y cuándo aparecen las actividades en la pantalla Recientes.

La clase ActivityManager.AppTask te permite administrar tareas, y las marcas de actividad de la clase Intent te permiten especificar cuándo se agrega o se quita una actividad de la pantalla Recientes. Además, los atributos <activity> te permiten configurar el comportamiento en el manifiesto.

Cómo agregar tareas a la pantalla Recientes

Usar las marcas de la clase Intent para agregar una tarea te brinda un mayor control sobre cuándo y cómo se abre o se vuelve a abrir un documento en la pantalla Recientes. Cuando usas los atributos <activity>, puedes elegir entre abrir siempre el documento en una tarea nueva o reutilizar una existente para el documento.

Cómo usar la marca de intent para agregar una tarea

Cuando creas un documento nuevo para tu actividad, llamas al método startActivity() y le pasas el intent que inicia la actividad. Para insertar una interrupción lógica de modo que el sistema trate tu actividad como una tarea nueva en la pantalla Recientes, pasa la marca FLAG_ACTIVITY_NEW_DOCUMENT en el método addFlags() de Intent que inicia la actividad.

Si configuras la marca FLAG_ACTIVITY_MULTIPLE_TASK cuando creas el documento nuevo, el sistema siempre creará una tarea nueva con la actividad objetivo como raíz. Este parámetro de configuración permite abrir el mismo documento en más de una tarea. En el siguiente código, se muestra cómo la actividad principal hace esto:

Kotlin

fun createNewDocument(view: View) {
    val newDocumentIntent = newDocumentIntent()
    if (useMultipleTasks) {
        newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
    }
    startActivity(newDocumentIntent)
}

private fun newDocumentIntent(): Intent =
        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, documentCounter++)
        }

Java

public void createNewDocument(View view) {
      final Intent newDocumentIntent = newDocumentIntent();
      if (useMultipleTasks) {
          newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
      }
      startActivity(newDocumentIntent);
  }

  private Intent newDocumentIntent() {
      boolean useMultipleTasks = checkbox.isChecked();
      final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
      newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
      newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, documentCounter++);
      return newDocumentIntent;
  }

}

Cuando la actividad principal inicia una actividad nueva, el sistema busca en las tareas existentes una cuyo intent coincida con el nombre del componente del intent y los datos del intent de la actividad. Si no se encuentra la tarea, o el intent contenía la marca FLAG_ACTIVITY_MULTIPLE_TASK, se crea una tarea nueva con la actividad como raíz.

Si el sistema encuentra una tarea cuyo intent coincide con el nombre del componente y los datos del intent, lleva esa tarea al primer plano y pasa el intent nuevo a onNewIntent(). La actividad nueva obtiene el intent y crea un documento nuevo en la pantalla Recientes, como se muestra en el siguiente ejemplo:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_new_document)
    documentCount = intent
            .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0)
    documentCounterTextView = findViewById(R.id.hello_new_document_text_view)
    setDocumentCounterText(R.string.hello_new_document_counter)
}

override fun onNewIntent(newIntent: Intent) {
    super.onNewIntent(newIntent)
    /* If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this Activity
    will be reused. */
    setDocumentCounterText(R.string.reusing_document_counter)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new_document);
    documentCount = getIntent()
            .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0);
    documentCounterTextView = (TextView) findViewById(
            R.id.hello_new_document_text_view);
    setDocumentCounterText(R.string.hello_new_document_counter);
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    /* If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this activity
    is reused to create a new document.
     */
    setDocumentCounterText(R.string.reusing_document_counter);
}

Usa el atributo de actividad para agregar una tarea

Una actividad también puede especificar en su manifiesto que siempre se inicia en una tarea nueva mediante el atributo <activity> android:documentLaunchMode. Este atributo tiene cuatro valores que producen los siguientes efectos cuando el usuario abre un documento con la aplicación:

intoExisting
La actividad reutiliza una tarea existente para el documento, Esto es lo mismo que configurar la marca FLAG_ACTIVITY_NEW_DOCUMENT sin establecer la marca FLAG_ACTIVITY_MULTIPLE_TASK, como se describe en la sección Cómo usar la marca de intent para agregar una tarea.
always
La actividad crea una tarea nueva para el documento, incluso si este ya está abierto. Usar este valor equivale a establecer las marcas FLAG_ACTIVITY_NEW_DOCUMENT y FLAG_ACTIVITY_MULTIPLE_TASK.
none
La actividad no crea una nueva tarea para el documento. La pantalla Recientes trata la actividad como lo haría de forma predeterminada. Se muestra una sola tarea para la app, que se reanuda desde la última actividad que el usuario invocó.
never
La actividad no crea una nueva tarea para el documento. Configurar este valor anula el comportamiento de las marcas FLAG_ACTIVITY_NEW_DOCUMENT y FLAG_ACTIVITY_MULTIPLE_TASK. Si cualquiera de estos se establece en el intent y en la pantalla Recientes se muestra una sola tarea para la app, se reanuda desde la última actividad que el usuario invocó.

Cómo quitar tareas

De forma predeterminada, la tarea de un documento sale automáticamente de la pantalla Recientes cuando finaliza su actividad. Puedes anular este comportamiento con la clase ActivityManager.AppTask, con una marca Intent o con un atributo <activity>.

Puedes excluir por completo una tarea de la pantalla Recientes. Para ello, configura el atributo <activity> android:excludeFromRecents en true.

Para establecer la cantidad máxima de tareas que tu app puede incluir en la pantalla Recientes, configura el atributo <activity> android:maxRecents en un valor de número entero. Cuando se alcanza la cantidad máxima de tareas, la que se usó menos recientemente desaparece de la pantalla Recientes. El valor predeterminado es 16 y el valor máximo es 50 (25 en dispositivos con poca memoria). Los valores inferiores a 1 no son válidos.

Cómo usar la clase AppTask para quitar tareas

En la actividad que crea una tarea nueva en la pantalla Recientes, puedes especificar cuándo quitar la tarea y finalizar todas las actividades asociadas con ella llamando al método finishAndRemoveTask():

Kotlin

fun onRemoveFromOverview(view: View) {
    // It is good pratice to remove a document from the overview stack if not needed anymore.
    finishAndRemoveTask()
}

Java

public void onRemoveFromRecents(View view) {
    // The document is no longer needed; remove its task.
    finishAndRemoveTask();
}

Retener las tareas finalizadas

Si deseas conservar una tarea en la pantalla Recientes, incluso si su actividad ya finalizó, pasa la marca FLAG_ACTIVITY_RETAIN_IN_RECENTS en el método addFlags() del intent que inicia la actividad.

Kotlin

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())
        }

Java

private Intent newDocumentIntent() {
    final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
    newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
      android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
    newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, getAndIncrement());
    return newDocumentIntent;
}

Para lograr el mismo efecto, establece el atributo android:autoRemoveFromRecents del atributo <activity> en false. El valor predeterminado es true para las actividades de documentos y false para las actividades normales. El uso de este atributo anula la marca FLAG_ACTIVITY_RETAIN_IN_RECENTS.

Habilita el uso compartido de URLs recientes (solo para Pixel)

En los dispositivos Pixel que ejecutan Android 12 o versiones posteriores, los usuarios pueden compartir vínculos a contenido web visto recientemente directamente desde la pantalla Recientes. Después de visitar el contenido de una app, el usuario puede deslizar el dedo hasta la pantalla Recientes, buscar la app en la que vio el contenido y, luego, presionar el botón de vínculo para copiar o compartir la URL.

La pantalla Recientes con un vínculo para compartir el contenido web visto recientemente.

Cualquier app puede habilitar la vinculación de Recientes para los usuarios proporcionando una IU web y anulando onProvideAssistContent(), como se muestra en el siguiente ejemplo:

Kotlin

class MainActivity : AppCompatActivity() {
    protected fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun onProvideAssistContent(outContent: AssistContent) {
        super.onProvideAssistContent(outContent)
        outContent.setWebUri(Uri.parse("https://example.com/myCurrentPage"))
    }
}

Java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void onProvideAssistContent(AssistContent outContent) {
        super.onProvideAssistContent(outContent);

        outContent.setWebUri(Uri.parse("https://example.com/myCurrentPage"));
    }
}