Hello Folks,
This blog describes you how to use Altbeacon library for detecting beacons.
What is a beacon ?
A beacon is a device that is designed to attract attention to specific locations. Bluetooth low energy (BLE) technology is used to detect nearby beacons.
For integrating this library you need to do the following steps:-
Step 1:
Configure your app’s build.gradle File
Make sure you have a jcenter() entry in your repositories like so:
repositories {
jcenter()
}
add the library dependency like so:
compile 'org.altbeacon:android-beacon-library:2+'
Now sync your gradle in android studio.
Step 2:
Add the following permissions in your manifest file:-
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
If you targeting Marshmallow i.e Android SDK 23+ then your app must also request permission from the user to get location access. Add following permission too in your manifest file.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Step 3:
Create an android service that continuously detects for beacon regardless of your application is running or not. This service class must implements BeaconConsumer. A BeaconConsumer is an interface in AltBeacon library which is used in conjunction with BeaconManager
and provides a callback when the BeaconService
is ready to use. Until this callback is made, ranging and monitoring of beacons is not possible.
public class BeaconDetectService extends Service implements BeaconConsumer {
private final String TAG = BeaconDetectService.class.getSimpleName();
public BeaconDetectService() {
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onBeaconServiceConnect() {
}
}
Step 4:
Create an instance of BeaconManager class in the above service class. Initialize this instance and bind it to BeaconService.
private BeaconManager beaconManager;
Create a method to initialize beaconManager
private void initializeBeaconmanager() {
beaconManager = BeaconManager.getInstanceForApplication(this);
// call the below line only when you trying to detect beacons that that does not match AltBeacon standard
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
// To detect proprietary beacons, you must add a line like below corresponding to your beacon
// type. Do a web search for "setBeaconLayout" to get the proper expression.
// beaconManager.getBeaconParsers().add(new BeaconParser().
// setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
//beaconManager.bind(this);
}
Call the above method in the onCreate() of BeaconDetectService
@Override
public void onCreate() {
super.onCreate();
initializeBeaconmanager();
}
Now, create a method to bind the beaconManger
private void bindBeaconManger() {
if (beaconManager != null) {
beaconManager.bind(this);
} else {
initializeBeaconmanager();
beaconManager.bind(this);
}
}
Call the above method in onStartCommand of BeaconDetectService
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
bindBeaconManger();
return START_STICKY;
}
Step 5:- Start monitoring and ranging of beacons
Inside onBeaconServiceConnect callback set the MonitorNotifier
@Override
public void onBeaconServiceConnect() {
// Specifies a class that should be called each time the BeaconService sees or stops seeing a Region of beacons.
beaconManager.addMonitorNotifier(new MonitorNotifier() {
@Override
public void didEnterRegion(Region region) {
Log.e("beacon detected", region.getUniqueId());
notifyBeacon(region, true);
setRangeNotify(region);
}
@Override
public void didExitRegion(Region region) {
Log.e("beacon lost", region.getUniqueId());
notifyBeacon(region, false);
}
@Override
public void didDetermineStateForRegion(int state, Region region) {
Log.i(TAG, "I have just switched from seeing/not seeing beacons: "+state);
}
});
try {
beaconManager.startMonitoringBeaconsInRegion(new Region("beacon.demo.com.beacondemo", null, null, null));
} catch (Exception e) {
Log.e("error", e.toString());
}
}
/**
* Start ranging of beacons
* @param region beacon region
*/
private void setRangeNotify(Region region) {
// Specifies a class that should be called each time the BeaconService gets ranging data, which is nominally once per second when beacons are detected.
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
for (Beacon beacon : beacons) {
System.out.println("Major: " + beacon.getId2().toString());
}
Log.i(TAG, "The first beacon I see is about "+beacons.iterator().next().getDistance()+" meters away.");
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (Exception e) {
}
}
/**
* Method that trigger notification each time when enter or exit in beacon region
* @param region beacon region
* @param isEnter true if we enter inside beacon region otherwise false
*/
private void notifyBeacon(Region region, boolean isEnter) {
String message = null;
if (isEnter) {
message = "You have enter at " + region.getUniqueId();
} else {
message = "You have exit from " + region.getUniqueId();
}
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = (int) System.currentTimeMillis();
NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("Beacon Notification")
.setContentText(message)
.setSmallIcon(R.mipmap.ic_launcher);
mNotifyBuilder.setContentText(message);
// Because the ID remains unchanged, the existing notification is
// updated.
mNotificationManager.notify(
notifyID,
mNotifyBuilder.build());
}
Step 6:-
Add service declaration in Manifest file
<service
android:name=".services.BeaconDetectService"
android:enabled="true"
android:exported="true"></service>
Step 7:-
Now call the BeaconDetectService from your activity class
startService(new Intent(this, BeaconDetectService.class));
If you are using Marshmallow then you have to ask location permission at run time. For runtime permission in Marshmallow please visit this link.
You can also download the sample code attached.
0 Comment(s)