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

O Backup automático para apps faz backup dos dados do usuário automaticamente a partir de apps segmentados para Android 6.0 (API nível 23) ou posterior. O Android preserva os dados do app fazendo upload para o Google Drive do usuário, onde ficam protegidos pelas credenciais da Conta do Google do usuário. A quantidade de dados é limitada a 25 MB por usuário do app, e não há custos para armazenar os dados de backup. Seu app pode personalizar o processo de backup ou recusá-lo desativando os backups.

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

Para ver sobre como configurar o Backup automático, consulte também o codelab Backup automático para o Android (em inglês).

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 arquivos em diretórios retornados por getCacheDir(), getCodeCacheDir() ou getNoBackupFilesDir(). Os arquivos salvos nesses locais são necessários apenas temporariamente ou são excluídos intencionalmente das operações de backup.

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

Observação: o Android não trata a configuração de componentes como dados do usuário. Caso seu app ative ou desative componentes específicos no manifesto enquanto está em execução, o Backup automático não salvará nem restaurará a configuração. Para preservar o estado de configuração, salve-o em "Preferências compartilhadas" e recupere essas preferências durante a restauração. Se você quiser que seu app salve o estado, armazene-o em Preferências compartilhadas e recupere essas preferências durante a restauração.

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, o backup anterior (se existir) é excluído. Os dados de backup não podem ser lidos pelo usuário ou por outros apps do dispositivo.

O usuário pode ver uma lista dos apps que foram armazenados em backup no app para Android Google Drive. Em um dispositivo com Android, o usuário pode encontrar essa lista na gaveta de navegação do app Drive em Configurações > Fazer backup e redefinir > Dados do app.

Os backups de cada ciclo de vida de configuração de dispositivo são armazenados em conjuntos de dados separados, conforme mostrado nos exemplos a seguir:

  • Se o usuário tem dois dispositivos, há um conjunto de dados de backup para cada dispositivo.
  • Se o usuário redefine um dispositivo para a configuração original e, em seguida, configura o dispositivo com a mesma conta, o backup é armazenado em um novo conjunto de dados. Os conjuntos de dados obsoletos sã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 os backups com dados móveis).

Na prática, essas condições ocorrem aproximadamente todas as noites, mas um dispositivo pode nunca fazer 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 são alterados.

Durante o Backup automático, o sistema desliga o app para garantir que ele não esteja mais gravando no sistema de arquivos. Por padrão, o sistema de backup ignora os apps que estão sendo executados em primeiro plano porque os usuários notariam que os apps estão sendo desligados. É possível modificar o comportamento padrão definindo o atributo backupInForeground como verdadeiro.

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

Programação de restauração

Os dados são restaurados sempre que o app é instalado, seja pela Play Store, durante a configuração do dispositivo (quando o sistema instala os apps instalados anteriormente) ou na instalação do adb. A operação de restauração ocorre depois que o APK é instalado, mas antes que o app esteja disponível para ser iniciado pelo usuário.

Durante a execução do assistente de configuração inicial do dispositivo, uma lista de conjuntos de dados de backup disponíveis é mostrada para o usuário, e é solicitado que ele escolha a partir de qual deles os dados devem ser restaurados. O conjunto de dados de backup selecionado se torna o conjunto de dados ancestral do dispositivo. O dispositivo pode ser restaurado a partir dos próprios backups ou do conjunto de dados ancestral. O dispositivo prioriza o próprio backup se backups das duas fontes estiverem disponíveis. Se o usuário não tiver passado pelo assistente de configuração, o dispositivo só poderá ser restaurado a partir dos 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 o backup e a restauração.

Ativar e desativar o backup

Os apps segmentados para o Android 6.0 (API nível 23) ou posterior participam automaticamente do 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 para deixar suas intenções claras, recomendamos que você configure explicitamente o atributo no manifesto, conforme mostrado abaixo:

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

Você pode desativar os backups definindo android:allowBackup como false. Faça isso se seu app puder recriar o próprio estado por meio de outro mecanismo ou se ele processar informações confidenciais que não devam ser armazenadas em backup pelo Android.

Incluir e excluir arquivos

Por padrão, o sistema faz backup de quase todos os dados dos apps. Para ver mais informações, consulte Arquivos que são salvos em backup. Esta seção mostra como definir regras XML personalizadas para controlar o que é salvo em backup.

  1. Em AndroidManifest.xml, adicione o atributo android:fullBackupContent ao elemento <application>. Esse atributo aponta para um XML file que contém regras de backup. Por exemplo:
        <application ...
            android:fullBackupContent="@xml/my_backup_rules">
        </application>
        
  2. Crie um XML file denominado my_backup_rules.xml no diretório res/xml/. Dentro do arquivo, adicione regras com os elementos <include> e <exclude>. A amostra a seguir 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>
        

Sintaxe de configuração XML

A sintaxe XML para o arquivo de configuração é mostrada abaixo:

    <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 da tag <full-backup-content>, é possível definir os elementos <include> e <exclude>:

  • <include>: especifica um arquivo ou uma pasta para o 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 nenhum arquivo por padrão e fará backup somente dos arquivos especificados. Para incluir vários arquivos, use diversos elementos <include>.

    Observação: 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 durante o backup. Veja alguns arquivos que costumam ser excluídos do backup:
    • Arquivos que têm identificadores específicos de dispositivo, emitidos por um servidor ou gerados no dispositivo. Por exemplo, o Google Cloud Messaging (GCM) precisa gerar um token de registro toda vez que um usuário instala seu app em um novo dispositivo. Se o token de registro antigo for restaurado, o app poderá ter um comportamento inesperado.
    • Credenciais de conta ou outras informações confidenciais. Recomendamos que você peça ao usuário para realizar a autenticação novamente na primeira vez que ele iniciar um app restaurado, em vez de permitir o armazenamento dessas informações no backup.
    • Arquivos relacionados à depuração do app.
    • Arquivos grandes que fazem o app exceder a cota de backup de 25 MB.

Observação: se seu arquivo de configuração especificar os dois elementos, o backup incluirá tudo o que for capturado pelos elementos <include>, exceto os recursos nomeados nos elementos <exclude>. Em outras palavras, <exclude> tem prioridade.

Cada elemento precisa incluir os dois atributos a seguir:

  • domain: especifica o local do recurso. Os valores válidos para esse atributo incluem:
    • root: o diretório no sistema de arquivos em que todos os arquivos particulares pertencentes ao 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 onde SharedPreferences são armazenadas.
    • external: o diretório retornado por getExternalFilesDir().
  • Observação: não é possível fazer backup de arquivos fora desses locais.

  • path: especifica um arquivo ou uma pasta a serem incluídos ou excluídos do backup. Algumas considerações:
    • Esse atributo não é compatível com a sintaxe de caractere curinga ou regex.
    • Você pode usar . para referenciar o diretório atual. No entanto, não é possível referenciar o diretório pai .. por motivos de segurança.
    • Se você especificar um diretório, a regra se aplicará a todos os arquivos que estiverem no diretório e nos subdiretórios recorrentes.

O elemento include também pode conter o atributo requiredFlags. Isso é descrito em mais detalhes na seção sobre como definir requisitos condicionais para o backup.

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

Se seu app salvar informações confidenciais no dispositivo, você poderá especificar as condições em que os dados do seu app serão incluídos no backup do usuário. Você pode adicionar as seguintes condições no Android 9 (API nível 28) ou versão posterior:

Se você fez upgrade dos seus dispositivos de desenvolvimento para o Android 9, é 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 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 com os valores que você quer usar nos elementos <include> dentro do conjunto de regras de backup:

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>
    

Se seu app implementa um sistema de backup de chave-valor ou se você implementa o BackupAgent, também é possível aplicar esses requisitos condicionais à lógica de backup fazendo uma comparação bit a bit entre um conjunto do objeto BackupDataOutput composto por sinalizações de transferência e as sinalizações FLAG_CLIENT_SIDE_ENCRYPTION_ENABLEDou FLAG_DEVICE_TO_DEVICE_TRANSFER do seu agente de backup personalizado.

O snippet de código a seguir mostra um exemplo de uso desse 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.
    }
    

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ê quer receber notificações de eventos de backup, como onRestoreFinished() ou 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 com regras XML. Nesses casos raros, é possível implementar um BackupAgent que modifique onFullBackup(FullBackupDataOutput) para armazenar o que você quer. Para manter a implementação padrão do sistema, chame o método correspondente na superclasse com super.onFullBackup().

Se você implementa um BackupAgent, o sistema espera, por padrão, que seu app faça backup e restauração de chave-valor. Para usar o Backup automático baseado em arquivo, defina o atributo android:fullBackupOnly como true no manifesto do seu app.

Durante as operações automáticas de backup e restauração, o sistema inicia o app em um modo restrito para evitar que o app acesse arquivos que possam causar conflitos e também que ele execute métodos de callback no BackupAgent. No 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.

Cuidado: para evitar erros, verifique se as partes do seu app que são executadas no modo restrito (principalmente o BackupAgent) não acessam provedores de conteúdo no mesmo app ou tentam transmitir o objeto Application. Se não for possível evitar esses padrões, implemente o Backup de chave-valor ou desative o backup completamente.

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

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

Outros recursos

Para ver mais informações sobre o Backup automático, consulte os recursos a seguir.

Codelabs