Esegui il backup dei dati utente con il backup automatico

Backup automatico per le app esegue automaticamente il backup dei dati di un utente dalle app che hanno come target e vengono eseguite su Android 6.0 (livello API 23) o versioni successive. Android conserva i dati dell'app caricandoli sul Google Drive dell'utente, dove sono protetti dalle credenziali dell'Account Google dell'utente. Il backup è protetto con crittografia end-to-end sui dispositivi con Android 9 o versioni successive utilizzando il PIN, la sequenza o la password del dispositivo. La quantità di dati è limitata a 25 MB per utente. Non è previsto alcun costo per l'archiviazione dei dati di backup. L'app può personalizzare la procedura di backup oppure disattivare i backup.

Per una panoramica delle opzioni di backup di Android e indicazioni su quali dati eseguire il backup e il ripristino, consulta la panoramica del backup dei dati.

File sottoposti a backup

Per impostazione predefinita, Backup automatico include i file nella maggior parte delle directory assegnate alla tua app dal sistema:

Il backup automatico esclude i file nelle directory restituite da getCacheDir(), getCodeCacheDir() e getNoBackupFilesDir(). I file salvati in queste posizioni sono necessari solo temporaneamente e sono esclusi intenzionalmente dalle operazioni di backup.

Puoi configurare l'app in modo da includere ed escludere determinati file. Per ulteriori informazioni, consulta la sezione Includi ed escludi file.

Posizione backup

I dati di backup sono archiviati in una cartella privata nell'account Google Drive dell'utente, limitatamente a 25 MB per app. I dati salvati non sono inclusi nel calcolo della quota di spazio di archiviazione personale di Google Drive dell'utente. Viene archiviato solo il backup più recente. Quando viene eseguito un backup, qualsiasi backup precedente viene eliminato. I dati di backup non possono essere letti dall'utente o da altre app sul dispositivo.

Gli utenti possono visualizzare un elenco delle app di cui è stato eseguito il backup nell'app Google Drive per Android. Sui dispositivi Android, gli utenti possono trovare l'elenco nel riquadro di navigazione a scomparsa dell'app Drive in Impostazioni > Backup e ripristino.

I backup per ogni durata della configurazione del dispositivo vengono archiviati in set di dati separati, come descritto nei seguenti esempi:

  • Se l'utente è proprietario di due dispositivi, per ognuno esiste un set di dati di backup.

  • Se l'utente ripristina i dati di fabbrica di un dispositivo e poi configura quest'ultimo con lo stesso account, il backup viene archiviato in un nuovo set di dati. I set di dati obsoleti vengono eliminati automaticamente dopo un periodo di inattività.

Programmazione backup

I backup vengono eseguiti automaticamente quando sono soddisfatte tutte le seguenti condizioni:

  • L'utente ha attivato il backup sul dispositivo. In Android 9, questa impostazione si trova in Impostazioni > Sistema > Backup.
  • Sono trascorse almeno 24 ore dall'ultimo backup.
  • Il dispositivo è inattivo.
  • Il dispositivo sia collegato a una rete Wi-Fi (se l'utente non ha attivato i backup con dati mobili).

In pratica, queste condizioni si verificano all'incirca ogni notte, ma un dispositivo potrebbe non eseguire mai il backup (ad esempio se non si connette mai a una rete). Per conservare la larghezza di banda della rete, il caricamento viene eseguito solo se i dati dell'app sono stati modificati.

Durante il backup automatico, il sistema arresta l'app per assicurarsi che non stia più scrivendo nel file system. Per impostazione predefinita, il sistema di backup ignora le app in esecuzione in primo piano per evitare un'esperienza utente scadente. Puoi ignorare il comportamento predefinito impostando l'attributo android:backupInForeground su true.

Per semplificare i test, Android include strumenti che ti consentono di avviare manualmente un backup della tua app. Per ulteriori informazioni, consulta la pagina Testare backup e ripristino.

Pianificazione ripristino

I dati vengono ripristinati ogni volta che l'app viene installata, dal Play Store, durante la configurazione del dispositivo (quando il sistema installa app installate in precedenza) o eseguendo l'installazione di adb. L'operazione di ripristino avviene dopo l'installazione dell'APK, ma prima che l'app diventi disponibile per l'avvio da parte dell'utente.

Durante la configurazione guidata iniziale del dispositivo, all'utente viene mostrato un elenco dei set di dati di backup disponibili e gli viene chiesto da quale ripristinare i dati. Qualsiasi set di dati di backup selezionato diventa il set di dati ancestrale del dispositivo. Il dispositivo può eseguire il ripristino dai propri backup o dal set di dati ancestrale. Se sono disponibili backup da entrambe le origini, il dispositivo dà priorità al proprio backup. Se l'utente non ha eseguito la configurazione guidata del dispositivo, il dispositivo può eseguire il ripristino solo dai propri backup.

Per semplificare i test, Android include strumenti che ti consentono di avviare manualmente un ripristino dell'app. Per ulteriori informazioni, consulta la pagina Testare backup e ripristino.

Abilita e disabilita il backup

Le app destinate ad Android 6.0 (livello API 23) o versioni successive partecipano automaticamente al backup automatico. Nel file manifest dell'app, imposta il valore booleano android:allowBackup per attivare o disattivare il backup. Il valore predefinito è true, ma ti consigliamo di impostare esplicitamente l'attributo nel file manifest, come mostrato nell'esempio seguente:

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

Puoi disattivare i backup impostando android:allowBackup su false. Potresti voler eseguire questa operazione se la tua app è in grado di ricreare il suo stato tramite altri meccanismi o se la tua app tratta informazioni sensibili.

Includi ed escludi file

Per impostazione predefinita, il sistema esegue il backup di quasi tutti i dati dell'app. Per ulteriori informazioni, consulta la sezione sui file di cui viene eseguito il backup.

Questa sezione mostra come definire regole XML personalizzate per controllare gli elementi di cui viene eseguito il backup. Se la tua app ha come target Android 12 (livello API 31) o versioni successive, devi specificare un set aggiuntivo di regole di backup XML, come descritto in questa sezione, per supportare le modifiche al ripristino del backup introdotte per i dispositivi che eseguono queste versioni di Android.

Controllare il backup su Android 11 e versioni precedenti

Segui i passaggi in questa sezione per controllare di quali file viene eseguito il backup sui dispositivi con Android 11 (livello API 30) o versioni precedenti.

  1. Nel file AndroidManifest.xml, aggiungi l'attributo android:fullBackupContent all'elemento <application>, come mostrato nell'esempio seguente. Questo attributo rimanda a un file XML contenente le regole di backup.

    <application ...
     android:fullBackupContent="@xml/backup_rules">
    </application>
    
  2. Crea un file XML denominato @xml/backup_rules nella directory res/xml/. In questo file, aggiungi le regole con gli elementi <include> e <exclude>. Il seguente esempio esegue il backup di tutte le preferenze condivise tranne 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>
    

Definisci le condizioni del dispositivo necessarie per il backup

Se la tua app salva informazioni sensibili sul dispositivo, puoi specificare le condizioni in cui i dati dell'app sono inclusi nel backup dell'utente. Puoi aggiungere le seguenti condizioni in Android 9 (livello API 28) o versioni successive:

Se hai eseguito l'upgrade dei dispositivi di sviluppo ad Android 9, devi disattivare e riattivare il backup dei dati dopo l'upgrade. Questo perché Android cripta i backup con un secret lato client solo dopo aver informato gli utenti in Impostazioni o nella configurazione guidata.

Per dichiarare le condizioni di inclusione, imposta l'attributo requireFlags su uno o più valori scelti negli elementi <include> all'interno dell'insieme di regole di backup:

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 la tua app implementa un sistema di backup chiave-valore o se implementi BackupAgent autonomamente, puoi anche applicare questi requisiti condizionali alla logica di backup eseguendo un confronto bit a bit tra l'insieme di flag di trasporto di un oggetto BackupDataOutput e i flag FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED o FLAG_DEVICE_TO_DEVICE_TRANSFER dell'agente di backup personalizzato.

Lo snippet di codice riportato di seguito mostra un esempio di utilizzo di questo metodo:

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.
}

Controllare il backup su Android 12 o versioni successive

Se la tua app ha come target Android 12 (livello API 31) o versioni successive, segui i passaggi in questa sezione per controllare quali file vengono sottoposti a backup sui dispositivi con Android 12 o versioni successive.

  1. Nel file AndroidManifest.xml, aggiungi l'attributo android:dataExtractionRules all'elemento <application>, come mostrato nell'esempio seguente. Questo attributo rimanda a un file XML contenente le regole di backup.

    <application ...
     android:dataExtractionRules="backup_rules.xml">
    </application>
    
  2. Crea un file XML denominato backup_rules.xml nella directory res/xml/. In questo file, aggiungi le regole con gli elementi <include> e <exclude>. Il seguente esempio esegue il backup di tutte le preferenze condivise tranne 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>
    

Sintassi di configurazione XML

La sintassi XML del file di configurazione varia a seconda della versione di Android su cui è in esecuzione la tua app.

Android 11 o versioni precedenti

Utilizza la seguente sintassi XML per il file di configurazione che controlla il backup per i dispositivi con Android 11 o versioni precedenti.

<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 o versioni successive

Se la tua app ha come target Android 12 (livello API 31) o versioni successive, utilizza la seguente sintassi XML per il file di configurazione che controlla il backup per i dispositivi con Android 12 o versioni successive.

<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>

Ogni sezione della configurazione (<cloud-backup>, <device-transfer>) contiene regole che si applicano solo a quel tipo di trasferimento. Questa separazione consente, ad esempio, di escludere un file o una directory dai backup di Google Drive continuando a trasferirli durante i trasferimenti da dispositivo a dispositivo (D2D). Ciò è utile se hai file troppo grandi per il backup sul cloud, ma che possono essere trasferiti da un dispositivo all'altro senza problemi.

Se non sono presenti regole per una determinata modalità di backup, ad esempio se manca la sezione <device-transfer>, tale modalità viene attivata completamente per tutti i contenuti tranne per le directory no-backup e cache, come descritto nella sezione File di cui è stato eseguito il backup.

La tua app può impostare il flag disableIfNoEncryptionCapabilities nella sezione <cloud-backup> per assicurarti che il backup venga eseguito solo se può essere criptato, ad esempio quando l'utente ha una schermata di blocco. L'impostazione di questo vincolo interrompe l'invio dei backup al cloud se il dispositivo dell'utente non supporta la crittografia. Tuttavia, poiché i trasferimenti D2D non vengono inviati al server, continuano a funzionare anche su dispositivi che non supportano la crittografia.

Sintassi per gli elementi di inclusione ed esclusione

Nei tag <full-backup-content>, <cloud-backup> e <device-transfer> (a seconda della versione di Android del dispositivo e dell'app targetSDKVersion), puoi definire gli elementi <include> e <exclude>:

<include>

Specifica un file o una cartella di cui eseguire il backup. Per impostazione predefinita, Backup automatico include quasi tutti i file delle app. Se specifichi un elemento <include>, per impostazione predefinita il sistema non include più alcun file ed esegue il backup solo dei file specificati. Per includere più file, utilizza più elementi <include>.

Su Android 11 e versioni precedenti, questo elemento può contenere anche l'attributo requireFlags, di cui la sezione che descrive come definire i requisiti condizionali per il backup viene descritta in maggiore dettaglio.

I file nelle directory restituite da getCacheDir(), getCodeCacheDir() o getNoBackupFilesDir() vengono sempre esclusi anche se tenti di includerli.

<exclude>

Specifica un file o una cartella da escludere durante il backup. Ecco alcuni file che in genere vengono esclusi dal backup:

  • File con identificatori specifici del dispositivo, emessi da un server o generati sul dispositivo. Ad esempio, Firebase Cloud Messaging (FCM) deve generare un token di registrazione ogni volta che un utente installa la tua app su un nuovo dispositivo. Se viene ripristinato il token di registrazione precedente, l'app potrebbe comportarsi in modo imprevisto.

  • File relativi al debug delle app.

  • File di grandi dimensioni, che causano il superamento della quota di backup di 25 MB da parte dell'app.

Ogni elemento <include> e <exclude> deve includere i seguenti due attributi:

domain

Specifica la località della risorsa. I valori validi per questo attributo includono:

  • root: la directory del file system in cui sono archiviati tutti i file privati appartenenti all'app.
  • file: directory restituite da getFilesDir().
  • database: directory restituite da getDatabasePath(). I database creati con SQLiteOpenHelper vengono archiviati qui.
  • sharedpref: la directory in cui sono archiviati SharedPreferences.
  • external: la directory restituita da getExternalFilesDir().
  • device_root: come root ma per l'archiviazione protetta dal dispositivo.
  • device_file: come file ma per l'archiviazione protetta dal dispositivo.
  • device_database: come database ma per l'archiviazione protetta dal dispositivo.
  • device_sharedpref: come sharedpref ma per lo spazio di archiviazione protetto dal dispositivo.
path

Specifica un file o una cartella da includere nel backup o da escludere. Tieni presente quanto segue:

  • Questo attributo non supporta la sintassi con caratteri jolly o espressioni regolari.
  • Puoi fare riferimento alla directory corrente utilizzando ./, ma non puoi fare riferimento alla directory padre, ad esempio utilizzando .., per motivi di sicurezza.
  • Se specifichi una directory, la regola si applica a tutti i file al suo interno e alle sottodirectory ricorsive.

Implementare BackupAgent

Per le app che implementano il backup automatico non è necessario implementare BackupAgent. Tuttavia, se vuoi, puoi implementare un BackupAgent personalizzato. In genere, ci sono due motivi per farlo:

  • Vuoi ricevere una notifica relativa a eventi di backup, ad esempio onRestoreFinished() e onQuotaExceeded(long, long). Questi metodi di callback vengono eseguiti anche se l'app non è in esecuzione.

  • Non puoi indicare facilmente l'insieme di file di cui vuoi eseguire il backup con le regole XML. In questi rari casi, puoi implementare un BackupAgent che sostituisca onFullBackup(FullBackupDataOutput) per archiviare ciò che vuoi. Per mantenere l'implementazione predefinita del sistema, chiama il metodo corrispondente nella superclasse con super.onFullBackup().

Se implementi un oggetto BackupAgent, per impostazione predefinita il sistema si aspetta che l'app esegua backup e ripristino delle coppie chiave-valore. Per utilizzare invece il backup automatico basato su file, imposta l'attributo android:fullBackupOnly su true nel file manifest della tua app.

Durante le operazioni di backup e ripristino automatico, il sistema avvia l'app in modalità con restrizioni per impedire all'app di accedere ai file che potrebbero causare conflitti e per consentire all'app di eseguire metodi di callback in BackupAgent. In questa modalità con restrizioni, l'attività principale dell'app non viene avviata automaticamente, i relativi fornitori di contenuti non vengono inizializzati e viene creata un'istanza della classe base Application anziché di una sottoclasse dichiarata nel file manifest dell'app.

BackupAgent deve implementare i metodi astratti onBackup() e onRestore(), utilizzati per il backup delle coppie chiave-valore. Se non vuoi eseguire il backup delle coppie chiave-valore, puoi lasciare vuota l'implementazione di questi metodi.

Per ulteriori informazioni, consulta Extend BackupAgent.