mobile developmentWhat's the Problem?

In my first blog on implementing the Gimbal SDK for Android, I provided a detailed example of integrating the Gimbal SDK as a background service to detect (and respond to) Gimbal beacons or geofences. With the latest Android release, Android O, Google has introduced new limitations on what apps can do when they run in the background. The Android documentation outlines these Background Execution Limits and provides alternative approaches to creating a background service, such as:

  • Job Scheduler
  • Service Whitelist
  • Foreground Service
  • Deferring Task to Foreground

What's the Solution?

The latest Gimbal SDK (Version 3.0) does not require developers to implement any of these alternatives. Gimbal has developed a customized and proprietary update to their SDK. They listen for various intents to "wake up" the Gimbal-associated app to perform tasks previously managed in a background service.

For those familiar with previous versions of the Gimbal SDK, once Gimbal.start() was invoked, the Gimbal background service started and would run indefinitely or until stopped. This service was responsible for detecting any beacon or geofence encounters. In Version 3.0, Gimbal.start() still needs to be invoked, but instead of starting a background service, it "begins monitoring for Gimbal events" as noted in their SDK documentation.

The focus of this blog will demonstrate how we can detect (and respond to) events with Gimbal's SDK updates.

To Target or Not to Target...Android O

Before getting into the integration details, it's important to understand when the Gimbal SDK Version 3.0 is required, or simply encouraged. If your app is targeting Version 26 (or higher) of Android APIs, you MUST use Version 3.0 of the Gimbal SDK. Otherwise, you can use earlier versions of the Gimbal SDK that use a background service, BUT be advised…

Users can still opt in to apply Android O service restrictions on earlier versions of Android. However, keep in mind, that a Gimbal implementation before Version 3.0 will become inoperable if users set these restrictions on their device. With increased attention to preserving battery life and memory, users are applying these restrictions with higher frequency.

Gimbal SDK 3.0 Integration

Step 1: Get the latest Gimbal SDK

Download the latest (Version 3.0 or higher) from your Gimbal Manager dashboard.

Step 2: Update Gimbal Library Files

Replace the Gimbal library files in your libs folder with the two new Version 3.0 files.

Step 3: Perform Migration/Setup Steps

Once you've completed steps 1 and 2, review and follow the migration steps outlined in the SDK Documentation:

  • Update build.gradle dependencies
  • Update AndroidManifest.xml
  • Update ProGuard Rules, if applicable

For users not migrating from an older version of the Gimbal SDK, the complete instructions for integrating Gimbal SDK Version 3.0 can be found in the developer guide.

Step 4: Initialize the Gimbal SDK

In prior implementations of the Gimbal SDK, we created a background service class that was responsible for performing actions after visit events were detected. For example, the onVisitStart and onVisitEnd callback methods could be overridden to relay event information (by way of an API call) to an endpoint on the client's services façade. Leveraging both the Gimbal service and an additional background service, event monitoring and callback activity was possible even when the app was not in the foreground.

Since background services are no longer viable for Gimbal on Android O, ensure that your app has an Application class which must have an entry in the application element of your AndroidManifest. You will need to initialize Gimbal inside this class's onCreate() method. Gimbal event listeners should be created and initialized inside this method as well.

public class MainApplication
 … 
 private PlaceEventListener mPlaceEventListener;
 … 
 public void onCreate() {
 … 
 Gimbal.setApiKey(this, AppConfig.GIMBAL_API_KEY);

 mPlaceEventListener = new PlaceEventListener() {
 @Override
 public void onVisitStart(final Visit visit) {
 // do something really awesome
 }
 @Override
 public void onVisitEnd(final Visit visit) {
 // do something equally awesome
 }
 };
 PlaceManager.getInstance().addListener(mPlaceEventListener);
 }
 … 
}
Step 5: Start Monitoring

Once the location permission is granted, presumably inside one of your Activities, Gimbal.start() can be invoked to start monitoring for any Gimbal events.

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
 if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
 Gimbal.start();
 }
 }
}

Gimbal.start() is not invoked from the main application class because location permissions need to be granted first. Remember, beginning with Android 6.0 (API level 23), users grant permissions while the app is running. Once we have UI available to request location permission, then we can initiate event monitoring.

Observations

The Android O updates on reducing battery life and memory usage by introducing background execution limits are forcing third-party vendors and developers to work with these limits. Luckily, Android offers several robust approaches that can be leveraged. Gimbal, however, has done much of the heavy lifting, albeit proprietary, with their latest SDK update. This translates to simpler and faster development efforts to update Gimbal-enabled applications.