Tworzenie kopii zapasowej danych użytkowników przy użyciu Automatycznej kopii zapasowej

Automatyczna kopia zapasowa aplikacji automatycznie tworzy kopie zapasowe danych użytkownika z aplikacji, które są kierowane na Androida 6.0 (poziom interfejsu API 23) lub nowszego. Android zachowuje dane aplikacji, przesyłając je na Dysk Google użytkownika, gdzie są chronione przez jego dane logowania do konta Google. Kopie zapasowe są szyfrowane od końca do końca na urządzeniach z Androidem 9 lub nowszym za pomocą kodu PIN, wzoru lub hasła urządzenia. Każda aplikacja może przydzielić do 25 MB danych kopii zapasowej na użytkownika. Przechowywanie danych kopii zapasowej jest bezpłatne. Aplikacja może dostosować proces tworzenia kopii zapasowej lub zrezygnować z niego, wyłączając tworzenie kopii zapasowych.

Informacje o opcjach tworzenia kopii zapasowych na urządzeniach z Androidem oraz wskazówki dotyczące tego, których danych używać do tworzenia kopii zapasowych i przywracania, znajdziesz w artykule Tworzenie kopii zapasowych danych.

Pliki, których kopia zapasowa jest tworzona

Domyślnie Automatyczna kopia zapasowa obejmuje pliki z większości katalogów przypisanych do aplikacji przez system:

Automatyczna kopia zapasowa wyklucza pliki w katalogach zwracanych przez getCacheDir(), getCodeCacheDir()getNoBackupFilesDir(). Pliki zapisane w tych lokalizacjach są potrzebne tylko tymczasowo i są celowo wykluczone z operacji tworzenia kopii zapasowych.

Możesz skonfigurować aplikację, aby uwzględniała i wykluczała określone pliki. Więcej informacji znajdziesz w sekcji Uwzględniaj i wykluczaj pliki.

Lokalizacja kopii zapasowej

Dane kopii zapasowej są przechowywane w prywatnym folderze na koncie Dysku Google użytkownika. Ich rozmiar jest ograniczony do 25 MB na aplikację. Zapisane dane nie wliczają się do limitu miejsca na Dysku Google użytkownika. Zapisana jest tylko najnowsza kopia zapasowa. Po utworzeniu kopii zapasowej wszystkie poprzednie kopie zapasowe są usuwane. Dane kopii zapasowej nie mogą być odczytane przez użytkownika ani inne aplikacje na urządzeniu.

Użytkownicy mogą zobaczyć listę aplikacji, których dane zostały zarchiwizowane w aplikacji Dysk Google na Androida. Na urządzeniu z Androidem mogą znaleźć tę listę w drawerze nawigacji Dysku w sekcji Ustawienia > Kopia zapasowa i resetowanie.

Kopie zapasowe z każdego okresu konfiguracji urządzenia są przechowywane w oddzielnych zbiorach danych, jak opisano w tych przykładach:

  • Jeśli użytkownik ma 2 urządzenia, na każdym z nich znajduje się kopia zapasowa zbioru danych.

  • Jeśli użytkownik przywróci ustawienia fabryczne urządzenia, a następnie skonfiguruje je przy użyciu tego samego konta, kopia zapasowa zostanie zapisana w nowym zbiorze danych. Nieaktualne zbiory danych są automatycznie usuwane po okresie nieaktywności.

Harmonogram tworzenia kopii zapasowej

Kopie zapasowe są tworzone automatycznie, gdy są spełnione wszystkie te warunki:

  • Użytkownik włączył kopię zapasową na urządzeniu. W Androidzie 9 to ustawienie znajduje się w sekcji Ustawienia > System > Kopia zapasowa.
  • od ostatniej kopii zapasowej upłynęło co najmniej 24 godziny.
  • Urządzenie jest nieaktywne.
  • Urządzenie jest połączone z siecią Wi-Fi (jeśli użytkownik nie zdecydował się na tworzenie kopii zapasowych za pomocą danych komórkowych).

W praktyce te warunki występują mniej więcej co noc, ale urządzenie może nigdy nie wykonać kopii zapasowej (na przykład, jeśli nigdy nie połączy się z siecią). Aby oszczędzać przepustowość sieci, przesyłanie odbywa się tylko wtedy, gdy dane aplikacji ulegną zmianie.

Podczas Automatycznej kopii zapasowej system wyłącza aplikację, aby upewnić się, że nie zapisuje już danych w systemie plików. Aby uniknąć problemów z wygodą użytkowników, system kopii zapasowej domyślnie ignoruje aplikacje działające w tle. Działanie domyślne możesz zastąpić, ustawiając wartość atrybutu android:backupInForeground na prawda.

Aby ułatwić testowanie, Android udostępnia narzędzia, które pozwalają ręcznie zainicjować kopię zapasową aplikacji. Więcej informacji znajdziesz w artykule Testowanie tworzenia i przywracania kopii zapasowej.

Przywracanie harmonogramu

Dane są przywracane za każdym razem, gdy aplikacja jest instalowana ze Sklepu Play, podczas konfiguracji urządzenia (gdy system instaluje wcześniej zainstalowane aplikacje) lub przez uruchomienie adb. Przywracanie następuje po zainstalowaniu pakietu APK, ale przed udostępnieniem aplikacji przez użytkownika.

W kreatorze wstępnej konfiguracji urządzenia użytkownik widzi listę dostępnych zbiorów danych kopii zapasowych i jest pytany, z którego ma zostać przywrócony dane. Wybrany zbiór danych kopii zapasowej stanie się zbiorem danych przodków na urządzeniu. Urządzenie może przywrócić dane z kopii zapasowych lub z danych przodków. Jeśli kopie zapasowe z obu źródeł są dostępne, urządzenie traktuje jako priorytet własną kopię zapasową. Jeśli użytkownik nie przeszedł przez kreatora konfiguracji urządzenia, urządzenie może przywrócić dane tylko z własnych kopii zapasowych.

Aby uprościć testowanie, Android zawiera narzędzia, które umożliwiają ręczne zainicjowanie przywracania aplikacji. Więcej informacji znajdziesz w artykule Testowanie tworzenia i przywracania kopii zapasowej.

Włączanie i wyłączanie kopii zapasowej

Aplikacje kierowane na Androida 6.0 (poziom interfejsu API 23) lub nowszego automatycznie korzystają z automatycznej kopii zapasowej. W pliku manifestu aplikacji ustaw wartość logiczną android:allowBackup, aby włączyć lub wyłączyć tworzenie kopii zapasowej. Wartość domyślna to true, ale zalecamy bezpośrednie ustawienie atrybutu w pliku manifestu, jak pokazano w poniższym przykładzie:

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

Możesz wyłączyć tworzenie kopii zapasowych, ustawiając wartość android:allowBackup na false. Możesz to zrobić, jeśli aplikacja może odtworzyć swój stan za pomocą innego mechanizmu lub jeśli aplikacja ma do czynienia z informacjami poufnymi.

Uwzględnianie i wykluczanie plików

Domyślnie system tworzy kopie zapasowe niemal wszystkich danych aplikacji. Więcej informacji znajdziesz w sekcji Pliki, których kopia zapasowa jest tworzona.

W tej sekcji dowiesz się, jak definiować niestandardowe reguły XML, aby kontrolować, co ma być kopiowane. Jeśli Twoja aplikacja jest kierowana na Androida 12 (API na poziomie 31) lub nowszego, musisz określić dodatkowy zestaw reguł XML kopii zapasowej zgodnie z opisem w tej sekcji, aby obsługiwać zmiany w przywracaniu kopii zapasowej wprowadzone na urządzeniach z tymi wersjami Androida.

Kontrolowanie kopii zapasowej na Androidzie 11 i starszych

Aby określić, które pliki mają być kopiowane na urządzeniach z Androidem 11 (poziom interfejsu API 30) lub starszym, wykonaj czynności opisane w tej sekcji.

  1. W pliku AndroidManifest.xml dodaj atrybut android:fullBackupContent do elementu <application>, jak pokazano w tym przykładzie. Ten atrybut wskazuje plik XML zawierający reguły kopii zapasowej.

    <application ...
     android:fullBackupContent="@xml/backup_rules">
    </application>
    
  2. Utwórz w katalogu res/xml/ plik XML o nazwie @xml/backup_rules. W tym pliku dodaj reguły za pomocą elementów <include><exclude>. Ten przykładowy skrypt tworzy kopie zapasowe wszystkich udostępnionych preferencji z wyjątkiem 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>
    

Określ warunki urządzenia wymagane do utworzenia kopii zapasowej

Jeśli aplikacja zapisuje na urządzeniu informacje poufne, możesz określić warunki, na jakich dane aplikacji są uwzględniane w kopii zapasowej użytkownika. W Androidzie 9 (poziom interfejsu API 28) lub nowszym możesz dodać te warunki:

Jeśli urządzenia do tworzenia aplikacji zostały uaktualnione do Androida 9, po uaktualnieniu musisz wyłączyć, a następnie ponownie włączyć tworzenie kopii zapasowej danych. Dzieje się tak, ponieważ Android szyfruje kopie zapasowe za pomocą obiektu tajnego po stronie klienta po tym, jak użytkownik o tym poinformuje w Ustawieniach lub w kreatorze konfiguracji.

Aby zadeklarować warunki uwzględniania, ustaw atrybut requireFlags na wybraną wartość lub wybrane wartości w elementach <include> w zestawie reguł zapasowych:

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

Jeśli Twoja aplikacja implementuje system kopii zapasowej klucz-wartość lub jeśli implementujeszBackupAgent samodzielnie, możesz też zastosować te wymagania warunkowe do logiki kopii zapasowej, wykonując porównanie bitowe między zestawem flag transportu obiektu BackupDataOutput a flagami FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED lub FLAG_DEVICE_TO_DEVICE_TRANSFER niestandardowego agenta kopii zapasowej.

Fragment kodu ilustruje przykład użycia tej metody:

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

Zarządzanie kopią zapasową na Androidzie 12 lub nowszym

Jeśli Twoja aplikacja jest kierowana na Androida 12 (poziom API 31) lub nowszego, wykonaj czynności opisane w tej sekcji, aby określić, które pliki mają być kopiowane na urządzeniach z Androidem 12 lub nowszym.

  1. W pliku AndroidManifest.xml dodaj do elementu <application> atrybut android:dataExtractionRules zgodnie z poniższym przykładem. Ten atrybut wskazuje plik XML zawierający reguły kopii zapasowej.

    <application ...
     android:dataExtractionRules="backup_rules.xml">
    </application>
    
  2. Utwórz w katalogu res/xml/ plik XML o nazwie backup_rules.xml. W tym pliku dodaj reguły za pomocą elementów <include><exclude>. Ten przykład tworzy kopię zapasową wszystkich ustawień udostępnionych oprócz 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>
    

Składnia konfiguracji XML

Składnia XML pliku konfiguracyjnego różni się w zależności od wersji Androida, na którą jest kierowana i na której działa Twoja aplikacja.

Android 11 lub starszy

Użyj tej składni XML w pliku konfiguracji, który kontroluje tworzenie kopii zapasowej na urządzeniach z Androidem 11 lub starszym.

<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 lub nowszy.

Jeśli Twoja aplikacja jest kierowana na Androida 12 (poziom interfejsu API 31) lub nowszego, użyj tej składni XML w pliku konfiguracji, który kontroluje tworzenie kopii zapasowej na urządzeniach z Androidem 12 lub nowszym.

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

Każda sekcja konfiguracji (<cloud-backup>, <device-transfer>) zawiera reguły, które mają zastosowanie tylko do danego typu transferu. Taki podział pozwala na przykład wykluczyć plik lub katalog z kopii zapasowych Dysku Google przy jednoczesnym jego przenoszeniu podczas przenoszenia między urządzeniami (D2D). Jest to przydatne, jeśli masz pliki, które są zbyt duże, aby utworzyć kopię zapasową w chmurze, ale można je bez problemu przenieść między urządzeniami.

Jeśli nie ma żadnych reguł dotyczących danego trybu tworzenia kopii zapasowej, np. brakuje sekcji <device-transfer>, ten tryb jest w pełni włączony dla wszystkich treści z wyjątkiem katalogów no-backupcache, zgodnie z opisem w sekcji Pliki, których kopie zapasowe są tworzone.

Aplikacja może ustawić flagę disableIfNoEncryptionCapabilities w sekcji <cloud-backup>, aby kopia zapasowa była tworzona tylko wtedy, gdy można ją zaszyfrować, np. gdy użytkownik ma ekran blokady. Ustawienie tego ograniczenia uniemożliwia wysyłanie kopii zapasowych do chmury, jeśli urządzenie użytkownika nie obsługuje szyfrowania, ale ponieważ transfery D2D nie są wysyłane na serwer, nadal działają nawet na urządzeniach, które nie obsługują szyfrowania.

Składnia elementów uwzględniania i wykluczania

W tagach <full-backup-content>, <cloud-backup><device-transfer> (w zależności od wersji Androida na urządzeniu i wersji aplikacji targetSDKVersion) możesz zdefiniować elementy <include><exclude>:

<include>

Określa plik lub folder, którego kopię zapasową chcesz utworzyć. Domyślnie automatyczne tworzenie kopii zapasowych obejmuje prawie wszystkie pliki aplikacji. Jeśli podasz element <include>, system nie będzie już domyślnie uwzględniać żadnych plików i będzie tworzyć kopie zapasowe tylko podanych plików. Aby uwzględnić kilka plików, użyj wielu elementów <include>.

Na Androidzie 11 i starszych ten element może też zawierać atrybut requireFlags, który jest bardziej szczegółowo omówiony w sekcji dotyczącej definiowania wymagań warunkowych dotyczących kopii zapasowej.

Pliki w katalogach zwracanych przez polecenie getCacheDir(), getCodeCacheDir() lub getNoBackupFilesDir() są zawsze wykluczane, nawet jeśli spróbujesz je uwzględnić.

<exclude>

Określa plik lub folder, który ma zostać wykluczony podczas tworzenia kopii zapasowej. Oto kilka plików, które zwykle są wykluczone z tworzenia kopii zapasowej:

  • Pliki z identyfikatorami związanymi z urządzeniami, które są udostępniane przez serwer lub generowane na urządzeniu. Na przykład Komunikacja w chmurze Firebase (FCM) musi wygenerować token rejestracji za każdym razem, gdy użytkownik zainstaluje Twoją aplikację na nowym urządzeniu. Po przywróceniu starego tokena rejestracji aplikacja może działać w nieoczekiwany sposób.

  • pliki związane z debugowaniem aplikacji.

  • duże pliki, które powodują przekroczenie przez aplikację limitu 25 MB na kopię zapasową;

Każdy element <include> i <exclude> musi zawierać 2 atrybuty:

domain

Określa lokalizację zasobu. Prawidłowe wartości tego atrybutu to:

  • root: katalog w systemie plików, w którym są przechowywane wszystkie prywatne pliki należące do tej aplikacji.
  • file: katalogi zwrócone przez getFilesDir().
  • database: katalogi zwrócone przez getDatabasePath(). Tutaj są przechowywane bazy danych utworzone za pomocą SQLiteOpenHelper.
  • sharedpref: katalog, w którym są przechowywane wartości SharedPreferences.
  • external: katalog zwrócony przez getExternalFilesDir().
  • device_root: jak root, ale dla pamięci chronionej przez urządzenie.
  • device_file: podobnie jak file, ale dotyczy pamięci chronionej na urządzeniu.
  • device_database: jak database, ale dla pamięci chronionej przez urządzenie.
  • device_sharedpref: podobnie jak sharedpref, ale dotyczy pamięci chronionej przez urządzenie.
path

Określa plik lub folder, który ma być uwzględniony w kopii zapasowej lub z niej wykluczony. Pamiętaj:

  • Ten atrybut nie obsługuje składni symboli wieloznacznych ani wyrażeń regularnych.
  • Możesz odwoływać się do bieżącego katalogu za pomocą ./, ale ze względów bezpieczeństwa nie możesz odwoływać się do katalogu nadrzędnego, na przykład za pomocą ...
  • Jeśli określisz katalog, reguła będzie obowiązywać w przypadku wszystkich plików w tym katalogu i w podkatalogach.

Implementacja BackupAgent

Aplikacje, które implementują automatyczne tworzenie kopii zapasowych, nie muszą implementować BackupAgent. Możesz jednak zaimplementować niestandardowy BackupAgent. Zwykle są 2 przyczyny:

  • Chcesz otrzymywać powiadomienia o zdarzeniach tworzenia kopii zapasowych, takich jak onRestoreFinished() czy onQuotaExceeded(long, long). Te metody wywołania zwrotnego są wykonywane nawet wtedy, gdy aplikacja nie jest uruchomiona.

  • Za pomocą reguł XML nie można łatwo wyrazić zestawu plików, których kopię zapasową chcesz utworzyć. W takich rzadkich przypadkach możesz zaimplementować BackupAgent, który zastąpi onFullBackup(FullBackupDataOutput), aby przechowywać to, co chcesz. Aby zachować domyślną implementację systemu, wywołaj odpowiednią metodę w superklasie za pomocą super.onFullBackup().

Jeśli zaimplementujesz obiekt BackupAgent, system domyślnie oczekuje, że aplikacja będzie wykonywać tworzenie i przywracanie par klucz-wartość. Aby zamiast tego korzystać z automatycznej kopii zapasowej opartej na plikach, w pliku manifestu aplikacji ustaw atrybut android:fullBackupOnly na true.

Podczas automatycznego tworzenia kopii zapasowej i przywracania system uruchamia aplikację w trybie ograniczonym, aby uniemożliwić jej dostęp do plików, które mogą powodować konflikty, oraz umożliwić jej wykonywanie metod wywołania w sposób BackupAgent. W tym trybie ograniczonym główna aktywność aplikacji nie jest uruchamiana automatycznie, dostawcy treści nie są inicjowani, a klasa podstawowa Application jest instancjonowana zamiast podklasy zadeklarowanej w pliku manifestu aplikacji.

BackupAgent musi implementować metody abstrakcyjne onBackup() i onRestore(), które są używane do tworzenia kopii zapasowych par klucz-wartość. Jeśli nie chcesz tworzyć kopii zapasowej pary klucz-wartość, możesz zostawić implementację tych metod puste.

Więcej informacji znajdziesz w artykule Rozszerzanie BackupAgent.