What you will learn

This step-by-step tutorial will teach you how to create your first Custom Alert Strategy, by extending the BeaconAlertStrategy object.

You will code a TimeAlertStrategy: this strategy will allow you to trigger an alert associated to a beacon, if the beacon is detected by a smartphone for 60 seconds or more.

Pre-requisites - What you need to get started

  • A Nexus Account: the SDK is available through a private Nexus. You must have received an email with your user account, including a link to create a password
  • Your SDK user information: in order to initialize the Mobile SDK, you must have received a User Name, a Password and a Company
  • A BLE beacon: a BLE beacon configured on your account is mandatory to test the application
  • An Android Device: you need a compatible Bluetooth Low Energy Android device that is able to detect beacons
  • The Android Studio application: you must have downloaded Android Studio from the Android Developpers’ website
  • You must have read the alert process tutorial and completed the alert tutorial

Two ways to code a Beacon Alert Strategy

There are two ways you can code a Beacon Alert Strategy:

  • Option #1 - Implementing the BeaconAlertStrategyListener interface: The BeaconAlertStrategyListener interface allows you to implement the complete strategy process, giving you control over the beacon objects but implying that you maintain their lifecycle (initializations, updates...).

  • Option #2 - Extending the BeaconAlertStrategy object: Extending the BeaconAlertStrategy object saves you time because you extend a source code base that already manages the initialization and update processes.

Because the latter fits the majority of needs, this tutorial will essentially focus on Option #2. Nevertheless, you can find an implementation for Option #1 in the source code for this tutorial (called TimeAlertStrategyFirstWay).

About the SDK model

Overview of the BeaconAlertStrategyListener interface

Prior to discussing implementation, let's take a deeper look at the methods of this interface.

    void updateBeaconContent(BeaconContent beacon);

    Class <extends BeaconAlertStrategyParameter> getBeaconAlertParameterClass();

    String getStrategyKey();

    boolean isConditionValid(BeaconAlertStrategyParameter beaconAlertStrategyParameter);

    boolean isReadyForAction(BeaconAlertStrategyParameter beaconAlertStrategyParameter);

Let's take a quick look at each one:

  void updateBeaconContent(BeaconContent beacon);
  • This method is called every time a beacon range scan is occurring (as a reminder, this only happens if the alert listener has been registered), and updates the Beacon Alert Strategy Parameter object associated to the Beacon Content object.
  Class <extends BeaconAlertStrategyParameter> getBeaconAlertParameterClass();
  • This method will permit to create the correct Beacon Alert Parameter for the Beacon Alert Strategy
    String getStrategyKey();
  • This method returns the String Key associated to the Alert Strategy that was created
  • You must add this key to the appropriate custom alert field on the Adtag platform
    boolean isConditionValid(BeaconAlertStrategyParameter beaconAlertStrategyParameter);
  • This method returns true if the conditions to display an alert are met.
    boolean isReadyForAction(BeaconAlertStrategyParameter beaconAlertStrategyParameter);
  • This method returns true if an alert can be triggered on this beacon.

Overview of the BeaconAlertStrategy object

The BeaconAlertStrategy object is an abstract class that implements most of the BeaconAlertStrategyListener methods.

The BeaconAlertStrategy object implements the following methods by default:

  • updateBeaconContent
  • getBeaconAlertParameterClass: returns a BeaconAlertParameter class as default.
  • isReadyForAction: returns true if the isConditionValid parameter is set to true, and the actionStatus parameter is at 'Waiting For Action'.

You also have to manually implement the three following additional methods:

  • getStrategyKey: from the BeaconAlertStrategyListener
  • updateAlertParameter: allows to update the Beacon Alert Strategy Parameter object associated to a beacon.
    • The BeaconAlertStrategyParameter calls this method before the isConditionValid method
    • this means the BeaconAlertStrategyParameter object transmitted to the isConditionValid method is up to date.
  • isConditionValid: from the BeaconAlertStrategyListener

The BeaconAlertStrategy object comes with a constructor with one parameter : maxTimeBeforeReset

   new BeaconAlertStrategy(maxTimeBeforeReset)

The maxTimeBeforeReset parameter allows to determine how long after the beacon stops being detected, the actionStatus parameter is automatically reset to Waiting for Action.

Note :

If necessary, you can override the 3 default methods of the BeaconAlertStrategyListener interface.

Step 1: Clone the sdk-tutorial repository

  • Clone the sdk-tutorial repository
git clone https://github.com/Connecthings/sdk-tutorial.git
  • Open the android>beacon>9-Alert-Strategy>Starter project with Android Studio

Step 2: Configure your SDK

  • Open the ApplicationAlert class

  • Configure your SDK with:

    • the UUID of your beacon
    • the appropriate Adtag Environment
    • your login, password, and company details you received from Connecthings

For more information, refer to the 5-minute Quickstart tutorial on configuring the SDK.

Step 3: Create a TimeAlertStrategyParameter object

The TimeAlertStrategyParameter object extends the BeaconAlertStrategyParameter object.

The BeaconAlertStrategyParameter object synchronizes and centralizes all of the information regarding a specific beacon and associated alerts. For more information, please read the alert process tutorial.

The TimeAlertStrategyParameter allows to save two additional parameters:

  • timeToShowAlert: indicates the time when the application can start to display an alert
  • lastDetectionTime: indicates the last time the beacon was detected by a smartphone

Now let's start coding the TimeAlertStrategyParameter:

  • Create a TimeAlertStrategyParameter object that extends the BeaconAlertStrategyParameter object.
public class TimeAlertStrategyParameter extends BeaconAlertStrategyParameter{
}
  • Add the timeToShowAlert and lastDetectionTime parameters, with their dedicated getter and setter.
public class TimeAlertStrategyParameter extends BeaconAlertStrategyParameter{

    private long timeToShowAlert;
    private long lastDetectionTime;

public long getTimeToShowAlert() {
        return timeToShowAlert;
    }

    public void setTimeToShowAlert(long timeToShowAlert) {
        this.timeToShowAlert = timeToShowAlert;
    }

    public long getLastDetectionTime() {
        return lastDetectionTime;
    }

    public void setLastDetectionTime(long lastDetectionTime) {
        this.lastDetectionTime = lastDetectionTime;
    }
}
  • Make the class parcelable compatible:
public class TimeAlertStrategyParameter extends BeaconAlertStrategyParameter{

    [..]
    protected TimeAlertStrategyParameter(Parcel from){
        super(from);
    }
    
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeLong(timeToShowAlert);
    }

    public void readFromParcel(Parcel from) {
        super.readFromParcel(from);
        timeToShowAlert = from.readLong();
        lastDetectionTime = from.readLong();
    }

    public static final Creator<TimeAlertStrategyParameter> CREATOR = new Creator() {
        public BeaconAlertStrategyParameter createFromParcel(Parcel in) {
            return new TimeAlertStrategyParameter(in);
        }

        public TimeAlertStrategyParameter[] newArray(int size) {
            return new TimeAlertStrategyParameter[size];
        }
    };
}

Note:

The BeaconAlertStrategyParameter implements the Parcelable interface.

Step 4: Create an AlertTimeStrategySecondWay class

  • Create a TimeAlertStrategySecondWay class that extends the BeaconAlertStrategy class:
public class TimeAlertStrategySecondWay extends BeaconAlertStrategy{
}
  • Add a constructor that allows to define the amount of time a beacon must be detected by the smartphone before triggering an alert
public class TimeAlertStrategySecondWay extends BeaconAlertStrategy{

    public TimeAlertStrategySecondWay(int maxTimeBeforeReset, long timeBeforeCreatingAlert) {
        super(maxTimeBeforeReset);
        this.timeBeforeCreatingAlert = timeBeforeCreatingAlert;
    }

}
  • Override the getBeaconAlertParameterClass method to associate the TimeAlertStrategyParameter to the TimeAlertStrategy.
@Override
    public Class<? extends BeaconAlertStrategyParameter> getBeaconAlertParameterClass() {
        return TimeAlertStrategyParameter.class;
    }
  • Define the key for the strategy:
public String getStrategyKey() {
	return "timeAlertStrategy";
}

Note:

This key will enable you to associate the strategy to a beacon on the Adtag Platform, using the 'Your custom strategy' field. Learn more in "Updating the alert content on the Adtag platform"

  • Update the timeToShowAlert and the lastDetectionTime parameters in the TimeAlertStrategyParameter
    @Override
    public void updateAlertParameter(BeaconContent beaconContent) {
        TimeAlertStrategyParameter timeAlertStrategyParameter = (TimeAlertStrategyParameter) beaconContent.getBeaconAlertStrategyParameter();
        //if the beacon is not detected for 3 sec or more, then it is considered to be a new zone entry
        //because scanning is performed every 1.1 sec and a beacon is kept in cache for over 10s.
        long currentTime = SystemClock.elapsedRealtime();
        if(timeAlertStrategyParameter.getLastDetectionTime() + 3000 < SystemClock.elapsedRealtime()){
            timeAlertStrategyParameter.setTimeToShowAlert(currentTime + timeBeforeCreatingAlert);
        }
        timeAlertStrategyParameter.setLastDetectionTime(currentTime);
    }
  • Define the conditions when the beacon fits the strategy:
    @Override
    public boolean isConditionValid(BeaconAlertStrategyParameter beaconAlertStrategyParameter) {
        TimeAlertStrategyParameter timeAlertStrategyParameter = (TimeAlertStrategyParameter) beaconAlertStrategyParameter;
        return timeAlertStrategyParameter.getTimeToShowAlert() < SystemClock.elapsedRealtime();
    } 

Step 5: Add the TimeAlertStrategy to the AdtagManager

In order to enable the SDK to apply a strategy to a beacon (assuming it has been properly configured in Adtag), you must register this strategy on the AdtagBeaconManager.

  • Open the ApplicationAlert class

  • Register the TimeAlertStrategySecondWay on the AdtagBeaconManager, at the end of the onCreate method

    public void onCreate(){
        super.onCreate();
        [...]
        //Register your additional strategy
        beaconManager.addAlertStrategy(new TimeAlertStrategySecondWay(30000 , 60000));
    }
  • Last but not least, go to Adtag and populate a beacon's Your Custom Strategy field with this key to start testing.

Step 6: Start testing

  1. From Android Studio, launch the installation process of the application you have just built on your mobile phone.

  2. Activate your beacon

  3. Wait 60 seconds

  4. The title of the alert appears, as defined in Adtag, along with a button and the following text: Click to get more information.

  5. Click on the button and access the detailed content of the alert.