Android Version 3 API Developer Guide

The Gimbal SDK V3 adds support for Android 8.0 Oreo and simplifies integration of the SDK into your app. This guide provides examples of the available functions in our SDK along with a step by step guide on how to create a Gimbal SDK enabled application.

If your app currently uses Gimbal SDK V2, you will need to migrate to V3 in order for it to operate properly on Android 8.0 devices. Please refer to our V2 to V3 Migration Guide for details.

Create Your Developer Account

Go to the Gimbal Manager and sign up to create a new account.

Gimbal Manager »

Create Your Android Application

The following steps will guide you through setting up a new application. As part of the Gimbal SDK download, we include a sample app which demonstrates all the basic SDK features such as place and communication events.


While we prefer Gimbal to be intergrated into an application built in Android Studio, our SDK can still be used with applications built in Eclipse. Included in this guide are instructions for getting Gimbal up and running in your app for both development tools.


Note To get started quickly and easily, please visit the Android Studio Quickstart »

The Quickstart provides a link for a sample application built with Android Studio and automatically creates the necessary Gimbal Application for Android.

Android Studio

Confirm Your Environment for Android Studio

  • Have a device with Android 4.4.3 or higher if using proximity(beacon) features.
      Important Proximity is not enabled on Android 4.4.x devices by default. You can enabled this on a per application basis in Gimbal Manager.
  • Use the ADT plug-in to download a version of Android equal to API 21

Create a new Android Studio project

In Android Studio under Quickstart choose "Start a new Android Studio Project"

Fill out your "Application Name", "Company Domain", and "Project location" fields.

Important The "Minimum SDK" should be set to at least API 14. Finish up by adding and customizing the appropriate activity for your app and press "Finish".

Add Gimbal Dependencies

Dependencies may be added to your project via artifacts from the Maven Central repository, or with the AARs packaged within our published Gimbal SDK zip file.

Adding Gimbal SDK with Maven Central

Add Maven Central and Google to the repositories section of your project's build.gradle file:

    repositories {
        ...
        mavenCentral()
        maven { url "https://maven.google.com" }
        ...
    }

Add the following artifacts to the dependencies section of your application module's build.gradle file:

    dependencies {
        ...
        compile group:'com.gimbal.android.v3', name:'gimbal-sdk', version:'3.0'
        compile group:'com.gimbal.android.v3', name:'gimbal-slf4j-impl', version:'3.0'
        compile 'com.google.android.gms:play-services-gcm:11.0.4'
        compile 'com.google.android.gms:play-services-location:11.0.4'
        compile 'com.google.android.gms:play-services-ads:11.0.4'
        ...
    }

version:'3.0' is the current SDK V3 version as of this writing. As updates are made, they will be made available in the SDK Downloads section of Gimbal Manager.

Manually adding Gimbal SDK to your project

You will find the Gimbal SDK AARs in the libs folder inside the Gimbal SDK zip file:

  • gimbal.aar

  • gimbal-slf4j-impl.aar

Add the AARs to your Android application by copying them into the libs folder of your app module. After adding them, add the following lines to your app's build.gradle file.

repositories {
    flatDir {
        dirs 'libs'
    }
    maven { url "https://maven.google.com" }
}

dependencies {
    ...
    compile(name:'gimbal', ext:'aar')
    compile(name:'gimbal-slf4j-impl', ext:'aar')
    compile 'org.slf4j:slf4j-api:1.7.13'
    compile 'com.google.android.gms:play-services-gcm:11.0.4'
    compile 'com.google.android.gms:play-services-location:11.0.4'
    compile 'com.google.android.gms:play-services-ads:11.0.4'
    ...
}

Your project should now look similar to the following:

External Dependencies

Google Play Services

The Gimbal SDK has optional dependencies on Google Play Services, which have already been added to the Gradle dependencies snippets above. The SDK will operate without them, but the associated functions will be disabled or crippled on some versions of Android. The dependencies are:

  • play-services-gcm - enables push notifications for Communication delivery

  • play-services-location - enables optimal location monitoring, required for geofence Place Event detection

  • play-services-ads - enables Manage Device ID for Advertising functionality

Note Note: Play Services version 11.0.x is the minimum version for full Gimbal SDK functionality. It is also the latest version that supports targeting Android API 25 and lower. If your application targets API 26, you may safely use later versions of the Play Services APIs.

SLF4J

The Gimbal SDK uses SLF4J as a logging adapter to the underlying Android logging API. The gimbal-slf4j-impl library is a pluggable implementation of the API. You may replace our SLF4J implementation, but you must retain the slf4j-api dependency.

Note When sourced from a Maven repository, the gimbal-slf4j-impl POM references slf4j-api:1.7.13 as a compile dependency. When sourced from a local directory, there is no external dependency information, so you will need to include slf4j-api as a compile dependency in your app.

Integrate the Gimbal SDK

Add an Application Class to Your App

The Gimbal SDK must be initialized from within your Application.onCreate() method. Apps created within Android Studio do not start with a Application derived class, so you must add your own derived class. The class must also be added in your app manifest in the android:name="..." attribute of the application element.

The Sample App included with the Gimbal SDK includes a SampleApplication class that you can use for reference. The included manifest shows how to specify SampleApplication so that Gimbal gets initialized properly whenever the app starts.

Initialize Gimbal

There are three main things that need to occur to receive events from the Gimbal SDK:

  • Set the API key

  • Register Gimbal event listeners

  • Start monitoring for Gimbal events

When integrated correctly, the Gimbal SDK will generate Place Events and Communications even when the user isn't using the app.

Set API Key

Calling Gimbal.setApiKey() links instances of the application with a specific application that you have created in Gimbal Manager. This must be invoked before any other Gimbal calls, from within your application's onCreate() call hierarchy.

import com.gimbal.android.Gimbal;
...
public class MyApplication extends Application {
    private static final String GIMBAL_APP_API_KEY = "YOUR APP'S API KEY HERE";
    ...
    public void onCreate() {
        ...
        Gimbal.setApiKey(this, GIMBAL_APP_API_KEY);
        ...
    }
}

In the Sample App, this is called within GimbalIntegration.onCreate(), which is called from SampleApplication.onCreate().

See the Set API Key and Add Application sections below for more details about the call and how to get an API key.

Register Gimbal event listeners

Listeners allow the app to be notified of location events and Gimbal Communications configured on Gimbal Manager. The Gimbal SDK has three listener interfaces for Communications, Place events, and Beacon events. The example below shows the addition of a Communication listener.

import com.gimbal.android.Gimbal;
import com.gimbal.android.Communication;
import com.gimbal.android.CommunicationListener;
import com.gimbal.android.CommunicationManager;
...
public class MyApplication extends Application {
    private CommunicationListener communicationListener;
    ...
    public void onCreate() {
        Gimbal.setApiKey(this, GIMBAL_APP_API_KEY);
        communicationListener = new CommunicationListener() {
            // override methods as required
        };
        CommunicationManager.getInstance().addListener(communicationListener);
        ...
    }
}

Important The Gimbal SDK only holds weak references to your listeners. You must hold your own references so that the listeners are not made eligble for garbage collection.

Note If no listeners are added, end users will still receive default Notifications in the system tray upon receipt of Gimbal Communications.

Start Monitoring for Gimbal Events

The most direct way to start monitoring for Gimbal events is to invoke Gimbal.start(). This starts the PlaceManager, CommunicationManager and EstablishedLocationsManager. These services may alternatively be started individually for special use cases.

This should be called after location permission is granted by the user, or the services may not initialize correctly. There are a multitude of ways this can be achieved. One way is to invoke Gimbal.start() upon permission result success:

import com.gimbal.android.Gimbal;
...
public class PermissionActivity extends AppCompatActivity {
    public static final int LOCATION_PERMISSION_REQUEST_CODE = 101;
    ...
    @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();
            }
        }
    }
}

Please refer to our Runtime Permissions for Marshmallow section and to our Sample App for additional information and code samples.

Create A Gimbal Application

Create Your Gimbal Application in the Gimbal Manager.

Create Gimbal Application »

Add Application

You will be presented with a form where you will enter the following information: Name of your app, Platform (android), App category, Package name. Enter the package name you set in your Eclipse New Application. You will also need to select option for Android 4.4.3 and 4.4.4 (Kitkat support).

Important If you are testing with an Android device with version 4.4.3 or 4.4.4, you must allow for Kitkat support when using proximity features.

Hit the Generate button. Once finished, your app will have a Gimbal API Key.

Important You will need to set the API Key in your Android app.

Add Place

Create Gimbal Place »

You will be presented with a form where you will enter information about your Place. A Place represents both Geofence and Proximity. For example, a place can be represented by a geofence (circular or polygonal) or a series of beacons.

Please enter your Place information. For example, you can enter a Place name and enter your activated beacon(s). You can always update your Place by adding a Geofence or add/delete your beacons.

Note This is where you would enter the Place(s) where you will look for Place Events in your app.

Add Communication

Create Gimbal Communication »

You will be presented with a form where you will enter information about your communication. For example a Communication can be entered for a place and when an app enters the specified place, a notification will be received. Please select 'Save & Publish' to activate your communication.

Application Configuration


There are a number of application settings that you can configure. These can can be found by clicking on the Application’s Bundle ID / Package Name within Gimbal Manager.

Place detection with Beacons

The following settings control how place events are triggered. Note: any of the similar settings you set for a Place take precedence over these app-wide settings.

Arrival RSSI

The 'Arrival RSSI' setting allows you to specify a specific RSSI (signal strength) to be used in determining if a beacon sighting should be processed as an arrival to a beacon. Signals weaker than 'Arrival RSSI' will be ignored.
Default = null, such that whenever a beacon is first detected it will cause a sighting and an arrival.
You may wish to modify this value if you wish to decrease the range of when a beacon trigger an arrival.

Departure RSSI

The 'Departure RSSI' setting allows you to specify a specific RSSI (signal strength) to be used in determining if a beacon sighting should be processed as a departure. Signals weaker than 'Departure RSSI' will be ignored.
Note that the Departure RSSI must be at least 10dBm lower than the 'Arrival RSSI'. This is done to avoid excessive bouncing (where arrival and departures events are triggered repeatedly, even when both the mobile device and beacon are standing still).

Departure interval in seconds

The ‘Departure interval’ is the number of seconds that must elapse where the SDK does not see a beacon RSSI level stronger than the Departure RSSI before processing the departure.

Smoothing Window

The smoothing algorithm processes RSSI signal strengths from sightings to make them less jumpy. The larger the smoothing window the more steady the output RSSI readings will be.

Beacon Support on Android 4.4.3 and 4.4.4

This setting allows you to enable beacon support on Android 4.4.3 and 4.4.4 devices. Please note, these versions of Android have known performance issues. Learn more

SDK Feature Enablement

These settings allow you to turn specific features on/off.

Geofence Monitoring

Allows you to turn on/off geofencing monitoring.
This may be desired if your application only uses beacon-based places.

Beacon Monitoring

Allows you to turn off beacon monitoring. This will affect both beacon-based Place detection and beacon detection.
This may be useful if your application only uses geofence-based places.

Communicate Delivery

Allows you to turn on/off Communicate delivery.
This may be useful if your application does not use the Communicate feature.

Manage Device ID for Advertising

Allows you to turn on/off whether Gimbal records the device advertising identifier and limit ad tracking state for devices. Turning this on is necessary if you wish to correlate your advertising data with the data collected by the Gimbal SDK. This functionality is off by default. Your application must include the Google Play Services to use this feature.

Note For privacy reasons, when a device's advertising identifier is reset, the device is re-registered with Gimbal and receives a new application instance identifier.

Communication Limit Frequency


The configuration for communication limit frequency can be found in the 'Communicate' tab then the 'Triggers' section in Gimbal Manager.

The following settings are used to limit frequency when triggering communications for place events.

Limit Frequency

Selecting 'Yes' in the 'Limit Frequency' drop-down displays additional options for setting the frequency interval.

Only Deliver Once Every

The 'Only Deliver Once Every' setting allows you to specify the value in hours, days or weeks for the communication frequency. Please note, one day specifies a 24hr period. One week specifies a 168hr period. For example, if the frequency limit is set for one day, then a user who initially receives a communication at 4pm won't get that same communication until after that 24hr period, no matter how often the user comes back in and out of the triggering place.

Important If your CommunicationListener implements presentNotificationForCommunications, you MUST handle frequency limit and delay (dwell) yourself.

Communication Delay


The configuration for communication delay can be found in the 'Communicate' tab under the 'Triggers' section in Gimbal Manager.

Setting delay on a communication allows the communication to be delivered with some delay after a person has entered or exited a place. If a communication is scheduled to be delivered with some delay after a person has entered a place and the person exits that place before the communication is delivered, then the communication will be canceled. Similarly, if a communication is scheduled to be delivered some time after a person leaves a place and that person re-enters the place, the communication will be canceled.

Keep in mind that if delay causes a communication to be scheduled after the expiry date of the communication, it will not be delivered.

Important If your CommunicationListener implements presentNotificationForCommunications, frequency limit and delay (dwell) are honored only for communications returned by that method to the Gimbal SDK. Only use presentNotificationForCommunications if you want to handle scheduling and delivery of communications yourself.

Instant Communications

Gimbal allows you to send instant (push) communications using Google/Firebase Cloud Messaging (GCM/FCM).


Set Up Google/Firebase Cloud Messaging

Gimbal uses Google/Firebase Cloud Messaging (GCM/FCM) for enabling push on Android. In order to use GCM/FCM you'll have to setup your application on Firebase Console and obtain a GCM/FCM Sender ID and the Server key for the GCM/FCM Service.Please refer to Firebase Cloud Messaging and follow the steps to create a new FCM project to obtain these keys. Here's an overview of the steps you'll have to follow:

From Firebase Console

    1. In the Firebase console, click Add project.


    2. Supply a project name and click Create Project.


    3. Select the gear icon next to your project name at top left, and select Project settings.


    4. Select the Cloud Messaging tab. You can find your sender ID and server key in this page. The sender ID is the GCM Sender ID. The server key is the Cloud Messaging Key you will enter in your Gimbal application.

Note Before moving forward make sure that you have obtained the Server key and Sender ID from Firebase Console.

Add Google/Firebase Server API Key to Gimbal Manager

On Gimbal Manager, select your existing Android application and scroll down to the Google/Firebase Cloud Messaging Key section to setup Android push. Enter the Server API Key (created from Firebase Console) and hit save. Now your application is set to send push messages.

Add Google/Firebase Sender ID to Gimbal Enabled Application

In your application, add the Sender ID to the registerForPush method.

For details on how to register your app to receive push messages, look at section Register For Push.

Register For Push

Description

There are two ways to register with GCM/FCM to send messages to your app.

The first method is by using the Sender ID (generated from creating the Firebase project) to register for Push.

Sample

import com.gimbal.android.Gimbal;
...
Gimbal.registerForPush("## PLACE YOUR Sender ID # HERE ##");

The second method is by using the Registration Token (obtained from calling the GoogleCloudMessaging register method) to register for Push.

Sample

import com.gimbal.android.Gimbal;
...
Gimbal.setPushRegistrationToken("## PLACE YOUR Google Messaging Registration Token # HERE ##");

Note If both methods are used within the same application, only the last method is used to register for Push.


Receive Push Content

Whenever a push is sent to the client, Gimbal will call the CommunicationListener methodshouldPresentNotificationForCommunications. Your application can now decide whether or not to raise a notification to the User or allow the Gimbal SDK to raise the notification on your behalf.

public Collection<Communication> presentNotificationForCommunications(Collection<Communication> communications, Push push) {
    // This will be invoked when there is a Push based communication.  The communications
    // returned from this method will be presented as a Notification (collapsed notifications if more than one)
    // on behalf of the developer before applying frequency limit and delay.
    return filteredCommunications
}

Add Push Communication On Gimbal Manager

Send Instant Push

Instant Pushes are pushes that are sent immediately. To send instant pushes, go to the Communicate tab on Gimbal Manager, and click on + New.

On the resulting Communication Detail page, fill in an identifying name for your Communication. Select "TIME TRIGGERED: NOW (INSTANT)" in the Triggering Event dropdown box. The Start Date and End Date entries will disappear.

Fill in the details of your push message and click on Save & Publish to send your Instant Communication to your device.

Schedule Time Triggered Push

Time Triggered Push Notifications are Push Notifications that are sent at a specified time. To send instant pushes, go to the Communicate tab on Gimbal Manager, and click on + New.

On the resulting Communication Detail page, fill in an identifying name for your Communication. Select "TIME TRIGGERED: SPECIFIC TIME" in the Triggering Event dropdown box. Enter a start and end date, and any time filters as needed.

Set API key


Description

This call sets the API key for your Gimbal application. When you register an application on the Developer Portal the API key is generated and supplied to you.

This was done in the previous section Create Gimbal Application.

Sample

import com.gimbal.android.Gimbal;
...
public static final String GIMBAL_APP_API_KEY = "## PASTE YOUR API KEY HERE ##";
...
        Gimbal.setApiKey(this.getApplication(), GIMBAL_APP_API_KEY);

Important Gimbal.setApiKey must be invoked from your Application class's onCreate() method. In the Sample App, this is done within the GimbalIntegration class, which is invoked from SampleApplication.onCreate(). If using GimbalIntegration as a template, simply paste your API key into the value of its GIMBAL_APP_API_KEY variable.

Gimbal Started

The Gimbal defines the interface for starting all the services like PlaceManager, CommunicationManager and EstablishedLocationsManager, stopping the services and finding the status.


Check Gimbal Started

Description

Returns the Gimbal services state. It will return false if start was not called, or stop was called, on PlaceManager, CommunicationManager and EstablishedLocationsManager

Sample

import com.gimbal.android.Gimbal;
...
        Gimbal.isStarted();

Gimbal Start

Description

Starts all the Gimbal services which includes the generation of events based on the users location and proximity to geofences and beacons, receive communications associated to place entry and exit events and generation of established locations based on the users locations. Its a method for starting the PlaceManager, CommunicationManager and EstablishedLocationsManager. These features can also be controlled server side anytime for a specific application using advanced configuration at Gimbal Manager.

Sample

import com.gimbal.android.Gimbal;
...
        Gimbal.start();

Gimbal Stop

Description

Stops all the Gimbal services. Its a method for stoping the PlaceManager, CommunicationManager and EstablishedLocationsManager.

Sample

import com.gimbal.android.Gimbal;
...
        Gimbal.stop();

Place Manager

The PlaceManager defines the interface for delivering place entry and exits events to your Gimbal SDK enabled application. You use this class to start or stop place monitoring and to check whether monitoring is enabled.


Check Monitoring

Description

Check if place monitoring has started

Sample

import com.gimbal.android.PlaceManager;
...
        PlaceManager.getInstance().isMonitoring();

Start Monitoring

Description

Starts the generation of events based on the users location and proximity to geofences and beacons.

Important Please check the following section if you are targetting android SDK 23 and above for runtime permissions checks.

Sample

import com.gimbal.android.PlaceManager;
...
        PlaceManager.getInstance().startMonitoring();

Stop Monitoring

Description

Stops the generation of events based on the users location and proximity to geofences and beacons.

Sample

import com.gimbal.android.PlaceManager;
...
        PlaceManager.getInstance().stopMonitoring();

Current Visits

Description

The following gets visits for places that you are currently AT. The array returned is ordered ascending by arrival date.

Sample

import com.gimbal.android.PlaceManager;
...
        PlaceManager.getInstance().currentVisits();

Place Event Listener

Description

This is the listener for place event notifications. One of the following methods will be invoked based on the place event.

Place Event Methods

import com.gimbal.android.PlaceEventListener;
import com.gimbal.android.Place;
import com.gimbal.android.Visit;
...
    public void onVisitStart(Visit visit) {

         // This will be invoked when a place is entered
    }

    public void onVisitStartWithDelay(Visit visit, int delayTimeInSeconds) {

        // This will be invoked when the user entered the specified place and remained at the specified place with out
        // exiting for the delay time period assigned to the place in manager.gimbal.com. Places with no assigned delay
        // will invoke the method immediately upon entry.
    }

    public void onVisitEnd(Visit visit) {
        // This will be invoked when a place is exited
    }

    public void onBeaconSighting(BeaconSighting sighting, List<Visit> visits) {
        // This will be invoked when a beacon assigned to a place within a current visit is sighted.
    }

    public void locationDetected(Location location)  {
        // This will be invoked when Gimbal has detected a reliable location.
    }

Visit Accessor Methods

The Vist class defines the period of time which a User dwelled at a place. A Visit without a departure time represents an active visit where the User is still dwelling at a place.

Method Description
getPlace() returns the place the visit is associated to
getArrivalTimeInMillis() returns time in milliseconds at which the User arrived at a Place
getDepartureTimeInMillis() returns time in milliseconds at which the User was considered to be departed from a Place
getDwellTimeInMillis() returns dwell time in milliseconds

Place Accessor Methods

The Place class defines a place which is represented by a geofence (circular or polygonal) or a series of beacons. A place is defined in the Gimbal Manager portal.

Method Description
getIdentifier() return the unique identifier for this place
getName() returns the name assigned to this place
getAttributes() returns the attributes of this place

Beacon Sighting Accessor Methods

The Place class defines a BeaconSighting which is represented by a sighting information of a beacon.

Method Description
getRSSI() return the rssi value for the beacon sighted
getTimeInMillis() returns the beacon sighting date i milliseconds
getBeacon() returns beacon object with beacon attributes

Add Place Event Listener

Description

Create and implement the PlaceEventListener interface. Add the PlaceEventListener to the PlaceManager instance.

Sample

import com.gimbal.android.PlaceManager;
import com.gimbal.android.PlaceEventListener;
...
    private PlaceEventListener placeEventListener;
...
        placeEventListener = new PlaceEventListener(){
            // Add PlaceEventListener methods here
        }
        ...
        PlaceManager.getInstance().addListener(placeEventListener);

Note PlaceEventListener methods are implemented by default. To customize, please provide your own implementation for the desired PlaceEventListener methods.

Communication Manager

The CommunicationManager defines the interface for delivering communications to your Gimbal SDK enabled application. You use this class to start or stop receiving communications.


Start Receiving Communications

Description

Enables the SDK to receive communications.

Sample

import com.gimbal.android.CommunicationManager;
...
        CommunicationManager.getInstance().startReceivingCommunications();

Stop Receiving Communications

Description

Stops all communication delivery. This includes both local and instant(push) communications.

Sample

import com.gimbal.android.CommunicationManager;
...
        CommunicationManager.getInstance().stopReceivingCommunications();

Set Notification Channel

Description

Sets the Android Notification Channel ID to be used for Notifications posted from Gimbal Communications for clients running on Android 8.0 and newer, for apps targeting API 26 and newer.

By default, the Gimbal SDK will create and manage its own channel for notifications to be posted to. If any custom behavior is desired, e.g. vibration patterns or sounds, the developer may create and manage their own channel and specify it with setNotificationChannelId.

Note If a CommunicationListener is added that returns a Notification.Builder from its prepareCommunicationForDisplay() methods, then setNotificationChannelId has no effect.

Sample

import android.app.NotificationChannel;
import android.app.NotificationManager;
import com.gimbal.android.CommunicationManager;
...
        NotificationChannel channel = new NotificationChannel("sample_channel_id", "Sample", NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription("sample description");
        NotificationManager manager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        manager.createNotificationChannel(channel);
        CommunicationManager.getInstance().setNotificationChannelId("sample_channel_id");

Note Once set, the channel ID remains in use until null is specified. Declining to call setNotificationChannelId() does not clear a previously set ID within an application instance.

Communication Listener

Description

This is the listener for communications. One of the following methods will be invoked based on the communication event.

Important Gimbal does not support posting Notifications for versions below 3.0 for Visits & Instant Communications. Developers must override one or more of the following methods in CommunicationListener and post notifications.

Communication Methods

import com.gimbal.android.CommunicationListener;
import com.gimbal.android.Communication;
import com.gimbal.android.Place;
...

    public Collection<Communication> presentNotificationForCommunications(Collection<Communication> communications, Visit visit) {
        // This will be invoked when there is a communication associated with a Place Entry or Exit.  The communications
        // returned from this method will be presented as a Notification (collapsed notifications if more than one)
        // on behalf of the developer after applying any frequency limit and delay.
        // If you implement this method to filter communications, you MUST handle frequency limiting and delay yourself.
        return filteredCommunications;
    }

    public Collection<Communication> presentNotificationForCommunications(Collection<Communication> communications, Push push) {
        // This will be invoked when there is a Push based communication.  The communications
        // returned from this method will be presented as a Notification (collapsed notifications if more than one)
        // on behalf of the developer after applying any frequency limit and delay.
        // If you implement this method to filter communications, you MUST handle frequency limiting and delay yourself.
        return filteredCommunications
    }

    public void onNotificationClicked(List<Communication> communications) {
        // This method will be invoked when a user has clicked on a presented notification.  The first Communication in the list is the
        //notification visible to the end user and the rest were collapsed.
    }

    public Notification.Builder prepareCommunicationForDisplay(Communication communication, Visit visit, int notificationId) {
        // This method will be invoked when a communicate is received for place event. The caller is given a chance to
        // customize the Notification presented to the user. To do so, return a custom Notification.Builder from
        // from this method. The SDK will use a default implementation if null is returned.
        // Note that you will need to set the Notification Channel on this builder when running on an Android 8.0 or
        // later device when your app targets API 26.
        return null;
    }

    public Notification.Builder prepareCommunicationForDisplay(Communication communication, Push push, int notificationId) {
        // This method will be invoked when a communicate is received for push. The caller is given a chance to
        // customize the Notification presented to the user. To do so, return a custom Notification.Builder from
        // from this method. The SDK will use a default implementation if null is returned.
        // Note that you will need to set the Notification Channel on this builder when running on an Android 8.0 or
        // later device when your app targets API 26.
        return null;
    }

Communication Accessor Methods

A Communication is defined in the Gimbal Manager portal.

Method Description
getAttributes() returns the attributes of this communication
getDescription() returns the description for this communication
getIdentifier() returns the identifier for this communication
getExpiryTimeInMillis() returns the expiration time for this communication
getTitle() returns the title for this communication
getURL() returns the url for this communication
getDeliveryDate() returns the delivery date for this communication

Visit Accessor Methods

The Vist class defines the period of time which a User dwelled at a place. A Visit without a departure time represents an active visit where the User is still dwelling at a place.

Method Description
getPlace() returns the place the visit is associated to
getArrivalTimeInMillis() returns time in milliseconds at which the User arrived at a Place
getDepartureTimeInMillis() returns time in milliseconds at which the User was considered to be departed from a Place
getDwellTimeInMillis() returns dwell time in milliseconds
getVisitID returns unique ID for visit

Place Accessor Methods

The Place class defines a place which is represented by a geofence (circular or polygonal) or a series of beacons. A place is defined in the Gimbal Manager portal.

Method Description
getIdentifier() return the unique identifier for this place as type String
getName() returns the name assigned to this place as type String
getAttributes() returns the attributes of this place as type Attributes

Attributes Interface

Method Description
getAllKeys() returns all the keys as type List<String>
getValue(String key) returns the value of the key as type String

Add Communication Listener

Description

Create and implement the CommunicationListener interface. Add the CommunicationListener to the CommunicationManager instance

Sample

import com.gimbal.android.CommunicationManager;
import com.gimbal.android.CommunicationListener;
...
    private CommunicationListener communicationListener;
...
        communicationListener = new CommunicationListener(){
            // Add CommunicationListener methods here
        }
        ...
        CommunicationManager.getInstance().addListener(communicationListener);

Note CommunicationListener interface and methods are implemented by default. To customize (ie: by receving event callbacks), please provide your own implementation for the desired communication listener methods.

Beacon Manager

The BeaconManager defines the interface for delivering beacon sightings to your Gimbal SDK enabled application. You use this class to start or stop listening for beacon sightings.


Start Listening for Beacons

Description

Allows the BeaconManager to start listening for beacon sightings.

Important Please check the following section if you are targetting android SDK 23 and above for runtime permissions checks.

Sample

import com.gimbal.android.BeaconManager;
...
        BeaconManager manager = new BeaconManager()
        manager.startListening();

Note PlaceManager and BeaconManager works independently of each other. For example, to just get place events, you'll need to start monitoring on PlaceManager only.

Stop Listening for Beacons

Description

Stops beacon listening. No beacons will be sighted.

Sample

import com.gimbal.android.BeaconManager;
...
        BeaconManager manager = new BeaconManager()
        manager.stopListening();

Beacon Event Listener

Description

This is the listener for beacon sightings. The following method will be invoked upon beacon sighting.

Beacon Method

import com.gimbal.android.BeaconEventListener;
import com.gimbal.android.BeaconSighting;
...
    public void onBeaconSighting(BeaconSighting sighting) {
        // This will be invoked upon beacon sighting
    }

BeaconSighting Accessor Methods

A Beacon is activated in the Gimbal Manager portal.

Method Description
getRSSI() returns the RSSI for the beacon sighted as type Integer
getTimeInMillis() returns the time for the beacon sighted as type Long
getBeacon() returns the beacon sighted as type Beacon

Beacon Accessor Methods

Method Description
getIdentifier() returns the unique identifier (factory ID) for this beacon as type String
getUuid() returns the 32-character UUID for this beacon as type String. This value corresponds to the beacon ID returned by the Gimbal Manager.
getName() returns the name assigned to the beacon as type String
getIconURL() returns the url of the icon assigned to the beacon as type String
getBatteryLevel() returns the battery level of the beacon as type Integer
getTemperature() returns the temperature of the beacon in Farenheit as type Integer. The value will be Integer.MAX_VALUE if no temperature sensor is present on this beacon.

Add a Beacon Event Listener

Description

Create and implement the BeaconEventListener interface. Add the BeaconEventListener to the BeaconManager instance

Sample

import com.gimbal.android.BeaconEventListener;
import com.gimbal.android.BeaconManager;
...
    private BeaconEventListener beaconEventListener;
    private BeaconManager beaconManager = new BeaconManager();
...
        beaconEventListener = new BeaconEventListener(){
            // add BeaconEventListener method here
        }
...
        beaconManager.addListener(beaconEventListener);

Beacon Configuration

For information on default beacon configurations and how to assign and push a configuration, please refer to the link provided

Beacon Configuration »

Established Locations Manager

The EstablishedLocations Manager defines the interface for enabling the Established Locations feature in the Gimbal SDK. Once enabled, Gimbal will passively monitor for locations commonly visited by the user. Each location inferred in this way is scored by a relevance value.


Check Monitoring

Description

Check if established locations has been enabled.

Sample

import com.gimbal.android.EstablishedLocationsManager;
...
        EstablishedLocationsManager.getInstance().isMonitoring();

Start Monitoring

Description

Enables the passive collection of Established Locations.

Sample

import com.gimbal.android.EstablishedLocationsManager;
...
        EstablishedLocationsManager.getInstance().startMonitoring();

Stop Monitoring

Description

Disables the passive collection of Established Locations.

Sample

import com.gimbal.android.EstablishedLocationsManager;
...
        EstablishedLocationsManager.getInstance().stopMonitoring();

Retrieve Established Locations

Description

Retrieve the Established Locations inferred by the Gimbal SDK for the user. Each Established Location contains a boundary represented by a geographical Circle (with a center latitude/longitude and radius in meters). In addition, each location is accompanied by a score representing the relevance of the location to the user. A higher score value dictates higher relevancy.

Sample

import com.gimbal.android.EstablishedLocationsManager;
import com.gimbal.android.EstablishedLocation;
...
    private EstablishedLocationsManager establishedLocationsManager;
...
        establishedLocationsManager = EstablishedLocationsManager.getInstance();
        ...
        for (EstablishedLocation establishedLocation : establishedLocationsManager.getEstablishedLocations()) {
            Log.i("Established Location", establishedLocation.toString());
        }

Established Location Accessor Methods

The EstablishedLocation class defines a commonly visited location of the user. It contains a relevancy score and a boundary defining the geographical features.

Method Description
getScore() returns the score of the EstablishedLocation; a higher score value indicates that this location is more relevant to the user
getBoundary() returns the Circle representing the boundary of the EstablishedLocation
toString() returns the attributes of the EstablishedLocation and its boundary in a String

Circle Accessor Methods

A geographical circle.

Method Description
getCenter() returns the Coordinate representing the center of the Circle
getRadius() returns the radius of the Circle, in meters

Coordinate Accessor Methods

The Coordinate class represents a latitude and longitude.

Method Description
getLatitude() returns the latitude of the Coordinate
getLongitude() returns the longitude of the Coordinate

Device Attribute Manager


Requires SDK 2.63+ The Device Attribute Manager allows you to associate attributes specific to the user of that individual device.

Set Device Attributes


Attributes can be set by passing in a map to setDeviceAttributes:. The passed in map will replace existing attributes. Passing in null or an empty map will remove the attributes associated with specific device.

import com.gimbal.android.DeviceAttributesManager;
...
        Map<String,String> attributes = new HashMap<String,String>();
        attributes.put("key1","value1");
        attribytes.put("key2","value2");
        DeviceAttributesManager.getInstance().setDeviceAttributes(attributes);

Get Device Attributes


The current attributes for a device can be retrieved through getDeviceAttributes.

import com.gimbal.android.DeviceAttributesManager;
...
        Map<String,String> attributes = DeviceAttributesManager.getInstance().getDeviceAttributes();

Reset Application Instance Identifier


Important Only use this API if you intend to reset the Application Instance Identifier for this SDK instance. Normally this is not required.

Description

This call dissociate a device and data (place events) reported by the application running on that device. The open place sightings gets closed on server. Data on device also gets cleared due to this API invocation.

Sample

import com.gimbal.android.Gimbal;
...
        Gimbal.resetApplicationInstanceIdentifier();

Runtime Permissions for Marshmallow


Description

Runtime permissions are a new feature in Android 6.0 Marshmallow that allows you to request permissions at runtime, when it matters rather than at install time. Your application which uses Gimbal SDK need to integrate runtime permissions in order to avoid any unexpected behaviour or crash. Gimbal SDK is not responsible for requesting permissions runtime. Learn more about Requesting Permissions at Run Time.

Important Applications using the Gimbal SDK must implement the runtime permissions checks in their application if their targetSdkVersion is 23 or above. The Gimbal SDK will not request runtime permissions.

Note Gimbal uses the android.permission.ACCESS_FINE_LOCATION "dangerous" permission for location services and sighting beacons. This permission is merged by default into your application's manifest from the SDK AAR manifest. If location services are not required for your use of the Gimbal SDK, it is possible to operate with just beacon sighting with the android.permission.ACCESS_COARSE_LOCATION "dangerous" permission.

The runtime permissions checks need to be made before making the startMonitoring call in PlaceManager. The PlaceManager defines the interface for delivering place entry and exits events to your Gimbal SDK enabled application and uses the location access.

import com.gimbal.android.PlaceManager;
...
        //check runtime permissions
        PlaceManager.getInstance().startMonitoring();

The runtime permissions checks need to be made before making the startListening call in BeaconManager. While the bluetooth permissions are enough to allow your legacy app to scan for beacons on Android 6.0, these permissions only allow it to do so in the foreground. Background scanning for bluetooth devices in Android 6.0, including beacons, now requires locations permission. Also, it is important to note that the location permission does not replace the need to request BLUETOOTH and BLUETOOTH_ADMIN permission

import com.gimbal.android.BeaconManager;
...
        //check runtime permissions
        BeaconManager manager = new BeaconManager()
        manager.startListening();

Runtime Permissions Checks

Depending on where you are calling the Gimbal SDK api's specifically the above mentioned(place monitoring and beacon monitoring) you will have to add some extra code in your Activity to handle the runtime permissions. The Sample application which is packaged with the SDK has a helper class which shows you how to handle it, but here's some details on what apis are available and how to achieve it.

Checking for permissions

        // Assume thisActivity is the current activity
        ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.ACCESS_FINE_LOCATION);

Make sure you use the above api to check the permissions are granted to you. If the permissions are already granted then you need not check anything else and go ahead and use the gimbal apis. If the permissions is not granted , you will have to go ahead and request it as below.

Requesting for permissions

        ActivityCompat.requestPermissions(thisActivity, new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                                          MY_LOCATION_PERMISSION_REQUEST_CODE);

This is an asynchronous call and make sure the Activity is handling the onRequestPermissionsResult callback. If you want to give a rationale or explaination to the users about why you need these runtime permissions you could use another api to leverage it. We have to make sure the user is convinced that we need runtime permissions for Gimbal SDK to function correctly.

Rationale for the permissions usage

        ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.ACCESS_FINE_LOCATION))

This method returns true if the app has requested this permissions previously and the user denied the request. Show an explanation to the user asynchronously. Don't block this thread waiting for the user's response. After the user sees the explanation, try again to request the permissions.

What will happen if permissions is revoked while application is in background?

Permissions can be revoked anytime through the phone's "Settings" application. When the Manifest.permission.ACCESS_FINE_LOCATION permission is revoked, PlaceManager will not be able to generate any place events in foreground or in the background. Whereas the BeaconManager will be able to generate events only when the application is in the foreground. Applications using Gimbal SDK should check for Manifest.permission.ACCESS_FINE_LOCATION permission when the application comes in the foreground and request for the permission to be granted and handle gracefully if the permissions are denied. Please follow "Permissions Best Practices" guide provided by Google here for more information.

Enable Sightings Logging


Description

Enables beacon sighting logs. These logs gives more information about beacon sightings your application is currently seeing. Use 'SIGHTINGS' keyword as a filter in your LOGCAT to see the relevant logs.

Sample

        GimbalDebugger.enableBeaconSightingsLogging();

Disable Sightings Logging


Description

Disables beacon sighting logs

Sample

        GimbalDebugger.disableBeaconSightingsLogging();

Check if Sightings Logging is enabled


Description

Checks if sightings logging is enabled

Sample

        GimbalDebugger.isBeaconSightingsLoggingEnabled();

Appendix


Migration from Gimbal SDK Version V2 to V3

The driving change behind the version 3 release is support for Android 8.0 Oreo. In addition to structural changes required by Android 8.0, we added support for custom Notification Channels and greatly reduced the amount of setup required for new apps. Existing apps need to make a few changes to how the Gimbal SDK gets initialized.

Update Dependencies

In addition to changing our artifacts' versions, we changed the Group ID to signal that this change will a bit of additional work from developers.

In your app's build.gradle change the Gimbal dependency package names to com.gimbal.android.v3 from com.gimbal.android.v2. Your dependency block will look something like this (with version:'3.0' being current at the time of this writing):

dependencies {
    ...
    compile group:'com.gimbal.android.v3', name:'gimbal-sdk', version:'3.0'
    compile group:'com.gimbal.android.v3', name:'gimbal-slf4j-impl', version:'3.0'
    ...
}

Migrate SDK Invocation from Background Service to Application

Previous versions of the Gimbal SDK worked best when invoked from a background service, but this approach is no longer viable in Android 8.0. Now the best way to get Gimbal started is from within your Application's onCreate() method.

The Gimbal Sample App (bundled within the SDK zip downloadable from Gimbal Manager) has an example of how this can be done. Instead of initializing Gimbal from within your service's onCreate(), the same initialization code is moved within the GimbalIntegration class. This is then initialized and invoked from the application's onCreate().

Clean AndroidManifest.xml

We bundled several elements into our manifest so that they automatically get merged into your app manifest at build time. Remove the following service and receiver elements from your manifest:

  • com.gimbal.internal.service.GimbalService
  • com.gimbal.internal.service.GimbalServiceStartStopReceiver

We also put our uses-permission elements into our manifest. Your own code may have a requirement for some of them, e.g. android.permission.INTERNET, in which case you will need to keep them in your manifest. But the rest you can safely remove because they will be automatically merged in at build time:

  • android.permission.INTERNET
  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.ACCESS_WIFI_STATE
  • android.permission.WAKE_LOCK
  • android.permission.ACCESS_NETWORK_STATE
  • android.permission.RECEIVE_BOOT_COMPLETED
  • android.permission.BLUETOOTH
  • android.permission.BLUETOOTH_ADMIN

Clean ProGuard rules

Similar to what we did with the manifest, we also automatically merge in the ProGuard rules required to keep our stuff working if/when you optimize and obfuscate your APK.

Remove the Gimbal-specific parts:

-keep public interface com.gimbal.proguard.Keep { }
-keep public class ** implements com.gimbal.proguard.Keep { *; }
-keep public class **.protocol.** { public protected *; }

And remove the other options, unless you have a requirement for them in your own code:

-keepattributes Signature
-keep public class org.codehaus.jackson..** { public protected *; }
-dontwarn org.codehaus.**,com.fasterxml.**,org.simpleframework.**,com.google.**,org.apache.**

Set a NotificationChannel (Optional)

Android 8.0 adds a Notification Channel feature to grant end users finer control over the notifications that are presented to them by apps. Each Notification on an 8.0 device in an app targeting API 26 or newer must be assigned to a channel or it will not post to the user.

The CommunicationManager adds a new setNotificationChannelId() method for the developer to specify what channel to be used by Gimbal default Notifications. The Gimbal SDK provides three usage modes:

  • The developer returns a Notification.Builder from prepareCommunicationForDisplay in a CommunicationListener.

    Important If your app already does this, a channel ID must now be set in the Builder, and the developer is responsible for creating and managing that channel. The Gimbal SDK will not create a channel for use with developers' Builders.

  • Else if a Builder is not returned, the Gimbal SDK creates a default Notification. The developer creates and manages a channel and specifies its use in the default Notification via setNotificationChannelId().

  • Else if the developer does not specify a channel, the Gimbal SDK will create and manage its own channel. No changes are necessary for notifications to post to the user in this mode.