Android Version 4 API Developer Guide

The Gimbal SDK V4 adds support for Firebase Cloud Messaging (FCM) and removes support for Google Cloud Messaging (FCM). This is necessitated by Google's deprecation and removal of GCM as soon April 11, 2019.

If your app currently uses Gimbal SDK V3 and uses GCM for Time-triggered or Instant Communications (push notifications), you will need to migrate to V4 in order for it to operate after GCM is removed. Please refer to our V3 to V4 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.

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

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()
    google()
    ...
}

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

dependencies {
    ...
    implementation 'com.gimbal.android.v4:gimbal-sdk:4.0.1'
    implementation 'com.gimbal.android.v4:gimbal-slf4j-impl:4.0.1'
    implementation 'com.google.android.gms:play-services-ads-identifier:16.0.0'
    implementation 'com.google.android.gms:play-services-location:16.0.0'
    implementation 'com.google.firebase:firebase-messaging:17.4.0'
    ...
}

Version 4.0.1 is the current SDK V4 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'
    }
    google()
}

dependencies {
    ...
    compile(name:'gimbal', ext:'aar')
    compile(name:'gimbal-slf4j-impl', ext:'aar')
    compile 'org.slf4j:slf4j-api:1.7.13'
    implementation 'com.google.android.gms:play-services-ads-identifier:16.0.0'
    implementation 'com.google.android.gms:play-services-location:16.0.0'
    implementation 'com.google.firebase:firebase-messaging:17.4.0'
    ...
}

External Dependencies

Firebase and Google Play Services

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

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

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

  • firebase-messaging - enables push notifications for Communication delivery

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 an implementation 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

For the most reliable operation, the Gimbal SDK should 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 new Android application. You will also need to select option for Android 4.4.3 and 4.4.4 (Kitkat support).

Important If you require beacon functionality, and are testing with an Android device running version 4.4.3/4.4.4, or want to support end users running these versions, you must enable Kitkat support.

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.

Push Communications

Gimbal uses Firebase Cloud Messaging push notifications to enable Time-triggered and Instant Communications.

Set Up Firebase Cloud Messaging

Gimbal uses Firebase Cloud Messaging (FCM) to enable push on Android. In order to use FCM you'll have to setup your application on Firebase Console and obtain a google-services.json file and the Server key for the 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:

  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. From the General tab, add an Android app to your project by clicking on the Android icon. You will be presented with a new form to enter information about your app.

  5. In Step 1, enter the package name that you chose for your Gimbal-enabled Android app.

  6. In Step 2, download the google-services.json file to your app module's root directory, as directed.

  7. In Step 3, follow the directions to add the FCM dependency and to let your app load information from the google-services.json file you downloaded in the previous step.

  8. In Step 4, you may run your app to verify successful installation of Firebase into your app, or you may click on "Skip this step".

  9. Back in the app settings screen, select the Cloud Messaging tab, where you can find your server key. 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 google-services.json file from Firebase Console.

Add Google/Firebase Server API Key to Gimbal Manager

In Gimbal Manager, select your existing Android application and select the Push Configuration tab. Enter the Server Key copied from the Firebase Console into the Cloud Messaging Key entry and press Save Push Configuration. Now your application is set to send push messages!

Enable Push Communications

Description

In your application, a call to Gimbal.enablePushMessaging(true) enables an Android Service provided by the Gimbal SDK that receives push messages and registration tokens from Firebase. This method only needs to be called once per application instance — the state is remembered across restarts. It may not be called before Gimbal.setApiKey().

If migrating an existing app from the V3 Gimbal SDK, and a sender ID had been set with Gimbal.registerForPush(), then the V4 SDK will automatically enable push messaging without a call to enablePushMessaging(), given that FCM setup was successful.

Note Changing the enabled state may not take effect until the next app restart. This is not considered a reliable method of toggling handling of Communications on the client. Instead consider starting and stopping the CommunicationManager or filtering individual Communications with your CommunicationListener.

Tip Because of the possibility of push not enabling until app restart, developers who uninstall and reinstall frequently may want to explicitly enable Gimbal's FCM service in their manifest. This will allow push messages to be received immediately after Communications are started and push messaging is enabled with Gimbal.enablePushMessaging(true).

    <service android:name="com.gimbal.internal.push.FcmListenerService"
        android:enabled="true"
        tools:replace="android:enabled" />        

Receive Push Content

Whenever a push is sent to the client, Gimbal will call the CommunicationListener method shouldPresentNotificationForCommunications. 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
}

Send Push Communication On Gimbal Manager

Send Instant Communication

Instant Communications 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 Communication

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 should 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 V3 to V4

Google has deprecated Google Cloud Messaging (GCM) and may end support for it as soon as April 11, 2019. They have provided a migration path to Firebase Cloud Messaging (FCM). Gimbal SDK V3 for Android and earlier use GCM to enable Instant and Time-triggered Communications. In order to continue this functionality, the Gimbal SDK V4 has been modified to work with FCM.

If your app uses Instant and/or Time-triggered Communications, read on. If not, you may safely ignore this migration guide, as there are no other API changes in the V4 release.

Gimbal will be transitioning its servers to use FCM before the cutoff date. Before the cutoff date, existing app instances running the V3 SDK will continue to receive Communications as the "legacy" GCM tokens will continue to work with the new FCM system. After the cutoff date, push capabilities may be lost for clients still running the V3 SDK.

Migration Steps

Note The following steps assume that you obtained your sender id and cloud messaging key from a Firebase project. Some developers may have set up their Gimbal app with a Google Cloud Platform project instead. To proceed, the project must first be migrated into Firebase. Contact Gimbal support if assistance is required.

  1. Add the google-services plugin to your root-level build.gradle file:

    buildscript {
        // ...
        dependencies {
            // ...
            classpath 'com.google.gms:google-services:4.2.0' // google-services plugin
        }
    }
    
    allprojects {
        // ...
        repositories {
            google() // Google's Maven repository
            // ...
        }
    }
    
  2. Replace the GCM dependency with the FCM dependency, and apply the google-services plugin in your app module's build.gradle file:

    dependencies {
        // ...
        // implementation com.google.android.gms:play-services-gcm:11.0.4' << REMOVE THIS
        implementation 'com.google.firebase:firebase-messaging:17.4.0' // << ADD THIS
    }
        
    // ADD THIS AT THE BOTTOM
    apply plugin: 'com.google.gms.google-services'
    
  3. Download the google-services.json file from your Firebase app, and copy it to your app module's root-level directory.

  4. Replace call to Gimbal.registerForPush() with Gimbal.enablePushMessaging().