Andromeda
Andromeda

Reputation: 240

Runtime Permissions Not Working on Real Device

I have implemented RT location permissions in my app and tested on a Nougat device. I have checked the logcat but it looks like the ContextCompat.checkSelfPermission() and ActivityCompat.requestPermission dont execute and subsequently onRequestPermissionRationale never gets called but in the device settings for the app, it is always showing as permission granted

I have tried logging like below in code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_client_home);

    prefsHelper = new SharedPrefsHelper(this);
    initViews();
    setSupportActionBar(toolbar);

    Log.d(TAG, "BEFORE CHECK");
    checkPerms();

    setUpDrawer();
    prefsHelper.setLoggedOut(false);

    getVehicles();
    handlePlacesInput();

    rideContinueLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (validate() && Utils.isNetwork(ClientHomeActivity.this)) {
                Intent intent = new Intent(ClientHomeActivity.this, BookRideActivity.class);
                intent.putExtra("start_addr", startAddr);
                intent.putExtra("dest_addr", destAddr);
                startActivity(intent);
                clearInputs();
            } else {
                Snackbar.make(findViewById(android.R.id.content), "Enter Start and Drop Locations", Snackbar.LENGTH_LONG).show();
            }
        }
    });

}

private void checkPerms() {
    Log.d(TAG, "DO CHECK");
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        Log.d(TAG, "INSIDE CHECK");
        reqPerms();
    }
}

private void reqPerms() {
    Log.d(TAG, "ASKING");
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, AppConstants.LOC_PERMS_REQ_CODE);
}

@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case AppConstants.LOC_PERMS_REQ_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG, "GRANTED");
            } else {
                if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
                    Log.d(TAG, "Permission Rationale");
                } else {
                    reqPerms();
                }

            }
            break;
    }
}

The log stops at "DO CHECK" tag and other tags after that don't execute. I am trying to build a location based app. Can anyone tell me why its is happening this way, is it a bug on my device or in code? Thanks.

Upvotes: 2

Views: 2269

Answers (5)

Dhaval Solanki
Dhaval Solanki

Reputation: 4705

There is tow possibility to not show permission dialog after request which is bellow.

Target Version
Please set your targetSdkVersion in your build great than 23

Declare permissions Manifest
Please don't miss to declare permission in manifest which you need and you are requesting at runtime,

Upvotes: 0

Sagar
Sagar

Reputation: 24907

ActivityCompat.requestPermission dont execute and subsequently onRequestPermissionRationale never gets called but in the device settings for the app, it is always showing as permission granted

Since your app is old app and you have already granted the necessary permissions to the app, ActivityCompat.checkSelfPermission will return PackageManager.PERMISSION_GRANTED and you won't see the permission request again.

If you want to see the permission request, un-install the older app and install a new one. Another way is to just disable the permissions from the settings.

Upvotes: 2

Nabin Bhandari
Nabin Bhandari

Reputation: 16379

The only logical explanation for your code to log "DO CHECK" and not "INSIDE CHECK" is that the permissions are already granted.

Before requesting permissions, if the permissions are already granted, you can do your required operations directly.

Also you can make use of my library to handle runtime permissions easily. https://github.com/nabinbhandari/Android-Permissions

Upvotes: 2

user4571931
user4571931

Reputation:

Try this make sure your app level gradle file in compile sdk version latest. like

  compileSdkVersion 27

then after also add permission into android manifest file.

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

and after check runtime permission like below make two method.

/**
 * this method check permission and return current state of permission need.
 */
private boolean checkPermissions() {
    int permissionState = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);
    return permissionState == PackageManager.PERMISSION_GRANTED;
}

/**
 * this method request to permission asked.
 */
private void requestPermissions() {
    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);

    if (shouldProvideRationale) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");
    } else {
        Log.i(TAG, "Requesting permission");
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length <= 0) {
            // If user interaction was interrupted, the permission request is cancelled and you
            // receive empty arrays.
            Log.i(TAG, "User interaction was cancelled.");
        } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission was granted. Kick off the process of building and connecting
            // GoogleApiClient.
            buildGoogleApiClient();
        } else {
            // Permission denied.

        }
    }
}

then when call get location method then put like below check

 // Check if the user revoked runtime permissions.
    if (!checkPermissions()) {
        requestPermissions();
    }

    buildGoogleApiClient();

Upvotes: 2

蔡旻袁
蔡旻袁

Reputation: 181

Maybe you already granted the permission.

Try to reinstall the app.

Upvotes: 1

Related Questions