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

Automatyczna kopia zapasowa aplikacji automatycznie tworzy kopię zapasową danych użytkownika z aplikacji, które są kierowane na Androida 6.0 (poziom API 23) lub nowszego i działają na nim. Android pozwala zachować dane aplikacji, przesyłając je na Dysk Google użytkownika, gdzie są chronione danymi logowania do konta Google użytkownika. Kopia zapasowa jest w pełni szyfrowana na urządzeniach z Androidem 9 lub nowszym z użyciem kodu PIN, wzoru lub hasła urządzenia. Ilość danych jest ograniczona do 25 MB na użytkownika. Przechowywanie kopii zapasowych danych jest bezpłatne. Twoja aplikacja może dostosować proces tworzenia kopii zapasowej lub z niej zrezygnować przez wyłączenie kopii zapasowych.

Więcej informacji o opcjach tworzenia kopii zapasowych na Androidzie oraz wskazówki dotyczące tego, które dane tworzyć i przywracać, znajdziesz w omówieniu kopii zapasowych danych.

Pliki, których kopie zapasowe zostały utworzone

Domyślnie Automatyczna kopia zapasowa obejmuje pliki w większości katalogów, które system przypisze do aplikacji:

Automatyczna kopia zapasowa nie obejmuje plików w katalogach zwracanych przez getCacheDir(), getCodeCacheDir() i getNoBackupFilesDir(). Pliki zapisane w tych lokalizacjach są potrzebne tylko tymczasowo i celowo są wykluczane z operacji tworzenia kopii zapasowych.

Możesz skonfigurować aplikację tak, aby uwzględniała lub wykluczała określone pliki. Więcej informacji znajdziesz w sekcji Uwzględnianie i wykluczanie plików.

Lokalizacja kopii zapasowej

Dane kopii zapasowej są przechowywane w prywatnym folderze na koncie Dysku Google użytkownika, którego rozmiar nie może przekraczać 25 MB na aplikację. Zapisane dane nie wliczają się do limitu osobistego miejsca na Dysku Google użytkownika. Przechowywana jest tylko najnowsza kopia zapasowa. Wraz z tworzeniem kopii zapasowej usuwane są wszystkie wcześniejsze kopie. Użytkownik ani inne aplikacje na urządzeniu nie mają dostępu do danych kopii zapasowej.

Użytkownicy mogą zobaczyć listę aplikacji, których kopie zapasowe zostały utworzone, w aplikacji Dysk Google na Androida. Na urządzeniach z Androidem użytkownicy mogą znaleźć tę listę w panelu nawigacji w aplikacji Dysk w sekcji Ustawienia > Kopia zapasowa i resetowanie.

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

  • Jeśli użytkownik ma 2 urządzenia, dla każdego z nich istnieje zapasowy zbiór danych.

  • Jeśli użytkownik zresetuje urządzenie do ustawień fabrycznych, a potem skonfiguruje to urządzenie przy użyciu tego samego konta, kopia zapasowa zostanie zapisana w nowym zbiorze danych. Nieaktualne zbiory danych są automatycznie usuwane po okresie braku aktywnoś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ę Ustawienia > System > Kopia zapasowa.
  • Od utworzenia ostatniej kopii zapasowej upłynęły co najmniej 24 godziny.
  • Urządzenie jest nieaktywne.
  • Urządzenie jest połączone z siecią Wi-Fi (jeśli użytkownik nie wyraził zgody na tworzenie kopii zapasowych przez mobilną transmisję danych).

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

Podczas korzystania z Automatycznej kopii zapasowej system wyłącza aplikację, aby upewnić się, że nie zapisuje w nim już plików. Domyślnie system kopii zapasowej ignoruje aplikacje działające na pierwszym planie, aby nie obniżać komfortu użytkowników. Możesz zastąpić działanie domyślne, ustawiając wartość atrybutu android:backupInForeground na prawda.

Aby uprościć testowanie, Android obejmuje narzędzia umożliwiające ręczne rozpoczęcie tworzenia kopii zapasowej aplikacji. Więcej informacji znajdziesz w artykule Testowanie tworzenia i przywracania kopii zapasowej.

Harmonogram przywracania

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

W kreatorze początkowej konfiguracji urządzenia użytkownik widzi listę dostępnych zbiorów danych kopii zapasowej i jest pytany, z którego z nich należy przywrócić dane. Każdy wybrany zbiór danych kopii zapasowej staje się nadrzędnym zbiorem danych urządzenia. Urządzenie może przywracać dane z własnych kopii zapasowych lub z pierwotnego zbioru danych. Jeśli dostępne są kopie zapasowe z obu źródeł, urządzenie traktuje priorytetowo własną kopię zapasową. Jeśli użytkownik nie przeszedł do kreatora konfiguracji urządzenia, można przywrócić dane tylko z własnych kopii zapasowych.

Aby uprościć testowanie, Android obejmuje narzędzia umożliwiające ręczne rozpoczęcie przywracania aplikacji. Więcej informacji znajdziesz w artykule Testowanie tworzenia i przywracania kopii zapasowych.

Włączanie i wyłączanie kopii zapasowej

Aplikacje kierowane na Androida 6.0 (poziom 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ć kopię zapasową. Wartość domyślna to true, ale zalecamy jawne ustawienie atrybutu w pliku manifestu, tak jak w tym przykładzie:

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

Aby wyłączyć tworzenie kopii zapasowych, ustaw android:allowBackup na false. Może to być przydatne, jeśli aplikacja może odtworzyć swój stan za pomocą innego mechanizmu lub jeśli obsługuje informacje poufne.

Uwzględniaj i wykluczaj pliki

Domyślnie system tworzy kopię zapasową prawie wszystkich danych aplikacji. Więcej informacji znajdziesz w sekcji na temat plików z kopią zapasową.

W tej sekcji opisujemy, jak zdefiniować niestandardowe reguły XML, które pozwalają kontrolować elementy objęte kopiami zapasowymi. Jeśli Twoja aplikacja jest kierowana na Androida 12 (poziom interfejsu API 31) lub nowszego, musisz określić dodatkowy zestaw reguł tworzenia kopii zapasowych XML zgodnie z opisem w tej sekcji, aby uwzględnić zmiany w przywracaniu kopii zapasowych wprowadzone na urządzeniach z tymi wersjami Androida.

Kontrolowanie kopii zapasowej na Androidzie 11 i starszych

Wykonaj czynności opisane w tej sekcji, aby określić, które pliki mają być zapisywane w kopii zapasowej na urządzeniach z Androidem 11 (poziom interfejsu API 30) lub niższym.

  1. W pliku AndroidManifest.xml dodaj atrybut android:fullBackupContent do elementu <application> w sposób podany w poniższym przykładzie. Wskazuje on plik XML, który zawiera reguły tworzenia kopii zapasowych.

    <application ...
     android:fullBackupContent="@xml/backup_rules">
    </application>
    
  2. W katalogu res/xml/ utwórz plik XML o nazwie @xml/backup_rules. W tym pliku dodaj reguły z elementami <include> i <exclude>. Ten przykład tworzy kopię zapasową wszystkich wspólnych 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 informacje poufne na urządzeniu, możesz określić warunki, w jakich mają być uwzględniane dane w kopii zapasowej użytkownika. W Androidzie 9 (poziom interfejsu API 28) lub nowszym możesz dodać te warunki:

Jeśli Twoje urządzenia deweloperskie zostały uaktualnione do Androida 9, po przejściu na nową wersję musisz wyłączyć i ponownie włączyć tworzenie kopii zapasowej danych. Dzieje się tak, ponieważ Android szyfruje kopie zapasowe za pomocą tajnego klucza po stronie klienta tylko po poinformowaniu użytkowników w Ustawieniach lub w kreatorze konfiguracji.

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

reguły_kopii_zapasowej.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 ma wdrożony system zapasowych par klucz-wartość lub wdrożysz BackupAgent samodzielnie, możesz także zastosować te wymagania warunkowe do logiki zapasowej, przeprowadzając bitowe porównanie zestawu flag transportu obiektu BackupDataOutput z flagami FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED lub FLAG_DEVICE_TO_DEVICE_TRANSFER niestandardowego agenta zapasowego.

Poniższy fragment kodu przedstawia 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.
}

Kontrolowanie kopii zapasowej na Androidzie 12 lub nowszym

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

  1. W pliku AndroidManifest.xml dodaj atrybut android:dataExtractionRules do elementu <application> w sposób podany w poniższym przykładzie. Wskazuje on plik XML, który zawiera reguły tworzenia kopii zapasowych.

    <application ...
     android:dataExtractionRules="backup_rules.xml">
    </application>
    
  2. W katalogu res/xml/ utwórz plik XML o nazwie backup_rules.xml. W tym pliku dodaj reguły z elementami <include> i <exclude>. Ten przykład tworzy kopię zapasową wszystkich wspólnych preferencji z wyjątkiem 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 konfiguracji różni się w zależności od wersji Androida, na którą kierowana jest Twoja aplikacja i na której działa.

Android 11 lub starszy

Użyj tej składni XML w pliku konfiguracji, który steruje kopią zapasową 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 steruje tworzeniem kopii zapasowych 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 dotyczą tylko tego typu przeniesienia. Rozdzielenie pozwala na przykład wykluczyć plik lub katalog z kopii zapasowych na Dysku Google, ale nadal przesyłać go w trakcie przenoszenia między urządzeniami. Jest to przydatne, gdy masz pliki, które są za duże, aby utworzyć ich kopię zapasową w chmurze, ale bez problemu można je przenosić między urządzeniami.

Jeśli nie ma reguł dotyczących konkretnego trybu kopii zapasowej, np. brakuje sekcji <device-transfer>, ten tryb jest w pełni włączony dla całej zawartości oprócz katalogów no-backup i cache. Więcej informacji na ten temat znajdziesz w sekcji Pliki, dla których utworzono kopie zapasowe.

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

Składnia elementów uwzględniających i wykluczających

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

<include>

Wskazuje plik lub folder, którego kopię zapasową chcesz utworzyć. Domyślnie Automatyczna kopia zapasowa obejmuje prawie wszystkie pliki aplikacji. Jeśli określisz element <include>, system domyślnie nie będzie uwzględniać żadnych plików i będzie tworzyć kopie zapasowe tylko określonych plików. Aby uwzględnić wiele plików, użyj wielu elementów <include>.

W Androidzie 11 i starszych element może też zawierać atrybut requireFlags. Więcej informacji na ten temat znajdziesz w sekcji dotyczącej definiowania wymagań warunkowych dotyczących kopii zapasowej.

Pliki w katalogach zwracanych przez funkcję getCacheDir(), getCodeCacheDir() lub getNoBackupFilesDir() są zawsze wykluczane, nawet jeśli chcesz 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 nie są uwzględniane w kopii zapasowej:

  • Pliki z identyfikatorami związanymi z urządzeniem wydanymi przez serwer lub wygenerowany na urządzeniu. Na przykład Firebase Cloud Messaging (FCM) musi wygenerować token rejestracji za każdym razem, gdy użytkownik zainstaluje Twoją aplikację na nowym urządzeniu. Jeśli stary token rejestracji zostanie przywrócony, aplikacja może działać w nieoczekiwany sposób.

  • Pliki związane z debugowaniem aplikacji.

  • Duże pliki, które powodują przekroczenie limitu 25 MB kopii zapasowej aplikacji.

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

domain

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

  • root: katalog w systemie plików, w którym przechowywane są wszystkie prywatne pliki tej aplikacji.
  • file: katalogi zwrócone przez getFilesDir().
  • database: katalogi zwrócone przez getDatabasePath(). Są tu przechowywane bazy danych utworzone za pomocą SQLiteOpenHelper.
  • sharedpref: katalog, w którym przechowywane są SharedPreferences.
  • external: katalog zwrócony przez getExternalFilesDir().
  • device_root: jak root, ale w pamięci chronionej przez urządzenie.
  • device_file: jak file, ale w pamięci chronionej przez urządzenie.
  • device_database: jak database, ale w pamięci chronionej przez urządzenie.
  • device_sharedpref: jak sharedpref, ale do pamięci chronionej urządzeniem.
path

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

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

Wdrażanie agenta kopii zapasowej

Aplikacje, które stosują Automatyczną kopię zapasową, nie muszą implementować BackupAgent. Opcjonalnie możesz zaimplementować niestandardowy element BackupAgent. Zwykle dzieje się tak z 2 powodów:

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

  • Nie można w łatwy sposób określić za pomocą reguł XML zestawu plików, których kopię zapasową chcesz utworzyć. W tych rzadkich przypadkach możesz wdrożyć BackupAgent, który zastępuje onFullBackup(FullBackupDataOutput) i zapisuje to, czego potrzebujesz. Aby zachować domyślną implementację systemu, wywołaj odpowiednią metodę w superklasie za pomocą funkcji super.onFullBackup().

Jeśli wdrożysz BackupAgent, system domyślnie oczekuje, że aplikacja będzie wykonywać tworzenie i przywracanie kopii zapasowych par klucz-wartość. Aby zamiast tego użyć Automatycznej kopii zapasowej opartej na plikach, ustaw atrybut android:fullBackupOnly na true w pliku manifestu aplikacji.

Podczas operacji automatycznego tworzenia i przywracania kopii zapasowych system uruchamia aplikację w trybie ograniczonego dostępu, aby uniemożliwić aplikacji dostęp do plików, które mogą powodować konflikty, oraz umożliwić aplikacji wykonywanie metod wywołania zwrotnego w elemencie BackupAgent. W tym trybie główna aktywność aplikacji nie jest uruchamiana automatycznie, dostawcy treści nie są inicjowani, a klasa podstawowa Application jest tworzona zamiast dowolnej 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 zapasowych par klucz-wartość, możesz pozostawić implementację tych metod pustą.

Więcej informacji znajdziesz w artykule Extend BackupAgent.