Adding cloud functionality to an Android app

It’s often said that Apple don’t do cloud services as well as Google, and one very clear example of this can be seen in the Android SDK. Right from API Version 1 Android has supported something called “Sync Adapters“. They’re a little convoluted to set up, but basically Android provides an abstract framework straight out of the box for adding any kind of background network sync behaviour you need to your app. It handles calling your sync task at suitable times, for optimum battery usage, and makes sure it all runs nicely in a background thread. All you need to do then is define the behaviour each time the sync is performed.

The step by step instructions here are pretty thorough in talking you through what you need to do. I got stuck at just a couple of points:

  1. Firstly, they provide incomplete code in step 3 for their CreateSyncAccount method. I had assumed that if addAccountExplicitly failed then that was a fatal error, so was returning a null account. In fact, you can ignore this error completely and still return the new account object you’ve created.
  2. In the final step, running your adapter, it would appear from what I’ve experienced and what I’m reading on StackOverflow that the documentation everywhere is completely lying to you, and you do in fact need to turn setSyncAutomatically ON even to use addPeriodicSync. What’s more, addPeriodicSync takes an interval in seconds not in milliseconds like the example code would suggest.
  3. Finally, the example code passes a null extras bundle to addPeriodicSync, but this will in fact cause an exception. So make sure you pass in a bundle, even if it’s completely empty.

Despite these initial hickups, Sync Adapters have given me a real headstart in adding online feed subscriptions to the Android version of PrayerMate, so consider me impressed.

Update: Big gotcha – setting the frequency

It’s worth being aware that if configured naively, your SyncAdapter could be run arbitrarily frequently, i.e. multiple times per minute, effectively constantly running in the background and draining the battery. You are therefore strongly advised to make sure your onPerformSync method sets the delayUntil property. Just be aware that the documentation on this is completely misleading – if you look at the source code to how the SyncManager works, delayUntil isn’t “the number of seconds to wait before running again” at all – it’s the absolute timestamp when it should next run. So don’t set syncResult.delayUntil = 60*10 to make it wait for ten minutes, instead set syncResult.delayUntil = (System.currentTimeMillis()/1000) + 60*10.