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" />
Check Permissions
// 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 brevityActivityCompat.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 grantedstartScan();} else {if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {//we should show some explanation for user hereshowExplanationDialog();} else {//request permissionActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 100);}}}
Override onRequestPermissionsResult in your Activity
@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {if (100 == requestCode) { //same request code as was in request permissionif (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
Code the business logic
Now after all this necessary setup, we can finaly start the scanning procedure:
@Overrideprotected void onStart() {super.onStart();proximityManager.connect(new OnServiceReadyListener() {@Overridepublic 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.