Beacon Scanning Setup

This section will briefly show how to scan beacons.

Let's look at the minimal set of permissions you need to include in your AndroidManifest.xml file to perform Bluetooth scanning.

a) When using compileSdkVersion 30 and lower:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

b) When using compileSdkVersion 31 and higher:

<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" tools:targetApi="s" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

// new way of asking about permissions (compileSdkVersion=31)
private void checkPermissions() {
String[] requiredPermissions = Build.VERSION.SDK_INT < Build.VERSION_CODES.S
? new String[]{Manifest.permission.ACCESS_FINE_LOCATION}
: new String[]{ Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT }; // Note that there is no need to ask about ACCESS_FINE_LOCATION anymore for BT scanning purposes for VERSION_CODES.S and higher if you add android:usesPermissionFlags="neverForLocation" under BLUETOOTH_SCAN in your manifest file.
if(isAnyOfPermissionsNotGranted(requiredPermissions)) {
// you should also reqursively check if any of those permissions need rationale popup via ActivityCompat.shouldShowRequestPermissionRationale before doing the actual requestPermissions(...), but this part was cut out for brevity
ActivityCompat.requestPermissions(this, requiredPermissions, 100);
} else {
startScan();
}
}
// old way of asking about permission (compileSdkVersion<=30)
private void checkPermissionAndStart() {
int checkSelfPermissionResult = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
if (PackageManager.PERMISSION_GRANTED == checkSelfPermissionResult) {
//already granted
startScan();
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
//we should show some explanation for user here
showExplanationDialog();
} else {
//request permission
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 100);
}
}
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (100 == requestCode) { //same request code as was in request permission
if (allPermissionsGranted(grantResults)) {
startScan();
} else {
//not granted permission
//show some explanation dialog that some features will not work
}
}
}

More information about new permissions can be found in Google's Android training


Now after all this necessary setup, we can finaly start the scanning procedure:

@Override
protected void onStart() {
super.onStart();
proximityManager.connect(new OnServiceReadyListener() {
@Override
public void onServiceReady() {
proximityManager.startScanning();
}
});
}

You can check out our Sample Activity for details how to ask about permissions; see the samples under our sample directory for full examples of how to perform scanning based on our sdk.