Android Getting Started

Prerequisites

The TapPoint SDK is built to be used with Gradle and Maven. For this guide we have used Android Studio. If you need support for other IDEs then please email support@proxama.com.

NOTE: You'll need an Android device running 4.3.x or higher and which also supports the Bluetooth 4.0 profile to receive beacon events. If the device doesn't have Bluetooth 4.0, or is running a version of Android lower than 4.3.x it will still be able to synchronize data. The SDK will run with Android 4.0 onwards.

Installing the SDK

You can download the example reference app from here. This app will register and sync with TapPoint, then scan for three beacons with the major of 1 and the minors of 1-3. When a beacon is seen it will display the beacon details and produce a notification.

Download

To download and use the SDK, firstly add the Maven repository to your project.

repositories {
    jcenter()

    maven {
        url "http://proxama.bintray.com/tappoint"
    }
}

Then to resolve the SDK, add the following to your Gradle build.

compile 'com.proxama:tappoint-sdk:3.2.2'

Permissions

The TapPoint SDK uses the following permissions to sync and scan for triggers:


<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Used to access the Bluetooth hardware and to scan for BLE beacons nearby.


<uses-permission android:name="android.permission.INTERNET"/>

Used to communicate with TapPoint.


<uses-permission android:name="android.permission.WAKE_LOCK"/>

Used to ensure that beacon processing is completed. When a wake-lock is used it is normally held for a very small amount of time (approx. 10-120ms).


<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Used for reporting various network states such as WiFi.


<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETE"/>

Used to ensure beacon scanning resumes after the phone has been rebooted.


Inside the <application> block add the following provider:

<provider
	android:name="com.proxama.trigger.ble.model.dao.BleTriggerProvider"
	android:authorities="com.proxama.tpsdkreferenceapp.bletriggerprovider"
	android:exported="false">
</provider>

NOTE: You will need to update the BleTriggerProvider authority to use your full app package name. For example, if your package was com.example.app then you need to declare the following:

android:authorities="com.example.app.bletriggerprovider"

Using the SDK

The TapPoint SDK has a set of APIs that you can use to:

  1. Authenticate your application with TapPoint
  2. Download Triggers (campaign data and campaign Payload)
  3. Start monitoring for beacons

NOTE: All API calls made are asynchronous and when they complete, will always return to the UI thread.

Authenticating with TapPoint

To ensure your application can retrieve and interact with Triggers, you should make sure that you have authenticated before interacting with any other API.

Import the following classes to authenticate with TapPoint:

import com.proxama.tappoint.auth.AuthListener;
import com.proxama.tappoint.auth.Authentication;
import com.proxama.tappoint.error.ApiError;

It is recommended that you call this API in your Activity's onCreate method. Pass in the application name provided by Proxama and a listener to be informed of the result.

Call the authenticate method on the AuthManager to authenticate with TapPoint:

Authentication.getAuthManager(this).authenticate(APP_NAME, this);

This API should be called every time your application launches to ensure that other APIs being called can be used. Implement the AuthListener interface to determine the result of the authentication request:

@Override
public void onAuthSuccess() {
    Toast.makeText(this, "Auth successful", Toast.LENGTH_LONG).show();
}

@Override
public void onAuthFailure(ApiError apiError) {
    Toast.makeText(this, "Auth failed: " + apiError.name(), Toast.LENGTH_LONG).show();
    Log.d(TAG, apiError.getErrorMessage());
}

Synchronising Triggers

One of the advantages of using TapPoint SDK is that it delivers campaign data even in areas of no connectivity (underground, stadiums). Triggers, which encapsulate campaign data, are required to be synced down to the SDK prior to a campaign starting.

For testing purposes we've sent 3 physical beacons to help you with your integration (or if you have an iOS device you can use our Virtual Beacon app to simulate a beacon). To add campaign data to these Triggers use the TapPoint Beacon Payload Editor tool.

Import the following classes:

import com.proxama.tappoint.sync.SyncListener;
import com.proxama.tappoint.sync.SyncResult;
import com.proxama.tappoint.sync.Synchronisation;

Call the synchronise method on the SyncManager to sync the trigger data from TapPoint:

Synchronisation.getSyncManager(this).synchronise(this);

Implement the SyncListener interface to determine the result of the synchronisation request:

@Override
public void onSyncSuccess(SyncResult syncResult) {
    int numberAdded = syncResult.getTriggersAdded().size();
    int numberRemoved = syncResult.getTriggersRemoved().size();

    Toast.makeText(this, "Sync successful. Added triggers: " + numberAdded + ". Removed triggers: " +
            numberRemoved, Toast.LENGTH_LONG).show();
}

@Override
public void onSyncFailure(ApiError apiError) {
    Toast.makeText(this, "Sync failed: " + apiError.name(), Toast.LENGTH_LONG).show();
}

Upon successful synchronisation with TapPoint, the success callback provides a SyncResult object that contains arrays of both Triggers that have been added, and Triggers that have been removed during this synchronisation. This is purely for your information, the Triggers will be automatically stored by the TapPoint SDK. In the instance where synchronisation has failed, you can inspect the ApiError object to find out the reason for failure where both an error code and error description is provided.

Synchronisation Strategy

Once Triggers have been successfully synced onto the device, you do not have to sync again, unless the Trigger data on TapPoint has changed (e.g. a new campaign has been created). It is up to you to decide when and how often a sync should take place.

A simple syncing strategy would be to perform a synchronisation with TapPoint every time your application launches.

Trigger Monitoring

Import the following class:

import com.proxama.tappoint.trigger.Triggers;

Call startMonitoring on the TriggersManager to begin scanning for Triggers:

Triggers.getTriggersManager(this).startMonitoring();

NOTE: If you are monitoring for Trigger events, any new triggers subsequently added will automatically be monitored.

NOTE: Trigger events can only be detected and notifications sent when the user has both Bluetooth turned on and support for Bluetooth 4.0. If the user should turn off Bluetooth scanning will pause and automatically start monitoring once it is turned on again. There is no need to call startMonitoring again to to resume monitoring.

If you wish to stop monitoring for trigger events, call the stopMonitoring method:

Triggers.getTriggersManager(this).stopMonitoring();
Receiving Trigger Events

The TapPoint SDK delivers your campaign data by sending a broadcast message to your application when an event is triggered (e.g. coming in range of a beacon). Using this mechanism rather than a callback listener allows your application to be notified of a Trigger event even when it is closed.

There are two main ways your app could receive beacon Trigger events. Either by using a dynamic broadcast receiver, or declaring a broadcast receiver in the manifest. The first method will enable events to be received when the app is open, the latter will ensure that events are received even when the app is closed.

Receiving events in the foreground

To dynamically receive beacon events, import the following classes to receive notifications when the application is open:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import com.proxama.tappoint.trigger.Trigger;

To listen for Trigger events:

private class BeaconEventReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (Triggers.ACTION_TRIGGERS_DETECTED.equals(intent.getAction())) {
            ArrayList<Trigger> triggers = intent.getParcelableArrayListExtra(Triggers.EXTRA_DETECTED_TRIGGERS);
            Log.d(TAG, "Received " + triggers.size() + " events.");
        }
    }
}

Then enable and disable the BroadcastReceiver in onResume and onPause, respectively. Make sure that the receiver is listening for the correct action:

com.proxama.tappoint.action.ACTION_TRIGGERS_DETECTED
Receiving events in the background

If it is required to receive beacon events even when the app is closed, a BroadcastReceiver can be declared in the manifest. This will ensure that your receiver will have access to every beacon event when they happen. To receive beacon events, add the intent filter to your receiver in the manifest:

<receiver android:name="com.proxama.tpsdkreferenceapp.BleTriggerReceiver">
    <intent-filter>
        <action android:name="com.proxama.tappoint.action.ACTION_TRIGGERS_DETECTED"/>
    </intent-filter>
</receiver>

Then handle the beacon events in your BroadcastReceiver:

@Override
public void onReceive(Context context, Intent intent) {
    if (Triggers.ACTION_TRIGGERS_DETECTED.equals(intent.getAction())) {
        ArrayList<Trigger> triggers = intent.getParcelableArrayListExtra(Triggers.EXTRA_DETECTED_TRIGGERS);

        Log.d(TAG, "Received " + triggers.size() + " events.");
    }
}
Handling beacon events

The list of Triggers passed back to you will contain the original campaign data you supplied at the time of creation. From this, you will be able to process each Trigger in the way best suited for your app.

Next Steps