Auto Backup API in Android

Hey there! Welcome. In this high-tech world, data is given the utmost importance, isn’t it? Nowadays, data-loss is a nightmare for most of us. Whether it is the data in your computer’s hard drive or any custom settings data of an app that you use, backing data up should be one of the tasks in your priority list.

Being an app developer, I believe we should provide a data backup facility to our users. Fortunately, Android has something called Auto Backup API for this purpose and it has been around for a while now.

Auto Backup API

It uploads the local app data in a private folder on the user's Google Drive account with a maximum storage limit of 25 MB/app. (data is not included in the user's personal Google Drive quota). If the quota limit for an app is reached, the system won’t backup the data anymore. However, when a new backup is done, the previous backup is deleted.
To enable it with its default configurations, we just need to add the following line in the application tag of the manifest file.

android:allowBackup="true"

That’s all..! The entire process is managed by the Android framework.

There’s actually one more requirement to make it work. Users should have Google Backup & Reset feature enabled on their device along with a backup account assigned to it. In Android 9, this option can be generally found at Settings > Backup and reset > App data.

The user’s data is now eligible for the backup.

By default, this data includes files, root & externalFiles directories, databases, and sharedPreferences but this API will always ignore noBackupFiles, cache & codeCache directories.

Now the question is when and how often the data gets uploaded on Google Drive? There are certain triggers to initiate the backup process.

  • Device is idle
  • The last backup was performed at least 24 hours ago
  • The device is connected with WiFi/mobile-data (as per user’s backup configurations)

Custom configurations

Suppose we have a requirement to consider only sharedPreferences for the backup process and the rest of the files/directories should be ignored. This can be achieved easily using the fullBackupContent property of manifest’s application tag.

We need to create an XML file(backup_rules.xml) with the following content in res > xml. Here, data.xml is the name of the sharedPreferences file.

<full-backup-content>
    <include domain="sharedpref" path="data.xml" />
</full-backup-content>

We can then point to this file as follows.

android:fullBackupContent="@xml/backup_rules"

Rules can be configured depending on the project’s requirements.

<full-backup-content>
    <include domain=["file" | "database" | "sharedpref" | "external" | "root"]
    path="string"
    requireFlags=["clientSideEncryption" | "deviceToDeviceTransfer"] />
    <exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]
    path="string" />
</full-backup-content>

Domains in the <include> tag will be included in the backup process whereas those in the <exclude> tag will be ignored.

There’s also a parameter requireFlags in the <include> tag to add flags which are basically used to enable a couple of features on Android 9 devices. It can have the following values.

  • clientSideEncryption: Used to encrypt the backup with client-side secret.
  • deviceToDeviceTransfer: Used to allow the user to transfer the backup to another device using local device-to-device transfer.

Backup Agent

Android provides an interface between application and data backup infrastructure. It is mostly used with the Key-Value backup mechanism and not really needed when we are working with file backup. However, if we need to have delegates or callbacks for events like completion of a backup process and allotted quota limit being reached, we can create an agent for such purposes.

class CustomBackupAgent : BackupAgentHelper() {

    override fun onFullBackup(data: FullBackupDataOutput?) {
        super.onFullBackup(data)

        Log.e("BACKUP", "onFullBackup")
    }
}

We have to create a child class of BackupAgentHelper and override the required method/event. After that, we need to define our agent in the manifest file’s application tag.

android:backupAgent=".CustomBackupAgent"

Testing

We can force backup & restore using ADB shell commands.

Backup

The following 4 commands can be used in sequence to have a full backup.

  • Enable backup manager
adb shell bmgr enabled
  • Initialize and run backup manager
adb shell bmgr backup @pm@
adb shell bmgr run
  • Perform full backup
adb shell bmgr fullbackup <package_name>

When the system performs a full backup, it’ll shut down the app by default to avoid any local data changes while the process is running. To have a backup in the foreground, we can enable a flag in the manifest. (works for version >= 24)

android:backupInForeground="true"

Restore

Data restoring is done automatically when the app is reinstalled from Google Play store or using ADB commands (installing using Android Studio). The restoring process is done after the app is installed and before it is made available to the user. If we need to force a restore using shell commands, it can be done as described here.

That’s too much theory, isn’t it? Let’s fire up the Android Studio to play with this API.

Demonstration

I’ll not bore you with the project creation, UI & initialization process and will directly discuss the core of this topic. We’ll consider a very simple use case of sharedPreferences.

We have an edit text to enter data and a button to save it in sharedPreferences. Here’s the GIF representing the entire demo.

I stored a value in the sharedPreferences, performed a forced backup, uninstalled the app, and reinstalled it using ADB commands. The data was successfully restored.

I also attached an agent to print the event log. Here’s the logcat output:

E/BACKUP: onFullBackup

You can find this demo here.

Avoiding backup

Backup is very necessary but there are a few things that shouldn’t be included in this process. For instance:

  • Any device-specific information such as FCM token
    • Restoring will also work when the user installs the app on another device with the same Google account. In this case, we should not have the previous device’s data.
  • Any sensitive user data such as account credentials
  • Authorization tokens
    • When the user installs his app on a different device, we should pass him through the login flow instead of fetching the older token and allowing him to use the app directly.
  • Large files
    • We should always keep the allotted quota in mind i.e. 25 MB/app. We should not include files that might occupy the entire space leading to backup failures.

Conclusion

Auto Backup API is a very handy tool provided by the Android framework. It’s very easy to use and customize. I recommend enabling this API in every project as per the requirements. That’s it from my end. I hope you enjoyed reading the article and grabbed something useful out of it. Stay safe and keep your users’ data safe too! :)