Retaining users when they migrate to a new Android device, or when they reinstall your app, can be tricky. If you don't craft a smooth experience, they might just drop your app and go to a competitor. Fortunately, Android Data Backup APIs can help!
It’s autumn, it’s new phones season, and I guess quite a few amongst you bought, or received, a new Android device in the last year or so. It certainly was so for me — I have sent my Nexus 6P in for warranty and was lucky enough that Google sent me back a new Pixel XL.
As I set myself to the generally painful task of migrating to my new device before sending the defective 6P back, I noticed that in the intervening year since I’ve last done this the process has become way smoother. Once connected the two devices with a cable, almost all the apps and accounts I had were migrated to the new device effortlessly. Had I not had a working 6P at all, a cloud restore would’ve provided the same convenience (albeit at a much slower pace, I suspect).
The nicest part? Most of my system and apps’ settings were migrated automatically, too! Setting up my new Pixel took me less than an hour, instead of several hours.
It had been quite some time that an Android device made me say "wow"!
How is this all possible, you might be wondering? It’s all down to more apps adopting one of the Android backup mechanisms. Google, for one, are doubling down their efforts to correctly backup their apps’ data — although they have a rather spotty record as of yet. The launcher can carry over the homescreens organisation, Drive and siblings will skip their onboarding, and so on. But not all of the Google apps still work well.
I’m looking at you, Play Music and Google Maps ಠ_ಠ
Why are you not automatically re-downloading my offline music and maps?
I find those examples a bit sad, especially since most other Google apps, and many third-party apps, will successfully restore their settings on a reinstall, through the app backup, account transfer and data sync capabilities that Android offers — more on that later.
To be clear, I don’t mean to suggest that Maps and Play Music should store their cached data in the backup — there is not enough room for that, obviously. What they could to though is to backup the list of content they had cached, so that when they’re restored they can re-download it all automatically, or at least prompt the user if they want to re-download all those things.
Of course Play Music and Maps aren’t alone in the "too good to backup their settings" camp. It’s very annoying as an user to open an app after they’ve migrated to a new device or reinstalled it, just to find out all their configurations have been lost. It makes even less sense when you consider that, if you keep backup and restore in mind when developing it’s extremely trivial to implement it. If you were not as tidy with your internal storage you might have to refactor things a bit, but in my opinion it’s still worth it.
Cool, but why should I care?
Even if you were not interested in making the best app ever, you probably still care about user retention. Here’s where backup and restore come to your help. When users buy new devices (every 1-3 years generally in Western countries) and you don’t allow your app to be backed up, it will not automagically show up on their new device. If your backup settings are wrong, they’ll have to sit through an onboarding they don’t need, and then will have to re-set all the configuration options your app has lost along the way. Maybe they’ll even have to log in to apps all over again. That’s super frustrating and can take the joy out of getting a new device even for the geekiest amongst us — and I count myself in there!
Users hate doing this, and they’ll be way more likely to uninstall your app, or switch to a competitor. Properly supporting backup and restore in your app takes very little time and has some solid pros and basically no cons. Even your manager and marketing should be able to immediately see a return on investment.
What makes the UX tick…
…is, unsurprisingly, clever usage of cloud-based backup services. In addition to the usual data syncing facilities such as
SyncAdapters, web APIs, or Firebase RTDB/Firestore, Android has some rather powerful APIs for backing up and restoring apps’ private data in a secure and effortless way:
They aim to provide the same end result — happy users that keep using your apps on their new devices — but they have substantial differences in their scope and how they work.
Not everyone knows it, but Android has been able to backup and restore app settings since the very early days of Froyo. This is because starting with Android 2.2 (API 8) Google introduced the Key/Value Backup API; as the name suggests, this works by storing a set of Key/Value pairs into a backup transport that is then queried when reinstalling an app.
The backup transport on all devices with Play Services that I am aware of is provided by Google’s Android Backup Service. I am not familiar enough with the GMS licensing terms to know whether this is a mandatory requirement or if OEMs can swap it out and use another provider, but I haven’t seen any doing it. The documentation seems to imply it is not a requirement, though, so I suspect OEMs simply cannot be bothered rolling out their own thing (luckily for us users!).
As far as I know non-GMS devices, such as Amazon Kindle Fires, do not provide any backup transport at all — possibly because they don’t care about these flows that much, or maybe because it’s a pure infrastructure cost that they cannot justify.
As developers and users though you don’t have to care much about this. All you need to know is that, if a backup transport is available, all your data will be backed up securely and restored as needed. If no transport is available, or if a different transport than Android Backup Service is available, then the system will do the right thing by either not backing up your data, or send it wherever it is supposed to go.
Implementing Key/Value Backup
This mechanism is opt-in; developers need to specify the
android:allowBackup="true" attribute on their apps’ manifests, and implement a
BackupAgent. The backup agent must then be declared in the manifest using the
android:backupAgent attribute. If you want to take advantage of the Android Backup Service on Play Services devices, you’ll need to obtain an API key and put it in your manifest, too. If you don’t do this last crucial step, Key/Value Backup won’t work! For example:
<application android:label="MyApplication" android:allowBackup="true" android:backupAgent="MyBackupAgent"> ... <meta-data android:name="com.google.android.backup.api_key" android:value="AEdPqrEAAAAIDaYEVgU6DJnyJdBmU7KLH3kszDXLv_4DIsEIyQ" /> </application>
With the Android Backup Service Key/Value Backup, you can store up to 5 MB of data in Google’s cloud. This is normally more than enough to back up your shared preferences contents.
BackupAgent is a generalised backup API that can be used to provide a custom backup logic, including migrations from older versions of your backup data (e.g., a user’s last backup was on a previous version of the app that had a different schema for the data). While most apps will just want to back up their
SharedPreferences, some might want to back up other configuration data that is stored elsewhere, such as in plain text files or databases.
At this point I need to remind y’all that with great power comes great responsibility: don’t use the backup services to backup non-configuration data!
If all you want to do is backup entire files, you can extend
BackupAgentHelper, which provides a greatly simplified version of the API. In there, you want to add one or both of its two subclasses,
SharedPreferencesBackupHelper. If you want to backup entire files, though, Key/Value is probably not the best choice for you.
There is also a little known library that the Backup and Restore team at Google have open sourced recently in AOSP, libbackup. While I have not used it yet, it’s supposed to let you backup only some keys that are matching a given regex, and to make testing easier.
Again, this I have learnt from the Backup and Restore team, but I have not had a chance to try it out and assess its capabilities. It’s unfortunately not documented either, which makes it complicated to peek into without using it. Hopefully this will improve in the future, and maybe we’ll see it getting on GitHub and JCenter (yes, I very well remember the fate of Volley).
In the second and last part of this series, we’ll see how we can get apps’ data backed up with even less effort than with Key/Value Backup!