You can reply to this article at https://medium.com/@jacobras/hidden-pitfalls-in-android-backup-53d1119b0a77.
“Users often invest significant time and effort creating an identity, adding data, and customizing settings and preferences within your app. Preserving this data and personalization for users when they upgrade to a new device or re-install your app is an important part of ensuring a great user experience.”
That’s how Google starts the page at https://developer.android.com/guide/topics/data/backup, which informs developers on how they can keep users’ data safely backed up. The takeaway is that user data is very important. Yet the solution offered; Android Auto Backup, is subpar. What’s bad about it and is there a way for developers to deal with that?
Backup systems
There are two systems for backup built into Android: a key-value backup system, “Android Backup Service” and a file backup system called “Android Auto Backup”. Here are the key differences:
Android Backup Service | Android Auto Backup | |
---|---|---|
Since | Android 2.2 (Froyo, API 8, 2010). | Android 6.0 (Marshmallow, API 23, 2015). |
Data | Key-value pairs. | Files. |
During backup | App keeps running, recommended to synchronise files in use. | App gets killed, runs in its own process. |
Transmission | Using Wi-Fi or cellular data. | Using Wi-Fi by default, but user can turn on mobile-data backups. |
Limit | 5 MB. | 25 MB, deducting from user’s Google Drive storage. |
Android Backup Service has existed for a long time, five years before Android Auto Backup was introduced. At time of writing, cumulative distribution for Android 6 is 97,83%, meaning both services are available to most users.
Difficulties for users
Users trying to keep their data safe for apps using these systems will have to deal with three big challenges:
1. Limited transparency
Here’s how to view the backups on Android 12: Settings » System » Backup » Manage storage » scroll down to “Device backup” and expand your device » Show details » Apps. That’s six levels of deeper navigation starting from the main settings screen, only if you know it’s there and click the right buttons.
There’s no detail per app, so it’s impossible to tell if these backups are up to date. Further down this post I’ll elaborate why that is a big issue due to the file size limitations.
2. Limited control
Here’s how to back up a single app: You can’t*. Best alternative, available on Android 9+, is to kick off the full backup by going to: Settings » System » Backup » Back up now. On my Pixel 4a, this took 10 minutes for 180 apps.
Here’s how to restore a single app: You can’t*. Restore happens automatically when you (re-)install an app. If for some reason it doesn’t, or if you for any other reason want to go back to a previous backup, then you’re out of luck and can’t manually trigger it.
* unless you’re comfortable with the ADB commands further down this post.
3. Limited data
The limit of 5MB for key-value pairs in Android Backup System seems reasonable. Storing some settings, that will surely fit in there. For apps dealing with larger user data, like photos, the 25MB limit of Android Auto Backup will pose an issue. What’s more, this limit cripples the system. When an app tries to backup more than the 25MB, the developer gets a notification. Not the user! Instead, the system rejects the backup that’s too big and keeps the oldest backup that fits. If the app doesn’t notify you, you’ll be left with an outdated backup, without ever knowing it.
Take a look:
Bonus: concerning reliability
Here’s an example of why the lack of insight described above is such a major issue. In 2019, Android Auto Backup was broken for several users for months: https://www.xda-developers.com/android-backup-google-drive-broken-how-to-fix-manager/. I wonder how many of the affected users actually noticed it.
Pitfalls for developers
Most of the difficulties listed above are also annoyances for developers, as they have to somehow try to manage them. In general, you can set a custom backup agent that supports both Android Backup Service and Android Auto Backup. It has API methods like onBackup()
and onRestore()
, where the system allows us to write data to or read data from the backup. See Implementing BackupAgent | Android Developers.
What can we do with that? Not much:
1. Managing the limited transparency
So the user doesn’t know when the backup last happened. Can we help the user out? Not really. We could record the timestamp when the system invokes our custom backup agent’s onBackup()
or onFullBackup()
methods. The issue with this is that if the system rejects our backup (which I’ve seen happen a lot of times during testing), we won’t know. Only if the backup size is too big we will be informed through onQuotaExceeded()
. Best we can do is tell the user “we gave the system your data to backup at [timestamp] but we don’t know if it went somewhere”, which is no help.
2. Managing the limited control
With Android Backup System, we can call dataChanged()
to let the system know it would be nice to backup the data. It’s just a notification and we don’t know if it actually triggered something or worked (see point 1 above), but at least it’s something. With Android Auto Backup, there is no such API.
3. Managing the limited data
If your app deals with bigger user data (like photos), the 25MB limit is insufficient. It’s too risky to hope the data size stays below it, because once you exceed it you leave the user with an incomplete/outdated backup.
In one of my own apps, I thought it would be nice to offer the user to use Android Auto Backup until 25MB and above that use a custom backup solution my app offers. I would check the data size and allow users to enable it if it’s below the limit. Here’s what I ran into:
- There is no way to enable/disable Android Auto Backup on runtime, because you have to opt-in in the manifest;
- Listing an empty
backup_rules.xml
set, and then adding data in the customBackupAgent
results in the backup not being triggered at all. Adding non-existing dummy content in the XML does cause the agent to boot up; - Since the agent always runs once enabled, I tried simply not adding any files if the user disabled the backup option. Bad idea: empty backups get rejected by the OS and your app is not informed. Again we’re running into limited transparency/insights;
- The more hacks we build into this, the more things can go wrong. Even if I’d figure out a way to make it work on my Pixel devices, who knows what Samsung’s or Xiaomi’s wonderful software will do?
I am therefore going with a different approach, see further down this post.
Triggering backup and restore using ADB
But first, some useful ADB commands for technical users.
adb shell bmgr backupnow com.example
creates a backup.adb shell bmgr restore <token> com.example
restores a backup
(get the token first usingbmgr dumpsys backup
).adb shell bmgr wipe <transport> com.example
deletes a backup (get the transport name first usingbmgr list transports
).
💡 Conclusion & suggested approach
If your app just has some settings to backup and it’s okay if they’re not backed up, then go with Android Backup System’s key-value pair option. If your app has some files, you’re absolutely sure it stays well below 25MB and think your users can live with the limitations above, use Android Auto Backup.
If your app has either crucial data or it may grow above 25MB, I would recommend creating your own backup system. For example, like how WhatsApp does with the Google Drive API. Notice how they offer a manual trigger, large size and show a date of last success in the screenshot below. None of that is thanks to the Android OS:
If you offer multiple backup destinations (like Dropbox, WebDAV) you could help the user find back the right one later by storing the location in a key-value pair in Android Backup System, and then on a fresh install remind the user where the backup was stored. If there’s just one destination/cloud service, this would still be a smart idea to help remember the user there’s data to be recovered.
Note: encryption. With Android Auto Backup, it’s possible to require backups to be client-side encrypted. In your own solution you’d have to encrypt the data yourself (or at least inform the user). See Defining device conditions | Android Developers.
Note: device to device transfer. The mechanism that transfers your data to a new device directly, is also using Android Auto Backup. I don’t know if the limit in that scenario is also 25 MB, but I’m afraid it is as I couldn’t find any source stating the opposite.
I hope that in the future Google will remove the 25 MB limit (after all, it deducts from your own Google Drive anyway, so why not?) and offer more control and insight into the backup mechanism. Until then, we’re stuck with workarounds.