Android – Programming a minimal Point SDK-enabled app

Introducing ServiceManager

ServiceManager is the entry-point for an app to start using Point SDK.

The first step is to start Bluedot Point Service by calling the sendAuthenticationRequest method on the shared instance of ServiceManager with an API key from Point Access as a parameter. Navigate to “App and Beacon Management” in your account to get your API key.

Starting the Bluedot Point Service requires that the device is connected to the internet via a mobile data network or Wi-Fi access point.

A custom URL can also be passed in as a parameter for authentication if the app needs to connect to an alternate Bluedot back-end. Custom URLs should only be used for debugging and support purposes.

In most cases, it is required that the SDK be initialized in App Restart mode to ensure that the Bluedot Service will be restarted if it is terminated by the Android OS. Please refer to the App Restart section for more details.

Please note: These callbacks should be thread-safe and should not update UI views directly. If a UI view needs to be updated from within the callback, it must be wrapped into runOnUiThread or a Handler.

It is recommended that you integrate the Bluedot Point SDK at the Application class level, as Application is the most commonly used singleton class and the Application lifecycle covers the availability of this class throughout the life of the application. It is also possible, depending on the particular application structure, to implement the ServiceStatusListener and ApplicationNotificationListener with an Activity, Service or Fragment as shown in the integration examples below:

@Override public void onBlueDotPointServiceStartedSuccess() {
// This is called when BlueDotPointService started successfully
// Your app logic can start from here
}
@Override public void onBlueDotPointServiceStop() {
// This will be called when BlueDotPointService has been stopped.
// Your app could release resources that use the BlueDotPointService
}
@Override public void onBlueDotPointServiceError(BDError error) {
// This gives you details if BlueDotPointService encounters an error.
// Human-readable string of bdError.getReason() can be useful to analyse the cause of the error.
// Boolean bdError.isFatal() identifies if error is fatal and BlueDotPointService is no more functional;
// onBlueDotPointServiceStop() callback is invoked next in such a case.
}
@Override public void onRuleUpdate(List zoneInfos) {
// Passively receive Zones information
// Optional
}
@Override public void onCheckIntoFence(FenceInfo fenceInfo, ZoneInfo zoneInfo, LocationInfo location, Map<String, String> customData, boolean isCheckOut) {
// This method will be called if the device checked into a Fence
// and the zone contains a custom action
// Using a handler to pass Runnable into UI thread to interact with UI elements
}
@Override public void onCheckedOutFromFence(FenceInfo fenceInfo, ZoneInfo zoneInfo, int dwellTime, Map<String, String> customData) {
// This method will be called when a device leaves the Fence that was checked into. Only applies to zones flagged as checkout enabled on the backend.
}
@Override public void onCheckIntoBeacon(BeaconInfo beaconInfo, ZoneInfo zoneInfo, LocationInfo location, Proximity proximity, Map<String, String> customData, boolean isCheckOut) {
// This will be called if the trigger happened on a Beacon
// and the zone contains a custom action
// Using runOnUiThread to interact with UI Elements within UI Thread
}
@Override public void onCheckedOutFromBeacon(BeaconInfo beaconInfo, ZoneInfo zoneInfo, int dwellTime, Map<String, String> customData) {
// This method will be called when a device Checks out of a Beacon
}
}

public class BDTestActivity extends Activity implements ServiceStatusListener, ApplicationNotificationListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// Get an instance of ServiceManager to access the Bluedot Point Service
serviceManager = ServiceManager.getInstance(this);
//Check for location permissions, before authenticating the SDK
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//Check the Bluedot Point Service is currently running, otherwise start it
if(!serviceManager.isBlueDotPointServiceRunning()){
// Setting Notification for foreground service, required for Android Oreo and above.
String channelId = "";
String channelName = "";
NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
...
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(notificationChannel);
Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext(), channelId)
...
Notification notification = notificationBuilder.build();
// Setting targetAllAPIs to TRUE will display foreground notification for Android versions lower than Oreo
serviceManager.setForegroundServiceNotification(notification, false);
serviceManager.sendAuthenticationRequest("<api key>",this);
}
}
}
@Override
public void onBlueDotPointServiceStartedSuccess() {
// This is called when BlueDotPointService started successfully
// Your app logic can start from here
}
@Override
public void onBlueDotPointServiceStop() {
// This will be called when BlueDotPointService has been stopped.
// Your app could release resources that use the BlueDotPointService
}
@Override
public void onBlueDotPointServiceError(BDError error) {
// This gives you details if BlueDotPointService encounters error.
// Human-readable string of bdError.getReason() can be useful to analyse the cause of the error.
// Boolean bdError.isFatal() identifies if error is fatal and BlueDotPointService is no more functional;
// onBlueDotPointServiceStop() callback is invoked next in such a case.
}
@Override
public void onRuleUpdate(List zoneInfos) {
// Passively receive Zones information
// Optional
}
@Override
public void onCheckIntoFence(FenceInfo fenceInfo, ZoneInfo zoneInfo, LocationInfo location, Map<String, String> customData, boolean isCheckOut) {
// This method will be called if the device checked into a Fence
// and the zone contains a custom action
// Using a handler to pass Runnable into UI thread to interact with UI elements
}
@Override
public void onCheckedOutFromFence(FenceInfo fenceInfo, ZoneInfo zoneInfo, int dwellTime, Map<String, String> customData) {
// This method will be called when a device leaves the Fence that was checked into. Only applies to zones flagged as checkout enabled on the backend.
}
@Override
public void onCheckIntoBeacon(BeaconInfo beaconInfo, ZoneInfo zoneInfo, LocationInfo location, Proximity proximity, Map<String, String> customData, boolean isCheckOut) {
// This will be called if the trigger happened on a Beacon
// and the zone contains a custom action
// Using runOnUiThread to interact with UI Elements within UI Thread
}
@Override
public void onCheckedOutFromBeacon(BeaconInfo beaconInfo, ZoneInfo zoneInfo, int dwellTime, Map<String, String> customData) {
// This method will be called when a device Checks out of a Beacon
}
}

public class BDTestService extends Service implements ServiceStatusListener, ApplicationNotificationListener {
@Override
public void onCreate() {
super.onCreate();
...
// Get an instance of ServiceManager to access the Bluedot Point Service
serviceManager = ServiceManager.getInstance(this);
//Check for location permissions, before authenticating the SDK
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//Check the Bluedot Point Service is currently running, otherwise start it
if(!serviceManager.isBlueDotPointServiceRunning()){
// Setting Notification for foreground service, required for Android Oreo and above.
String channelId = "bluedot";
String channelName = "Bluedot Service";
NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
...
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(notificationChannel);
Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext(), channelId)
...
Notification notification = notificationBuilder.build();
// Setting targetAllAPIs to TRUE will display foreground notification for Android versions lower than Oreo
serviceManager.setForegroundServiceNotification(notification, false);
serviceManager.sendAuthenticationRequest("<api key>",this);
}
}
}
@Override
public void onBlueDotPointServiceStartedSuccess() {
// This is called when BlueDotPointService started successfully
// Your app logic can start from here
}
@Override
public void onBlueDotPointServiceStop() {
// This will be called when BlueDotPointService has been stopped.
// Your app could release resources that use the BlueDotPointService
}
@Override
public void onBlueDotPointServiceError(BDError error) {
// This gives you details if BlueDotPointService encounters error.
// Human-readable string of bdError.getReason() can be useful to analyse the cause of the error.
// Boolean bdError.isFatal() identifies if error is fatal and BlueDotPointService is no more functional;
// onBlueDotPointServiceStop() callback is invoked next in such a case.
}
@Override
public void onRuleUpdate(List zoneInfos) {
// Passively receive Zones information
// Optional
}
@Override
public void onCheckIntoFence(FenceInfo fenceInfo, ZoneInfo zoneInfo, LocationInfo location, Map<String, String> customData, boolean isCheckOut) {
// This method will be called if the device checked into a Fence
// and the zone contains a custom action
// Using a handler to pass Runnable into UI thread to interact with UI elements
}
@Override
public void onCheckedOutFromFence(FenceInfo fenceInfo, ZoneInfo zoneInfo, int dwellTime, Map<String, String> customData) {
// This method will be called when a device leaves the Fence that was checked into. Only applies to zones flagged as checkout enabled on the backend.
}
@Override
public void onCheckIntoBeacon(BeaconInfo beaconInfo, ZoneInfo zoneInfo, LocationInfo location, Proximity proximity, Map<String, String> customData, boolean isCheckOut) {
// This will be called if the trigger happened on a Beacon
// and the zone contains a custom action
// Using runOnUiThread to interact with UI Elements within UI Thread
}
@Override
public void onCheckedOutFromBeacon(BeaconInfo beaconInfo, ZoneInfo zoneInfo, int dwellTime, Map<String, String> customData) {
// This method will be called when a device Checks out of a Beacon
}
}

public class BDTestFragment extends Fragment implements ServiceStatusListener, ApplicationNotificationListener {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// Get an instance of ServiceManager to access the Bluedot Point Service
serviceManager = ServiceManager.getInstance(this);
//Check for location permissions, before authenticating the SDK
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//Check the Bluedot Point Service is currently running, otherwise start it
if(!serviceManager.isBlueDotPointServiceRunning()){
// Setting Notification for foreground service, required for Android Oreo and above.
String channelId = "";
String channelName = "";
NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
...
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(notificationChannel);
Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext(), channelId)
...
Notification notification = notificationBuilder.build();
// Setting targetAllAPIs to TRUE will display foreground notification for Android versions lower than Oreo
serviceManager.setForegroundServiceNotification(notification, false);
serviceManager.sendAuthenticationRequest("<api key>",this);
}
}
}
@Override
public void onBlueDotPointServiceStartedSuccess() {
// This is called when BlueDotPointService started successfully
// Your app logic can start from here
}
@Override
public void onBlueDotPointServiceStop() {
// This will be called when BlueDotPointService has been stopped.
// Your app could release resources that use the BlueDotPointService
}
@Override
public void onBlueDotPointServiceError(BDError error) {
// This gives you details if BlueDotPointService encounters error.
// Human-readable string of bdError.getReason() can be useful to analyse the cause of the error.
// Boolean bdError.isFatal() identifies if error is fatal and BlueDotPointService is no more functional;
// onBlueDotPointServiceStop() callback is invoked next in such a case.
}
@Override
public void onRuleUpdate(List zoneInfos) {
// Passively receive Zones information
// Optional
}
@Override
public void onCheckIntoFence(FenceInfo fenceInfo, ZoneInfo zoneInfo, LocationInfo location, Map<String, String> customData, boolean isCheckOut) {
// This method will be called if the device checked into a Fence
// and the zone contains a custom action
// Using a handler to pass Runnable into UI thread to interact with UI elements
}
@Override
public void onCheckedOutFromFence(FenceInfo fenceInfo, ZoneInfo zoneInfo, int dwellTime, Map<String, String> customData) {
// This method will be called when a device leaves the Fence that was checked into. Only applies to zones flagged as checkout enabled on the backend.
}
@Override
public void onCheckIntoBeacon(BeaconInfo beaconInfo, ZoneInfo zoneInfo, LocationInfo location, Proximity proximity, Map<String, String> customData, boolean isCheckOut) {
// This will be called if the trigger happened on a Beacon
// and the zone contains a custom action
// Using runOnUiThread to interact with UI Elements within UI Thread
}
@Override
public void onCheckedOutFromBeacon(BeaconInfo beaconInfo, ZoneInfo zoneInfo, int dwellTime, Map<String, String> customData) {
// This method will be called when a device Checks out of a Beacon
}
}