The Estimote SDK for Android is a library that allows interaction with Estimote beacons. The SDK system requirements are Android 4.3 or above and Bluetooth Low Energy.
The Android SDK mimics the Estimote SDK for iOS. All naming conventions come from the iBeacon library for iOS and the Estimote iOS library.
It allows for:
- beacon ranging (scans beacons and optionally filters them by their properties)
- beacon monitoring (monitors regions for those devices that have entered/exited a region)
- beacon characteristic reading and writing (proximity UUID, major & minor values, broadcasting power, advertising interval), see [BeaconConnection] (http://estimote.github.io/Android-SDK/JavaDocs/com/estimote/sdk/connection/BeaconConnection.html) class and demos in the SDK
Docs:
What is ranging?
Ranging allows apps to know the relative distance between a device and beacons. This can be very valuable – consider for example an indoor location app of a department store. The app can determine which department (such as footwear, clothing, accessories etc) you're closest by. Information about this proximity can be used within the app to show fitting guides or offer discounts.
As Bluetooth Low Energy ranging depends on detecting radio signals, results will vary depending on the placement of Estimote beacons and whether a user's mobile device is in-hand, in a bag or a pocket. Clear line of sight between a mobile device and a beacon will yield better results so it is recommended that Estimote beacons not be hidden between shelves.
To enjoy consistent ranging it is good practice to use the app in the foreground while the user is holding the device in-hand (which means the app is on and running).
Apps can use the startRanging
method of the BeaconManager
class to determine relative proximity of beacons in the region and can be updated when this distance changes. Ranging updates come every second to listeners registered with the setRangingListener
method of the BeaconManager
class. Ranging updates contain a list of currently found beacons. If a beacon goes out of range it will not be presented on this list.
Ranging is designed to be used for apps running in the foreground.
What is monitoring?
Region monitoring is a term used to describe a Bluetooth device's usage and detect when a user is in the vicinity of beacons. You can use this functionality to show alerts or provide contextually aware information as a user enters or exits a beacon region. Beacon regions are defined by the following beacon properties:
- proximity UUID: 128-bit unique identifier,
- major: 16-bit unsigned integer to differentiate between beacons within the same proximity UUID,
- minor: 16-bit unsigned integer to differentiate between beacons with the same proximity UUID and major value.
Note that all of these values are optional, meaning that a single region can encompass multiple beacons — which creates interesting use cases. Consider for example a department store that is identified by a particular proximity UUID and major value. Different sections of the store are differentiated further by a different minor value. An app can monitor region defined by their proximity UUID and major value to provide location-relevant information by distinguishing minor values.
Apps can use the startMonitoring
method of the BeaconManager
class to start monitoring regions. Monitoring updates come to listeners registered with the setMonitoringListener
method of the BeaconsManager
class.
Monitoring is designed to perform periodic scans in the background. By default it scans for 5 seconds and sleeps for 25 seconds. This means that it can take by default up to 30 seconds to detect entering or exiting a region. Default behaviour can be changed via BeaconManager#setBackgroundScanPeriod
.
- Copy estimote-sdk-preview.jar to your
libs
directory. - Add following permissions and service declaration to your
AndroidManifest.xml
:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<service android:name="com.estimote.sdk.service.BeaconService"
android:exported="false"/>
(optional) You can enable debug logging of the Estimote SDK by calling com.estimote.sdk.utils.L.enableDebugLogging(true)
.
Demos are located in Demos directory. You can easily build it with Gradle by typing gradlew installDebug
(or gradlew.bat installDebug
on Windows) in terminal when your device is connected to computer. If you use Android Studio you can just simply open build.gradle
.
Demos include samples for ranging beacons, monitoring beacons, calculating distance between beacon and the device and also changing minor value of the beacon.
Quick start with ranging:
private static final String ESTIMOTE_PROXIMITY_UUID = "B9407F30-F5F8-466E-AFF9-25556B57FE6D";
private static final Region ALL_ESTIMOTE_BEACONS = new Region("regionId", ESTIMOTE_PROXIMITY_UUID, null, null);
private BeaconManager beaconManager = new BeaconManager(context);
// Should be invoked in #onCreate.
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
@Override public void onBeaconsDiscovered(Region region, List<Beacon> beacons) {
Log.d(TAG, "Ranged beacons: " + beacons);
}
});
// Should be invoked in #onStart.
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
@Override public void onServiceReady() {
try {
beaconManager.startRanging(ALL_ESTIMOTE_BEACONS);
} catch (RemoteException e) {
Log.e(TAG, "Cannot start ranging", e);
}
}
});
// Should be invoked in #onStop.
try {
beaconManager.stopRanging(ALL_ESTIMOTE_BEACONS);
} catch (RemoteException e) {
Log.e(TAG, "Cannot stop but it does not matter now", e);
}
// When no longer needed. Should be invoked in #onDestroy.
beaconManager.disconnect();
- Where are JavaDocs for Estimote Android library?
They are published on GitHub pages.
- Android Bluetooth stack is crashing (“Bluetooth Share has stopped” alert)
You may observe in logs either of those two:
- process com.android.bluetooth crashed with SIGSEGV and backtrace leading to Bluetooth native driver
- exception similar to this one: A/EstimoteSDK(2413): com.estimote.sdk.service.BeaconService.stopScanning:285 BluetoothAdapter throws unexpected exception A/EstimoteSDK(2413): java.lang.NullPointerException A/EstimoteSDK(2413): at android.bluetooth.BluetoothAdapter$GattCallbackWrapper.stopLeScan(BluetoothAdapter.java:1596) A/EstimoteSDK(2413): at android.bluetooth.BluetoothAdapter.stopLeScan(BluetoothAdapter.java:1540) A/EstimoteSDK(2413): at com.estimote.sdk.service.BeaconService.stopScanning(BeaconService.java:283) A/EstimoteSDK(2413): at com.estimote.sdk.service.BeaconService.access$700(BeaconService.java:60) A/EstimoteSDK(2413): at com.estimote.sdk.service.BeaconService$1$1.run(BeaconService.java:545) A/EstimoteSDK(2413): at android.os.Handler.handleCallback(Handler.java:733) A/EstimoteSDK(2413): at android.os.Handler.dispatchMessage(Handler.java:95) A/EstimoteSDK(2413): at android.os.Looper.loop(Looper.java:136) A/EstimoteSDK(2413): at android.os.HandlerThread.run(HandlerThread.java:61)
Resolution: turn on Airplane Mode on the device for a few seconds. If it does not help, please do try factory reset.
This happens only when hundreds of Bluetooth Low Energy devices are around (hackathons, dev shops). Bluetooth library has low-level bug which activates only of there many many BLE devices around.
This will not be seen by end users since they do not operate in the environment where there are many many Bluetooth devices.
Issue is already reported to Android and hopefully it will be fixed within next release.
For more detailed info please see those two StackOverflow threads.
There is a workaround around this bug. Please read the article and check out Bluetooth crash resolver project on GitHub.
- I did not find answer here. Where I can seek for help?
You have three options:
- file an issue on GitHub for Estimote SDK for Android if it is highly technical
- check our Community Portal to get answers for most common questions related to our Hardware and Software, you can post questions there
- ask a question on StackOverflow.com with iBeacon, Estimote, Android tags
- How to run demos from Eclipse?
Eclipse cannot import Gradle projects out of the box. See tutorial how to do it.
- 0.4.3 (November 12, 2014):
- Fixes Estimote#59: compatibilty with Android L
- 0.4.2 (June 24, 2014):
- Fixes Estimote#55: it is safe to use library from remote process
-
0.4.1 (March 18, 2014)
-
CAN BREAK BUILD: MonitoringListener returns list of beacons the triggered enter region event (Estimote#18)
-
Better messaging when BeaconManager cannot start service to scan beacons (Estimote#25)
-
Fixed bug in SDK when other beacons are around (Estimote#27)
-
0.4 (February 17, 2014)
-
Introducing ability to change beacon's UUID, major, minor, broadcasting power, advertising interval (see BeaconConnection class).
-
Dropping Guava dependency.
-
0.3.1 (February 11, 2014)
-
Fixes bug when simulated beacons were not seen even when using Estimote's proximity UUID.
-
0.3 (February 11, 2014)
-
Background monitoring is more robust and using AlarmService to invoke scanning.
-
Default values for background monitoring were changed. Scanning is performed for 5 seconds and then service sleeps for 25 seconds. Those values can be changed with BeaconManager#setBackgroundScanPeriod.
-
Beacons reported in RangingListener#onBeaconsDiscovered are sorted by accuracy (estimated distance between device and beacon).
-
Bug fixes.
-
0.2 (January 7, 2014)
-
IMPORTANT: package changes BeaconService is now in
com.estimote.sdk.service service
. You need to update yourAndroidManifest.xml
service definition tocom.estimote.sdk.service.BeaconService
. -
Support for monitoring regions in BeaconManager.
-
Region class: it is mandatory to provide region id in its constructor. This matches CLRegion/ESTBeaconRegion from iOS.
-
Beacon, Region classes now follow Java bean conventions (that is getXXX for accessing properties).
-
Debug logging is disabled by default. You can enable it via
com.estimote.sdk.utils.L#enableDebugLogging(boolean)
. -
0.1 (December 9, 2013)
-
Initial version.