Cómo crear una copia de seguridad automática para los datos del usuario

La función Copia de seguridad automática para apps realiza copias de seguridad de los datos del usuario de las apps que se orientan y ejecutan en Android 6.0 (API nivel 23) o versiones posteriores. Android conserva los datos de app cargándolos en el Google Drive del usuario, donde están protegidos por las credenciales de su Cuenta de Google. La cantidad de datos está limitada a 25 MB por usuario de tu app y no se cobra por almacenar datos de copia de seguridad. Tu app puede personalizar el proceso de copia de seguridad u optar por inhabilitarlo.

Para obtener una descripción general de las opciones de copia de seguridad de Android y orientación sobre qué datos se deben incluir en una copia de seguridad y restablecimiento, consulta Descripción general de la copia de seguridad de datos.

Para un recorrido sobre cómo configurar la copia de seguridad automática, consulta también Codelab de copia de seguridad automática para Android.

Archivos con copia de seguridad

De forma predeterminada, la copia de seguridad automática incluye archivos en la mayoría de los directorios que el sistema asigna a tu app:

La copia de seguridad automática excluye archivos en directorios que muestra getCacheDir(), getCodeCacheDir() o getNoBackupFilesDir(). Los archivos guardados en estas ubicaciones solo se necesitan temporalmente o se excluyen de las operaciones de copia de seguridad de manera intencional.

Puedes configurar tu app para incluir y excluir archivos particulares. Para obtener más información, consulta la sección Cómo incluir y excluir archivos.

Nota: Android no trata la configuración de los componentes como datos del usuario. Si tu app habilita o inhabilita componentes específicos en su manifiesto mientras se ejecuta, la copia de seguridad automática no guarda ni restablece la configuración. Para conservar el estado de la configuración, guárdalo en Preferencias compartidas y recupera esas preferencias en el restablecimiento. Si quieres que tu app guarde su estado, guárdalo en Preferencias compartidas y recupera esas preferencias en el restablecimiento.

Ubicación de las copia de seguridad

Los datos de copia de seguridad se almacenan en una carpeta privada en la cuenta de Google Drive del usuario, limitada a 25 MB por aplicación. Los datos guardados no cuentan para la cuota personal de Google Drive del usuario. Solo se almacena la copia de seguridad más reciente. Cuando se crea una copia de seguridad, se borra la anterior (si existe). El usuario u otras aplicaciones del dispositivo no pueden leer los datos de la copia de seguridad.

Los usuarios pueden ver una lista de apps con copia de seguridad en la app de Google Drive para Android. En un dispositivo con Android, los usuarios pueden encontrar esta lista en el panel lateral de navegación de la app de Drive en Configuración > Crear copia de seguridad y restablecer > Datos de app.

Las copias de seguridad de cada conjunto de dispositivo, configuración y ciclo de vida se almacenan en conjuntos de datos por separado como se muestra en los siguientes ejemplos:

  • Si el usuario posee dos dispositivos, existe un conjunto de datos de copia de seguridad para cada uno.
  • Si el usuario restablece la configuración de fábrica de un dispositivo y luego lo configura con la misma cuenta, la copia de seguridad se almacena en un nuevo conjunto de datos. Los conjuntos de datos obsoletos se borran automáticamente después de un período de inactividad.

Cronograma de copia de seguridad

Las copias de seguridad se crean automáticamente cuando se cumplen todas estas condiciones:

  • El usuario ha habilitado la copia de seguridad en el dispositivo. En Android 9, esta configuración está en Configuración > Sistema > Copia de seguridad.
  • Han transcurrido al menos 24 horas desde la última copia de seguridad.
  • El dispositivo está inactivo.
  • El dispositivo está conectado a una red Wi-Fi (si el usuario del dispositivo no ha aceptado las copias de seguridad de datos móviles).

En la práctica, estas condiciones ocurren casi todas las noches, pero es posible que un dispositivo nunca cree una copia de seguridad (por ejemplo, si nunca se conecta a una red). Para conservar el ancho de banda de la red, la carga se realiza solo si cambian los datos de la app.

Durante la copia de seguridad automática, el sistema cierra la app para asegurarse de que ya no está escribiendo en el sistema de archivos. De forma predeterminada, el sistema de copia de seguridad ignora las apps que se ejecutan en primer plano porque los usuarios notarían el cierre. Puedes anular el comportamiento predeterminado configurando el atributo backupInForeground como verdadero.

Para simplificar las pruebas, Android incluye herramientas que te permiten iniciar una copia de seguridad para tu app manualmente. Para obtener más información, consulta Cómo probar copias de seguridad y restablecimientos.

Cómo restablecer el programa

Los datos se restablecen cada vez que se instala la app, ya sea desde Play Store, durante la configuración del dispositivo (cuando el sistema instala apps instaladas previamente) o cuando se ejecuta adb install. La operación de restablecimiento ocurre después de instalar el APK, pero antes de que la app esté disponible para que el usuario la inicie.

Durante el asistente de configuración inicial del dispositivo, se muestra al usuario una lista de conjuntos de datos de copia de seguridad disponibles y se le pregunta de cuál desea restablecer los datos. El conjunto de datos de copia de seguridad seleccionado se convierte en el conjunto de datos principal del dispositivo. El dispositivo se puede restablecer desde sus propias copias de seguridad o desde el conjunto de datos principal. Si las copias de seguridad de ambas fuentes están disponibles, el dispositivo prioriza la suya. Si el usuario no usó el asistente de configuración del dispositivo, solo podrá restablecerlo desde sus propias copias de seguridad.

Para simplificar las pruebas, Android incluye herramientas que te permiten iniciar un restablecimiento de tu app manualmente. Para obtener más información, consulta Cómo probar copias de seguridad y restablecimientos.

Cómo habilitar e inhabilitar una copia de seguridad

Las apps que se orientan a Android 6.0 (API nivel 23) o versiones posteriores participan automáticamente en una copia de seguridad automática. En tu archivo de manifiesto de la app, configura el valor booleano android:allowBackup para habilitar o inhabilitar la copia de seguridad. El valor predeterminado es true, pero para aclarar tus intenciones, te recomendamos que configures de forma explícita el atributo en tu manifiesto, como se muestra a continuación:

<manifest ... >
        ...
        <application android:allowBackup="true" ... >
            ...
        </application>
    </manifest>
    

Puedes inhabilitar las copias de seguridad configurando android:allowBackup como false. Te recomendamos que lo hagas si tu app puede recrear su estado a través de algún otro mecanismo o si maneja información sensible de la que Android no debe crear una copia de seguridad.

Cómo incluir y excluir archivos

De forma predeterminada, el sistema crea copias de seguridad de casi todos los datos de app. Para obtener más información, consulta Archivos con copia de seguridad. En esta sección, se muestra cómo definir reglas XML personalizadas para controlar el contenido que se incluye en una copia de seguridad.

  1. En AndroidManifest.xml, agrega el atributo android:fullBackupContent al elemento <application>. Este atributo apunta a un archivo XML que contiene reglas de copias de seguridad. Por ejemplo:
        <application ...
            android:fullBackupContent="@xml/my_backup_rules">
        </application>
        
  2. Crea un archivo XML llamado my_backup_rules.xml en el directorio res/xml/. Dentro del archivo, agrega reglas con los elementos <include> y <exclude>. En el siguiente ejemplo, se crea una copia de seguridad de todas las preferencias compartidas, excepto device.xml:
        <?xml version="1.0" encoding="utf-8"?>
        <full-backup-content>
            <include domain="sharedpref" path="."/>
            <exclude domain="sharedpref" path="device.xml"/>
        </full-backup-content>
        

Sintaxis de la configuración XML

A continuación, se muestra la sintaxis XML para el archivo de configuración:

    <full-backup-content>
        <include domain=["file" | "database" | "sharedpref" | "external" | "root"]
        path="string"
        requiredFlags=["clientSideEncryption" | "deviceToDeviceTransfer"] />
        <exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]
        path="string" />
    </full-backup-content>
    

Dentro de la etiqueta <full-backup-content>, puedes definir los elementos <include> y <exclude>:

  • <include>: Especifica un archivo o una carpeta que necesita copia de seguridad. De forma predeterminada, la copia de seguridad automática incluye casi todos los archivos de la app. Si especificas un elemento <include>, el sistema ya no incluye ningún archivo de forma predeterminada y crea una copia de seguridad solo de los archivos especificados. Para incluir varios archivos, usa varios elementos <include>.

    Nota: Los archivos del directorio que muestra getCacheDir(), getCodeCacheDir() o getNoBackupFilesDir() siempre se excluyen, incluso si intentas incluirlos.

  • <exclude>: Especifica un archivo o una carpeta para excluir durante la copia de seguridad. Estos son algunos archivos que, por lo general, se excluyen de la copia de seguridad:
    • Archivos que tienen identificadores específicos del dispositivo, emitidos por un servidor o generados en el dispositivo. Por ejemplo, Google Cloud Messaging (GCM) necesita generar un token de registro cada vez que un usuario instala tu app en un dispositivo nuevo. Si se restablece el token de registro anterior, es posible que la app se comporte de forma inesperada.
    • Credenciales de cuenta u otra información sensible. Considera pedirle al usuario que vuelva a autenticarse la primera vez que inicie una app restablecida en vez de almacenar esa información en la copia de seguridad.
    • Archivos relacionados con la depuración de app.
    • Archivos grandes que hacen que la app exceda la cuota de copia de seguridad de 25 MB.

Nota: Si tu archivo de configuración especifica ambos elementos, la copia de seguridad contiene todo lo capturado por los elementos <include> menos los recursos nombrados en los elementos <exclude>. En otras palabras, <exclude> tiene prioridad.

Cada elemento debe incluir los siguientes dos atributos:

  • domain: Especifica la ubicación del recurso. Los valores válidos para este atributo incluyen lo siguiente:
  • Nota: No puedes crear una copia de seguridad de archivos fuera de estas ubicaciones.

  • path: Especifica un archivo o una carpeta para incluir o excluir de la copia de seguridad. Ten en cuenta lo siguiente:
    • Este atributo no admite comodines ni sintaxis de regex.
    • Puedes usar . para hacer referencia al directorio actual. Sin embargo, no puedes hacer referencia al directorio principal .. por razones de seguridad.
    • Si especificas un directorio, la regla se aplica a todos los archivos del directorio y los subdirectorios recursivos.

El elemento include también puede contener el atributo requiredFlags. Esto se describe con más detalle en la sección Cómo definir requisitos condicionales para la copia de seguridad.

Cómo definir las condiciones del dispositivo necesarias para la copia de seguridad

Si tu app guarda información sensible en el dispositivo, puedes especificar las condiciones en las que se incluyen sus datos en la copia de seguridad del usuario. Puedes agregar las siguientes condiciones en Android 9 (API nivel 28) o versiones posteriores:

Si has actualizado tus dispositivos de desarrollo a Android 9, debes inhabilitar y volver a habilitar la copia de seguridad de datos después de la actualización. Esto se debe a que Android solo encripta las copias de seguridad con un secreto del cliente después de informar a los usuarios en Configuración o en el Asistente de configuración.

Para declarar las condiciones de inclusión, configura el atributo requireFlags con los valores deseados en los elementos <include>dentro de tu conjunto de reglas de copia de seguridad:

my_backup_rules.xml

    <?xml version="1.0" encoding="utf-8"?>
    <full-backup-content>
        <!-- App data isn't included in user's backup
             unless client-side encryption is enabled. -->
        <include domain="file" path="."
                 requireFlags="clientSideEncryption" />
    <full-backup-content>
    

Si tu app implementa un sistema de copia de seguridad de clave-valor, o si implementas BackupAgent, también puedes aplicar estos requisitos condicionales a tu lógica de copia de seguridad realizando una comparación de bits entre el conjunto de marcas de transporte de un objeto BackupDataOutput y las marcas de FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED o FLAG_DEVICE_TO_DEVICE_TRANSFER de tu agente de copia de seguridad personalizado.

En el siguiente fragmento de código, se muestra un ejemplo de uso de este método:

Kotlin

    class MyCustomBackupAgent : BackupAgent() {
        override fun onBackup(oldState: ParcelFileDescriptor?,
                data: BackupDataOutput?, newState: ParcelFileDescriptor?) {
            if (data != null) {
                if ((data.transportFlags and
                        FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED) != 0) {
                    // Client-side backup encryption is enabled.
                }

                if ((data.transportFlags and FLAG_DEVICE_TO_DEVICE_TRANSFER) != 0) {
                    // Local device-to-device transfer is enabled.
                }
            }
        }

        // Implementation of onRestore() here.
    }
    

Java

    public class MyCustomBackupAgent extends BackupAgent {
        @Override
        public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
                ParcelFileDescriptor newState) throws IOException {
            if ((data.getTransportFlags() &
                    FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED) != 0) {
                // Client-side backup encryption is enabled.
            }

            if ((data.getTransportFlags() &
                    FLAG_DEVICE_TO_DEVICE_TRANSFER) != 0) {
                // Local device-to-device transfer is enabled.
            }
        }

        // Implementation of onRestore() here.
    }
    

Cómo implementar BackupAgent

Las aplicaciones que implementan la copia de seguridad automática no necesitan implementar un BackupAgent. Sin embargo, de forma opcional, puedes implementar un BackupAgent personalizado. Por lo general, existen dos motivos para hacer esto:

  • Deseas recibir notificaciones de eventos de copia de seguridad, como onRestoreFinished() o onQuotaExceeded(long, long). Estos métodos de devolución de llamada ocurren incluso si la aplicación no se está ejecutando.
  • No puedes expresar fácilmente el conjunto de archivos para los que quieres crear una copia de seguridad con reglas XML. En estos casos poco frecuentes, puedes implementar un BackupAgent que anule onFullBackup(FullBackupDataOutput) para almacenar lo que deseas. Para retener la implementación predeterminada del sistema, llama al método correspondiente en la superclase con super.onFullBackup().

Si implementas un agente de copia de seguridad, el sistema, de forma predeterminada, espera que tu app cree una copia de seguridad de clave-valor y un restablecimiento. Si en su lugar deseas utilizar la copia de seguridad automática basada en archivos, configura el atributo android:fullBackupOnly como true en el manifiesto de tu app.

Durante las operaciones de copia de seguridad automática y restablecimiento, el sistema inicia la app en modo restringido para evitar que acceda a archivos que podrían causar conflictos y permitir que ejecute métodos de devolución de llamada en su BackupAgent. En este modo restringido, la actividad principal de la app no se inicia automáticamente, sus proveedores de contenido no se inicializan y se crea una instancia para Application de la clase base en vez de cualquier subclase declarada en el manifiesto de la app.

Precaución: Para evitar errores, asegúrate de que las partes de tu app que se ejecutan en modo restringido (sobre todo tu BackupAgent) no accedan a proveedores de contenido en la misma app ni intenten transmitir el objeto Application. Si no puedes evitar esos patrones, considera implementar la copia de seguridad de clave-valor o inhabilitar la copia de seguridad por completo.

Tu BackupAgent debe implementar los métodos abstractos onBackup() y onRestore(), que se usan para la copia de seguridad de clave-valor. Pero si no deseas crear una copia de seguridad de clave-valor, puedes dejar en blanco la implementación de esos métodos.

Para obtener más información, consulta Cómo extender BackupAgent.

Recursos adicionales

Para obtener más información sobre la copia de seguridad automática, consulta los siguientes recursos.

Codelabs