Fazer backup dos dados de usuários com o Backup automático

O Backup automático para apps salva os dados do usuário automaticamente de apps para Android 6.0 (nível 23 da API) ou mais recente. App de preservação do Android dados fazendo upload deles para o Google Drive do usuário, onde estarão protegidos pela credenciais da Conta do Google do usuário. O backup tem criptografia de ponta a ponta em dispositivos com Android 9 ou versões mais recentes usando PIN, padrão ou senha. Cada app pode alocar até 25 MB de dados de backup por usuário. Não há custos para armazenar dados de backup. Seu app pode personalizar o processo de backup, ou desativando os backups.

Para ter uma visão geral das opções de backup do Android e conferir uma orientação sobre quais dados armazenar em backup e restaurar, consulte a Visão geral do backup de dados.

Arquivos que são salvos em backup

Por padrão, o Backup automático inclui arquivos da maioria dos diretórios atribuídos ao seu app pelo sistema:

O Backup automático exclui os arquivos nos diretórios retornados por getCacheDir(). getCodeCacheDir() e getNoBackupFilesDir(). Os arquivos salvos nesses locais são necessários apenas temporariamente e são excluídos intencionalmente das operações de backup.

É possível configurar seu app para incluir e excluir arquivos específicos. Para mais informações, consulte a seção Incluir e excluir arquivos.

Local de backup

Os dados de backup são armazenados em uma pasta particular na conta do Google Drive do usuário, com o limite de 25 MB por app. Os dados salvos não contam para a cota pessoal do usuário no Google Drive. Apenas o backup mais recente é armazenado. Quando um backup é feito, todos os backups anteriores são excluídos. Os dados de backup não podem ser lidos pelo do usuário ou de outros aplicativos no dispositivo.

Os usuários podem ver uma lista dos apps que foram armazenados em backup no Google Drive App Android. Em um dispositivo Android, os usuários podem encontrar essa lista no Google Drive. gaveta de navegação do app em Configurações > Fazer backup e redefinir.

Os backups de cada ciclo de vida de configuração do dispositivo são armazenados em conjuntos de dados separados, conforme descrito nos exemplos abaixo:

  • Se o usuário tiver dois dispositivos, haverá um conjunto de dados de backup para cada dispositivo.

  • Se o usuário redefinir um dispositivo para a configuração original e configurá-lo com a na mesma conta, o backup é armazenado em um novo conjunto de dados. Os conjuntos de dados obsoletos serão automaticamente excluídos após um período de inatividade.

Programação do backup

Os backups ocorrem automaticamente quando todas as condições a seguir são atendidas:

  • O usuário ativou o backup no dispositivo. No Android 9, essa configuração está em Configurações > Sistema > Backup.
  • Pelo menos 24 horas se passaram desde o último backup.
  • O dispositivo está ocioso.
  • O dispositivo está conectado a uma rede Wi-Fi (se o usuário do dispositivo não tiver ativado e backups de dados móveis).

Na prática, essas condições ocorrem quase todas as noites, mas um dispositivo pode nunca fará backup (por exemplo, se ele nunca se conectar a uma rede). Para preservar a largura de banda da rede, o upload acontece somente se os dados do app forem alterados.

Durante o Backup automático, o sistema desliga o app para garantir que ele não esteja mais gravação no sistema de arquivos. Por padrão, o sistema de backup ignora aplicativos que não estejam sendo executados em primeiro plano para evitar uma experiência ruim para o usuário. É possível substituir o comportamento padrão definindo o atributo android:backupInForeground como verdade.

Para simplificar o teste, o Android inclui ferramentas que permitem iniciar manualmente um backup do app. Para mais informações, consulte Testar backup e restauração.

Programação de restauração

Os dados são restaurados sempre que o app é instalado, seja da Play Store, durante a configuração do dispositivo (quando o sistema instala aplicativos previamente instalados) ou executando adb instalação. A operação de restauração ocorre após a instalação do APK mas antes de o app ficar disponível para ser iniciado pelo usuário.

Durante a execução do assistente de configuração inicial do dispositivo, o usuário encontrará uma lista de conjuntos de dados de backup disponíveis pedindo que ele escolha qual deles será usado para restaurar os dados. O conjunto de dados de backup selecionado se torna o conjunto de dados ancestral do dispositivo. O dispositivo pode ser restaurado usando os próprios backups ou o conjunto de dados ancestral. Se os backups de se as duas fontes estiverem disponíveis, o dispositivo vai priorizar o próprio backup. Se o usuário não tiver passado pelo assistente de configuração, o dispositivo só poderá ser restaurado usando os próprios backups.

Para simplificar o teste, o Android inclui ferramentas que permitem iniciar manualmente uma restauração do app. Para mais informações, consulte Testar backup e restauração.

Ativar e desativar o backup

Os apps voltados para o Android 6.0 (API de nível 23) ou versão mais recente são incluídos automaticamente no Backup automático. No arquivo de manifesto do app, defina o valor booleano android:allowBackup para ativar ou desativar o backup. O valor padrão é true, mas recomendamos definir explicitamente o atributo no manifesto, conforme mostrado no exemplo abaixo:

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

Você pode desativar os backups definindo android:allowBackup como false. Faça isso se o app puder recriar o próprio estado usando outro mecanismo ou se ele processar informações confidenciais.

Incluir e excluir arquivos

Por padrão, o sistema faz backup de quase todos os dados dos apps. Para mais informações, consulte a seção sobre arquivos que são salvos em backup.

Esta seção mostra como definir regras XML personalizadas para controlar o que é salvo em backup. Caso o app seja destinado ao Android 12 (nível 31 da API) ou versões mais recentes, especifique um conjunto adicional de regras de backup em XML, conforme descrito nesta seção, para Compatibilidade com as mudanças na restauração de backup introduzidas nos dispositivos que executam essas versões do Android.

Controlar o backup no Android 11 e em versões anteriores

Siga as etapas desta seção para controlar quais arquivos são salvos em backup nos dispositivos. com o Android 11 (nível 30 da API) ou uma versão anterior.

  1. No arquivo AndroidManifest.xml, adicione o atributo android:fullBackupContent ao elemento <application>, conforme mostrado no exemplo abaixo. Esse atributo aponta para um arquivo XML que contém regras de backup.

    <application ...
     android:fullBackupContent="@xml/backup_rules">
    </application>
  2. Crie um arquivo XML com o nome @xml/backup_rules no diretório res/xml/. Nesse arquivo, adicione regras com os elementos <include> e <exclude>. O exemplo abaixo faz backup de todas as preferências compartilhadas, exceto 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>

Definir as condições do dispositivo necessárias para backup

Se o app salvar informações sensíveis no dispositivo, você poderá especificar as condições em que os dados do app serão incluídos no backup do usuário. Você pode Adicione as condições abaixo no Android 9 (nível 28 da API) ou versões mais recentes:

Se você fez upgrade dos seus dispositivos de desenvolvimento para o Android 9, será necessário desativar e reativar o backup de dados depois do upgrade. Isso ocorre porque o Android só criptografa os backups com um segredo do lado do cliente depois de informar os usuários nas configurações ou no assistente de configuração.

Para declarar as condições de inclusão, defina o atributo requireFlags como uma os valores escolhidos ou os valores nos elementos <include> do conjunto de backup regras:

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>

Se o app implementar um sistema de backup de chave-valor ou se você implementar BackupAgent, também será possível aplicar esses requisitos condicionais à lógica de backup realizando uma comparação bit a bit entre um conjunto de flags de transporte de um objeto BackupDataOutput e as flags FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED ou FLAG_DEVICE_TO_DEVICE_TRANSFER do agente de backup personalizado.

O snippet de código a seguir mostra um exemplo de uso desse método:

Kotlin

class CustomBackupAgent : 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 CustomBackupAgent 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.
}

Controlar o backup no Android 12 ou mais recente

Caso o app seja direcionado ao Android 12 (nível 31 da API) ou versões mais recentes, siga as etapas desta seção para controlar quais arquivos são salvos em backup em dispositivos com o Android 12 ou versões mais recentes.

  1. No seu arquivo AndroidManifest.xml, adicione o Atributo android:dataExtractionRules ao <application> , como mostrado no exemplo a seguir. Esse atributo aponta para um arquivo XML que contém regras de backup.

    <application ...
     android:dataExtractionRules="backup_rules.xml">
    </application>
  2. Crie um arquivo XML com o nome backup_rules.xml no diretório res/xml/. Nesse arquivo, adicione regras com os elementos <include> e <exclude>. O exemplo abaixo faz backup de todas as preferências compartilhadas, exceto device.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <data-extraction-rules>
     <cloud-backup [disableIfNoEncryptionCapabilities="true|false"]>
       <include domain="sharedpref" path="."/>
       <exclude domain="sharedpref" path="device.xml"/>
     </cloud-backup>
    </data-extraction-rules>

Sintaxe de configuração XML

A sintaxe XML para o arquivo de configuração varia de acordo com a versão do Android em que o app é direcionado e está sendo executado.

Android 11 ou versão anterior

Use a seguinte sintaxe XML para o arquivo de configuração que controla o backup para dispositivos com o Android 11 ou versões anteriores.

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

Android 12 ou versão mais recente

Caso o app seja direcionado ao Android 12 (nível 31 da API) ou versões mais recentes, use a sintaxe XML mostrada abaixo para o arquivo de configuração que controla o backup em dispositivos com o Android 12 ou versões mais recentes.

<data-extraction-rules>
  <cloud-backup [disableIfNoEncryptionCapabilities="true|false"]>
    ...
    <include domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
    <exclude domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
  </cloud-backup>
  <device-transfer>
    ...
    <include domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
    <exclude domain=["file" | "database" | "sharedpref" | "external" |
                     "root" | "device_file" | "device_database" |
                     "device_sharedpref" | "device_root" ] path="string"/>
    ...
  </device-transfer>
</data-extraction-rules>

Cada seção da configuração (<cloud-backup>, <device-transfer>) contém regras que se aplicam apenas a esse tipo de transferência. Essa separação permite você, por exemplo, exclui um arquivo ou diretório dos backups do Google Drive enquanto ainda o transferir durante transferências entre dispositivos (D2D). Isso é útil se você tem arquivos muito grandes para fazer backup na nuvem, mas que podem ser transferidos entre dispositivos sem problemas.

Se não houver regras para um modo de backup específico, como se o A seção <device-transfer> está ausente. Esse modo está totalmente ativado para todos exceto para os diretórios no-backup e cache, conforme descrito no Seção Arquivos que são salvos em backup.

O app pode definir a sinalização disableIfNoEncryptionCapabilities na seção <cloud-backup> para garantir que o backup aconteça apenas se puder ser criptografado, como quando o usuário tem uma tela de bloqueio. A definição dessa restrição impede que os backups sejam enviados à nuvem se o dispositivo do usuário não oferecer suporte à criptografia. Porém, como as transferências D2D não são enviadas ao servidor, elas continuam funcionando até mesmo em dispositivos sem suporte à criptografia.

Sintaxe para os elementos "incluir" e "excluir"

Dentro das tags <full-backup-content>, <cloud-backup> e <device-transfer>, dependendo da versão do Android do dispositivo e da targetSDKVersion do app, é possível definir os elementos <include> e <exclude>:

<include>

Especifica um arquivo ou uma pasta para ser salva em backup. Por padrão, o Backup automático inclui quase todos os arquivos dos apps. Se você especificar um elemento <include>, o sistema não incluirá mais arquivos por padrão e fará o backup somente dos arquivos especificados. Para incluir vários arquivos, use vários elementos <include>.

No Android 11 e versões anteriores, esse elemento também pode conter o atributo requireFlags, discutido em mais detalhes na seção que descreve como definir requisitos condicionais para backup.

Os arquivos nos diretórios retornados por getCacheDir(), getCodeCacheDir() ou getNoBackupFilesDir() são sempre excluídos, mesmo que você tente incluí-los.

<exclude>

Especifica um arquivo ou uma pasta a serem excluídos do backup. Confira alguns arquivos que normalmente são excluídos do backup:

  • Arquivos que têm identificadores específicos do dispositivo, emitidos por um servidor ou gerados no dispositivo. Por exemplo, o Firebase Cloud Messaging (FCM) precisa gerar um token de registro toda vez que um usuário instala o app em um novo dispositivo. Se o token de registro antigo for for restaurado, o app poderá se comportar de maneira inesperada.

  • Arquivos relacionados à depuração do app.

  • Arquivos grandes que fazem com que o app exceda a cota de backup de 25 MB.

Cada elemento <include> e <exclude> precisa incluir os dois atributos a seguir:

domain

Especifica o local do recurso. Valores válidos para este atributo incluem o seguinte:

  • root: o diretório no sistema de arquivos em que todos os arquivos particulares que pertencem a este app são armazenados.
  • file: diretórios retornados por getFilesDir().
  • database: diretórios retornados por getDatabasePath(). Os bancos de dados criados com SQLiteOpenHelper são armazenados aqui.
  • sharedpref: o diretório em que SharedPreferences são armazenados.
  • external: o diretório retornado por getExternalFilesDir().
  • device_root: semelhante a root, mas para o armazenamento protegido pelo dispositivo.
  • device_file: semelhante a file, mas para o armazenamento protegido pelo dispositivo.
  • device_database: semelhante a database, mas para o armazenamento protegido pelo dispositivo.
  • device_sharedpref: semelhante a sharedpref, mas para o armazenamento protegido pelo dispositivo.
path

Especifica um arquivo ou uma pasta a serem incluídos ou excluídos do backup. Observe o seguinte:

  • Esse atributo não oferece suporte à sintaxe de caractere curinga ou expressão regular.
  • É possível referenciar o diretório atual usando ./, mas não é possível referenciar o diretório pai, usando .., por motivos de segurança.
  • Se você especificar um diretório, a regra se aplicará a todos os arquivos que estiverem nele e nos subdiretórios recursivos.

Implementar o BackupAgent

Os apps que implementam o Backup automático não precisam implementar um BackupAgent. No entanto, você tem a opção de implementar um BackupAgent personalizado. Normalmente, há duas razões para fazer isso:

  • Você deseja receber notificações de eventos de backup, como onRestoreFinished() e onQuotaExceeded(long, long). Esses métodos de callback são executados mesmo que o app não esteja em execução.

  • Você não consegue expressar com facilidade o conjunto de arquivos que quer armazenar em backup usando regras XML. Nesses casos raros, é possível implementar um BackupAgent que substitui onFullBackup(FullBackupDataOutput) para armazenar o que você quer. Para reter a implementação padrão do sistema, chame o método correspondente na superclasse com super.onFullBackup().

Se você implementar um BackupAgent, o sistema esperará, por padrão, que o app faça o backup e a restauração de chave-valor. Usar o Backup automático baseado em arquivos: Em vez disso, defina o atributo android:fullBackupOnly como true nas manifesto do app.

Durante as operações automáticas de backup e restauração, o sistema inicia o app em um modo restrito para evitar que ele acesse arquivos que possam causar conflitos e permitir que o app execute métodos de callback no BackupAgent. Nesse modo restrito, a atividade principal do app não é iniciada automaticamente, os provedores de conteúdo não são inicializados e a classe básica Application é instanciada em vez de qualquer subclasse declarada no manifesto do app.

Seu BackupAgent precisa implementar os métodos abstratos onBackup() e onRestore(), que são usados para o backup de chave-valor. Se você não quiser fazer backup de chave-valor, poderá deixar a implementação desses métodos em branco.

Para mais informações, consulte Estender o BackupAgent.