This SDK allows you to scan beacons and advertise as a beacon.
The SDK is compatible with all versions of Android supporting BLE (ie. 4.3+).
Have a look at the javadoc !
Add it to your project :
compile 'com.reelyactive:blesdk:0.5.0@aar'Add this call in your Application class :
registerActivityLifecycleCallbacks(new ReelyAwareApplicationCallback(this) { // let your IDE add what's missing });
And make sure any activity - which needs to get notified about bluetooth event - implements ReelyAwareActivity :
public class ReelyAwareScanActivity extends Activity implements ReelyAwareActivity { @Override public void onScanStarted() {} @Override public void onScanStopped() {} @Override public void onEnterRegion(ScanResult beacon) {} @Override public void onLeaveRegion(ScanResult beacon) {} }
This way, Bluetooth scanning is triggered when your Activity is resumed, and stopped when it is paused.
The ScanResult class is a clone of Lollipop's ScanResult class, offering identical APIs.
The scanning behaviour can be changed by overriding the other methods of ReelyAwareApplicationCallback, such as "shouldStartScan" :
public class MyReelyAwareApplicationCallback extends ReelyAwareApplicationCallback { @Override protected boolean shouldStartScan() { return isBound(); // always check this at least } @Override public boolean onBleEvent(BleService.Event event, Object data) { if(!super.onBleEvent(event, data)) { // do your background stuff here } return true; } }
The default filter for the scan is the following :
protected ScanFilter getScanFilter() { return new ScanFilter.Builder().setServiceUuid( ParcelUuid.fromString("7265656C-7941-6374-6976-652055554944") ).build(); }
Override this method and you can set the filter you want !
This is API is similar to what you usually find in a support package : the same APIs as on the latest Android version (Lollipop here), but on a different set of classes.
This API differs from the previous one, in the sens that you have to completely handle the scan lifecycle.
First, get a BluetoothLeScannerCompat, and decide what you'll do in a ScanCallback :
BluetoothLeScannerCompat scanner = BluetoothLeScannerCompatProvider.getBluetoothLeScannerCompat(mContext); ScanCallback scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { if (callbackType == ScanSettings.CALLBACK_TYPE_FIRST_MATCH) { // FOUND A BEACON } else { // LOST A BECON } } @Override public void onScanFailed(int errorCode) { // FAILED TO START SCANNING } };
Then, start a scan :
scanner.startScan( // Create a filter Arrays.asList(new ScanFilter.Builder().setServiceUuid( ParcelUuid.fromString("7265656c-7941-6374-6976-652055554944")) .build() ), // Use specific scan settings new ScanSettings.Builder() // .setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH | ScanSettings.CALLBACK_TYPE_MATCH_LOST) // .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // .setScanResultType(ScanSettings.SCAN_RESULT_TYPE_FULL) // .build(), scanCallback );
When you are done, stop the scan :
scanner.stopScan(scanCallback);
We desgined the advertising, so that it will be compatible with hlc-server.
You can get a reference to a BleAdvertiser with the following code:
BleAdvertiser avertiser = BleAdvertiserProvider.getAdvertiser(context);
Once you got it, you can advertise:
advertiser.startAdvertising(uuid);
Though, if you are using devices on which this feature is not available, it is advised to use:
advertiser.startAdvertising(uuid, closestBeacon);
This will make sure that any device can report data to HLC.
Give it a scan result which matches the closest beacon, for example using :
List<ScanResult> results = myAppCallback.getBleService().getMatchingRecentResults(myAppCallback.getScanFilter());
If you run your own HLC server, you might want to use:
advertiser.startAdvertising(uuid, closestBeacon, myHlcServerUrl);
This project uses the Apache Licence, and embeds code from Google's UriBeacon project.
Have a look there !