Runtime permissions and Proxi.Cloud SDK

For the majority of functions to work SDK requires location permissions to be granted, specifically ACCES_FINE_LOCATION and ACCESS_BACKGROUND_LOCATION (introduced in Android 10). In some cases it is more obvious (Geofencing) than in other(obtaining WiFi/Beacon BLE scan results) that such permissions are needed.

Since Android 6 (API 23) theese permissions are deemed dangerous so the user must be prompted and grant them explicitly. Developer is responsible for requesting them and handling results, example implementation below.

All of the code is called inside an Activity class.

Requesting permissions:

final static int LOCATION_PERMISSIONS_REQUEST_CODE = 1000; //can be any integer, needed to identify request

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    boolean locationPermissionGranted = ActivityCompat
            .checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED;

    if (!locationPermissionGranted) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {
            //present dialog that explains to the user why it is worth to grant location permission
            showRationaleDialog();
        } else {
            requestPermissions();
        }
    }
}

private void requestPermissions() {
    ActivityCompat.requestPermissions(this, new String[]{
                    Manifest.permission.ACCESS_FINE_LOCATION, //required for both foreground and background location access
                    Manifest.permission.ACCESS_BACKGROUND_LOCATION //skip this permission if your app does not target Android 10 or above
            },
            LOCATION_PERMISSION_REQUEST_CODE);
}

private void showRationaleDialog() {
    new AlertDialog.Builder(this)
            .setTitle("Functionality limited")
            .setMessage("Since location access has not been granted, " +
                    "this app will not be able to trigger geofences or scan beacons/wifi networks")
            .setPositiveButton(android.R.string.ok, null)
            .setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override
                public void onDismiss(DialogInterface dialog) {
                    requestPermissions();
                }
            })
            .create()
            .show();
}

After permission has been granted onRequestPermissionsResult callback will be called. Set flag that informs SDK about permission state change. It is not necessary but it will ensure that location based functions are put to work as soon as possible.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case LOCATION_PERMISSIONS_REQUEST_CODE: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                ProxiCloudSdk.getInstance().sendLocationFlagToReceiver(ProxiCloudServiceMessage.MSG_LOCATION_SET);
            } else {
                 ProxiCloudSdk.getInstance().sendLocationFlagToReceiver(ProxiCloudServiceMessage.MSG_LOCATION_NOT_SET_WHEN_NEEDED;
            }
        }
    }
}

More about runtime permissions: https://developer.android.com/training/permissions/requesting More about Android 10 location permissions: https://developer.android.com/training/location/request-updates#inform-user-background-location-requirement