Резервное копирование пользовательских данных с помощью Auto Backup

Автоматическое резервное копирование приложений автоматически создает резервные копии данных пользователя из приложений, предназначенных для Android 6.0 (уровень API 23) или более поздних версий. Android сохраняет данные приложения, загружая их на Google Диск пользователя, где они защищаются учетными данными пользователя Google. Резервная копия шифруется на устройствах под управлением Android 9 или более поздней версии с использованием PIN-кода, шаблона или пароля устройства. Каждое приложение может выделить до 25 МБ данных резервной копии каждому пользователю приложения. За хранение резервных данных плата не взимается. Ваше приложение может настроить процесс резервного копирования или отказаться от него, отключив резервное копирование .

Обзор возможностей резервного копирования Android и рекомендации о том, какие данные следует выполнять резервное копирование и восстановление, см. в обзоре резервного копирования данных .

Резервные копии файлов

По умолчанию автоматическое резервное копирование включает файлы в большинстве каталогов, назначенных вашему приложению системой:

  • Общие файлы настроек

  • Файлы, сохраненные во внутренней памяти вашего приложения и доступные с помощью getFilesDir() или getDir(String, int)

  • Файлы в каталоге, возвращаемом getDatabasePath(String) , который также включает файлы, созданные с помощью класса SQLiteOpenHelper

  • Файлы во внешнем хранилище в каталоге, возвращаемом getExternalFilesDir(String)

Автоматическое резервное копирование исключает файлы в каталогах, возвращаемые методами getCacheDir() , getCodeCacheDir() и getNoBackupFilesDir() . Файлы, сохраненные в этих местах, нужны только временно и намеренно исключены из операций резервного копирования.

Вы можете настроить свое приложение для включения и исключения определенных файлов. Дополнительные сведения см. в разделе «Включение и исключение файлов» .

Расположение резервной копии

Данные резервной копии хранятся в частной папке в учетной записи Google Диска пользователя, размер каждого приложения ограничен 25 МБ. Сохраненные данные не учитываются в личной квоте Google Диска пользователя. Сохраняется только самая последняя резервная копия. При создании резервной копии любая предыдущая резервная копия удаляется. Данные резервной копии не могут быть прочитаны пользователем или другими приложениями на устройстве.

Пользователи могут увидеть список приложений, для которых были созданы резервные копии, в приложении Google Drive для Android. На устройстве под управлением Android пользователи могут найти этот список в навигационной панели приложения Drive в разделе «Настройки» > «Резервное копирование и сброс» .

Резервные копии каждого срока службы настройки устройства хранятся в отдельных наборах данных, как описано в следующих примерах:

  • Если у пользователя есть два устройства, для каждого устройства существует резервный набор данных.

  • Если пользователь выполняет сброс настроек устройства до заводских настроек, а затем настраивает устройство с той же учетной записью, резервная копия сохраняется в новом наборе данных. Устаревшие наборы данных автоматически удаляются после периода бездействия.

Расписание резервного копирования

Резервное копирование создается автоматически при выполнении всех следующих условий:

  • Пользователь включил резервное копирование на устройстве. В Android 9 этот параметр находится в «Настройки» > «Система» > «Резервное копирование» .
  • С момента последнего резервного копирования прошло не менее 24 часов.
  • Устройство простаивает.
  • Устройство подключено к сети Wi-Fi (если пользователь устройства не включил резервное копирование мобильных данных).

На практике такие ситуации возникают примерно каждую ночь, но резервное копирование устройства может никогда не выполняться (например, если оно никогда не подключается к сети). В целях экономии пропускной способности сети загрузка происходит только в том случае, если данные приложения изменились.

Во время автоматического резервного копирования система закрывает приложение, чтобы убедиться, что оно больше не выполняет запись в файловую систему. По умолчанию система резервного копирования игнорирует приложения, работающие на переднем плане, чтобы избежать ухудшения взаимодействия с пользователем. Вы можете переопределить поведение по умолчанию, установив для атрибута android:backupInForeground значение true.

Чтобы упростить тестирование, в Android включены инструменты, позволяющие вручную инициировать резервное копирование вашего приложения. Дополнительные сведения см. в разделе Тестирование резервного копирования и восстановления .

Расписание восстановления

Данные восстанавливаются при каждой установке приложения, будь то из Play Store, во время настройки устройства (когда система устанавливает ранее установленные приложения) или при запуске adb install. Операция восстановления происходит после установки APK, но до того, как приложение станет доступным для запуска пользователем.

Во время мастера первоначальной настройки устройства пользователю отображается список доступных наборов данных резервного копирования и задается вопрос, из какого из них восстановить данные. Какой бы набор резервных данных ни был выбран, он становится исходным набором данных для устройства. Устройство может восстанавливать данные либо из собственных резервных копий, либо из исходного набора данных. Если доступны резервные копии из обоих источников, устройство отдает приоритет собственной резервной копии. Если пользователь не прошел мастер настройки устройства, то восстановить устройство можно только из собственных резервных копий.

Чтобы упростить тестирование, в Android включены инструменты, позволяющие вручную инициировать восстановление приложения. Дополнительные сведения см. в разделе Тестирование резервного копирования и восстановления .

Включить и отключить резервное копирование

Приложения, предназначенные для Android 6.0 (уровень API 23) или выше, автоматически участвуют в автоматическом резервном копировании. В файле манифеста приложения установите логическое значение android:allowBackup , чтобы включить или отключить резервное копирование. Значение по умолчанию — true , но мы рекомендуем явно задать атрибут в манифесте, как показано в следующем примере:

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

Вы можете отключить резервное копирование, установив android:allowBackup значение false . Возможно, вам захочется сделать это, если ваше приложение может воссоздать свое состояние с помощью какого-либо другого механизма или если ваше приложение имеет дело с конфиденциальной информацией.

Включение и исключение файлов

По умолчанию система создает резервные копии почти всех данных приложения. Дополнительную информацию см. в разделе о файлах, для которых создается резервная копия .

В этом разделе показано, как определить пользовательские правила XML для управления объектами резервного копирования. Если ваше приложение предназначено для Android 12 (уровень API 31) или более поздней версии, вам необходимо указать дополнительный набор правил резервного копирования XML , как описано в этом разделе, для поддержки изменений в восстановлении из резервной копии , которые были введены для устройств под управлением этих версий Android.

Управление резервным копированием на Android 11 и более ранних версиях

Следуйте инструкциям в этом разделе, чтобы контролировать резервное копирование файлов на устройствах под управлением Android 11 (уровень API 30) или ниже.

  1. В файле AndroidManifest.xml добавьте атрибут android:fullBackupContent к элементу <application> , как показано в следующем примере. Этот атрибут указывает на XML-файл, содержащий правила резервного копирования.

    <application ...
     android:fullBackupContent="@xml/backup_rules">
    </application>
    
  2. Создайте XML-файл с именем @xml/ backup_rules в каталоге res/xml/ . В этот файл добавьте правила с элементами <include> и <exclude> . В следующем примере копируются все общие настройки, кроме 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>
    

Определите условия устройства, необходимые для резервного копирования.

Если ваше приложение сохраняет конфиденциальную информацию на устройстве, вы можете указать условия, при которых данные вашего приложения будут включены в резервную копию пользователя. Вы можете добавить следующие условия в Android 9 (уровень API 28) или выше:

Если вы обновили свои устройства разработки до Android 9, вам необходимо отключить, а затем снова включить резервное копирование данных после обновления. Это связано с тем, что Android шифрует резервные копии с помощью секрета на стороне клиента только после информирования пользователей в настройках или мастере настройки.

Чтобы объявить условия включения, установите для атрибута requireFlags выбранное значение или значения в элементах <include> в вашем наборе правил резервного копирования:

резервная копия_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>

Если в вашем приложении реализована система резервного копирования «ключ-значение» или вы сами реализуете BackupAgent , вы также можете применить эти условные требования к своей логике резервного копирования, выполнив побитовое сравнение между набором транспортных флагов объекта BackupDataOutput и флагами FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED или FLAG_DEVICE_TO_DEVICE_TRANSFER вашего пользовательского агента резервного копирования. .

В следующем фрагменте кода показан пример использования этого метода:

Котлин

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

Ява

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

Управление резервным копированием на Android 12 или более поздней версии

Если ваше приложение предназначено для Android 12 (уровень API 31) или более поздней версии, выполните действия, описанные в этом разделе, чтобы контролировать, какие файлы резервируются на устройствах под управлением Android 12 или более поздней версии.

  1. В файле AndroidManifest.xml добавьте атрибут android:dataExtractionRules к элементу <application> , как показано в следующем примере. Этот атрибут указывает на XML-файл, содержащий правила резервного копирования.

    <application ...
     android:dataExtractionRules="backup_rules.xml">
    </application>
    
  2. Создайте XML-файл с именем backup_rules .xml в каталоге res/xml/ . В этот файл добавьте правила с элементами <include> и <exclude> . В следующем примере создаются резервные копии всех общих настроек, кроме 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>
    

Синтаксис конфигурации XML

Синтаксис XML для файла конфигурации зависит от версии Android, на которой работает ваше приложение.

Android 11 или более ранняя версия

Используйте следующий синтаксис XML для файла конфигурации, который управляет резервным копированием для устройств под управлением Android 11 или более ранней версии .

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

Андроид 12 или выше

Если ваше приложение предназначено для Android 12 (уровень API 31) или более поздней версии, используйте следующий синтаксис XML для файла конфигурации, который управляет резервным копированием для устройств под управлением Android 12 или более поздней версии .

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

Каждый раздел конфигурации ( <cloud-backup> , <device-transfer> ) содержит правила, применимые только к этому типу передачи. Такое разделение позволяет, например, исключить файл или каталог из резервных копий Google Диска, сохраняя при этом их передачу во время передачи с устройства на устройство (D2D). Это полезно, если у вас есть файлы, которые слишком велики для резервного копирования в облако, но их можно без проблем переносить между устройствами.

Если для определенного режима резервного копирования нет правил, например, если отсутствует раздел <device-transfer> , этот режим полностью включен для всего содержимого, за исключением каталогов no-backup и cache , как описано в разделе Файлы, для которых создается резервная копия. раздел.

Ваше приложение может установить флаг disableIfNoEncryptionCapabilities в разделе <cloud-backup> , чтобы резервное копирование выполнялось только в том случае, если оно может быть зашифровано, например, когда у пользователя есть экран блокировки. Установка этого ограничения предотвращает отправку резервных копий в облако, если устройство пользователя не поддерживает шифрование, но поскольку передачи D2D не отправляются на сервер, они продолжают работать даже на устройствах, которые не поддерживают шифрование.

Синтаксис включения и исключения элементов

Внутри тегов <full-backup-content> , <cloud-backup> и <device-transfer> (в зависимости от версии Android устройства и targetSDKVersion вашего приложения) вы можете определить элементы <include> и <exclude> :

<include>

Указывает файл или папку для резервного копирования. По умолчанию автоматическое резервное копирование включает почти все файлы приложений. Если вы укажете элемент <include> , система больше не будет включать файлы по умолчанию и будет выполнять резервное копирование только указанных файлов . Чтобы включить несколько файлов, используйте несколько элементов <include> .

В Android 11 и более ранних версиях этот элемент также может содержать атрибут requireFlags , который более подробно обсуждается в разделе, описывающем, как определить условные требования для резервного копирования .

Файлы в каталогах, возвращаемые методами getCacheDir() , getCodeCacheDir() или getNoBackupFilesDir() , всегда исключаются, даже если вы попытаетесь их включить.

<exclude>

Указывает файл или папку, которые необходимо исключить из резервного копирования. Вот некоторые файлы, которые обычно исключаются из резервного копирования:

  • Файлы, имеющие идентификаторы, специфичные для устройства, либо выданные сервером, либо сгенерированные на устройстве. Например, Firebase Cloud Messaging (FCM) должен генерировать токен регистрации каждый раз, когда пользователь устанавливает ваше приложение на новое устройство. Если старый токен регистрации будет восстановлен, приложение может вести себя неожиданно.

  • Файлы, связанные с отладкой приложений.

  • Большие файлы, из-за которых приложение превышает квоту резервного копирования в 25 МБ.

Каждый элемент <include> и <exclude> должен включать следующие два атрибута:

domain

Указывает расположение ресурса. Допустимые значения для этого атрибута включают следующее:

  • root : каталог файловой системы, в котором хранятся все личные файлы, принадлежащие этому приложению.
  • file : каталоги, возвращаемые getFilesDir() .
  • database : каталоги, возвращаемые getDatabasePath() . Здесь хранятся базы данных, созданные с помощью SQLiteOpenHelper .
  • sharedpref : каталог, в котором хранятся SharedPreferences .
  • external : каталог, возвращаемый getExternalFilesDir() .
  • device_root : аналогично root , но для хранилища, защищенного устройством.
  • device_file : аналогично file , но для хранилища, защищенного устройством.
  • device_database : аналогично database , но для хранилища, защищенного устройством.
  • device_sharedpref : аналогично sharedpref , но для хранилища, защищенного устройством.
path

Указывает файл или папку, которые необходимо включить в резервную копию или исключить из нее. Обратите внимание на следующее:

  • Этот атрибут не поддерживает синтаксис подстановочных знаков или регулярных выражений.
  • Вы можете ссылаться на текущий каталог, используя ./ , но вы не можете ссылаться на родительский каталог, например, используя .. , по соображениям безопасности.
  • Если вы укажете каталог, правило будет применяться ко всем файлам в каталоге и рекурсивным подкаталогам.

Внедрить агент резервного копирования

Приложениям, реализующим автоматическое резервное копирование, не требуется реализовывать BackupAgent . Однако при желании вы можете реализовать собственный BackupAgent . Обычно для этого есть две причины:

  • Вы хотите получать уведомления о событиях резервного копирования, таких как onRestoreFinished() и onQuotaExceeded(long, long) . Эти методы обратного вызова выполняются, даже если приложение не запущено.

  • Вы не можете легко определить набор файлов, резервную копию которых хотите создать, с помощью правил XML. В этих редких случаях вы можете реализовать BackupAgent , который переопределяет onFullBackup(FullBackupDataOutput) для хранения того, что вы хотите. Чтобы сохранить реализацию системы по умолчанию, вызовите соответствующий метод суперкласса с помощью super.onFullBackup() .

Если вы реализуете BackupAgent , система по умолчанию ожидает, что ваше приложение выполнит резервное копирование и восстановление значений ключа . Чтобы вместо этого использовать автоматическое резервное копирование на основе файлов, установите для атрибута android:fullBackupOnly значение true в манифесте вашего приложения.

Во время операций автоматического резервного копирования и восстановления система запускает приложение в ограниченном режиме, чтобы предотвратить доступ приложения к файлам, которые могут вызвать конфликты, и позволить приложению выполнять методы обратного вызова в своем BackupAgent . В этом ограниченном режиме основное действие приложения не запускается автоматически, его поставщики контента не инициализируются, а Application базового класса создается вместо любого подкласса, объявленного в манифесте приложения.

Ваш BackupAgent должен реализовать абстрактные методы onBackup() и onRestore() , которые используются для резервного копирования значений ключа. Если вы не хотите выполнять резервное копирование значений ключа, вы можете оставить реализацию этих методов пустой.

Дополнительные сведения см. в разделе Расширение BackupAgent .