Data is a crucial component of any app, which is why perfecting how your application interacts with data is so important. There are many techniques for improving interactions with remote data, such as request prioritization, speculative requests, and caching. These are certainly techniques to be explored and used, but what if your data was there before users even opened your app?
Both iOS and Android expose mechanisms for refreshing data when your app is in the background (i.e. when a user is using a different app on their mobile device). Previously, we covered how to perform background data refresh on iOS. In this blog post, we’re going to walk through the process of adding background data refresh to Android apps with the Google Cloud Messaging service in just a few easy steps.
Introduction to Android Background Data Refresh
Google Cloud Messaging (GCM) provides a way to send data between a client and server. However, it also exposes some additional functionality that we can take advantage of (even if you aren’t using GCM as a data service for your apps), such as the ability to schedule recurring background data refreshes at a regular interval. To get started, add the Xamarin Google Play Services – GCM NuGet to your project.
Android provides a mechanism for performing operations in the background called a service. Google Cloud Messaging exposes a special type of service named GcmTaskService
which we can use to configure how exactly the background refresh will take place. We can then use the GcmNetworkManager
to schedule a task on a regular interval.
Creating a Background Service
Create a new subclass of GcmTaskService
 named BackgroundService. All services must be marked with the [Service] attribute so that they can properly be bundled into the AndroidManifest.xml file. You can also specify additional members, such as required permissions for the service to operate. IntentFilter
can also be applied as an attribute to filter what types of messages the service responds to. Apply the following attributes to the BackgroundService class:
[Service (Exported = true, Permission = "com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE")] [IntentFilter (new [] {"com.google.android.gms.gcm.ACTION_TASK_READY"})]
Next, override the OnRunTask
method, where we’ll define the logic to refresh the app data in the background automatically. You should return either GcmNetworkManager.ResultSuccess
GcmNetworkManager.ResultReschedule
or GcmNetworkManager.ResultFailed
, depending on the result of the background operation:
public override int OnRunTask (TaskParams @params) { System.Threading.Tasks.Task.Run (async () => { // TODO: Perform background refresh logic here. Log.Debug ("Background Service", "Background Task Succeeded"); }); return GcmNetworkManager.ResultSuccess; }
GcmTaskService is a type of bound service, so we must create a class that subclasses the Binder
class, as seen below:
public class BackgroundServiceBinder : Binder { BackgroundService service; public BackgroundServiceBinder (BackgroundService service) { this.service = service; } public BackgroundService GetBackgroundService () { return service; } }
The Binder
class is responsible for maintaining a reference to our service so clients can make method calls against it. This is only created one time, in GcmTaskService
‘s OnBind
method and remains until it’s unbound. Override the OnBind
method and initialize and return the binder:
IBinder binder; public override IBinder OnBind (Intent intent) { binder = new BackgroundServiceBinder (this); return binder; }
Schedule the Background Data Refresh
Now that the GcmTaskService
is properly configured, it’s time to schedule our task using the GcmNetworkManager
. We can use the PeriodicTask</code builder to build a task around a set of options, including execution interval, the service to run, requiring a network connection, and more. Add a new method named
StartBackgroundDataRefreshService
to your MainActivity
and call it from the OnCreate
lifecycle method:
private void StartBackgroundDataRefreshService () { var pt = new PeriodicTask.Builder () .SetPeriod (1800) // in seconds; minimum is 30 seconds .SetService (Java.Lang.Class.FromType (typeof(BackgroundService))) .SetRequiredNetwork (0) .SetTag ("com.pierceboggan.backgrounddatarefresh") // package name .Build (); GcmNetworkManager.GetInstance (this).Schedule (pt); }
Configuration & Testing
Finally, GcmNetworkManager
requires a Google App Id to function properly, even if your app is not using Google Cloud Messaging services. To do this, create a new app in the Google Developers Console. Copy the application identifier and create a new string entry in the Strings.xml
file in the Resources/values directory:
APPLICATION_ID_HERE
Run the app, and you'll see it updates in the background every 30 seconds! For testing, ensure that the device (or emulator) in test has Google Play Services correctly installed, or GcmNetworkManager
will not be able to properly operate.
Wrapping Up
In this blog post, we created a background data refresh service using the Google Cloud Messaging NuGet with GcmTaskService
and scheduled our background service to run periodically using GcmNetworkManager
. Adding background data refresh is super easy, and only requires a few lines of code to get up and running. For more information on background services, check out our documentation on Android services or our blog post on how to perform background refresh in iOS apps.
0 comments