androidandroid-permissionsandroid-runtime

boolean value in onRequestPermissionsResult changes but MainActivity uses old boolean value


I have a Boolean value that I am updating in the onRequestPermissionsResult method if I'm granted the permissions. And later after call to my checkPermission method I am checking the value of boolean. The value of boolean is changing in the onRequestPermissionsResult but before the change happens the MainActivity code runs and uses the old value. What is the problem that MainActivity is not waiting for the onRequestPermissionsResult to end and then proceed to use the recent value of the boolean.

Also I am running the code on my mobile that have almost 300 contacts but the app only show one same random contact all the time.

    textView = (TextView) findViewById(R.id.textview);

    ContentResolver contentResolver = getContentResolver();

    Cursor data = null;

    getPermissionStatus();

    //the if statement does not waits for the onRequestPermissionsResult to ends

    if (permissionGranted) {
        data = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, mSelectionColumns,
                null, null, null);
        if (data != null && data.getCount() > 0) {
            while (data.moveToNext()) {
                textView.setText(data.getString(
                        data.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))
                        + "\t " +"\n");
            }
        } else
            Toast.makeText(this, "No data...", Toast.LENGTH_SHORT).show();
    } else
        Toast.makeText(this, "Permission not granted.", Toast.LENGTH_SHORT).show();

    if (data != null) {
        data.close();
    }

}

public void getPermissionStatus() {
    Toast.makeText(this, "Called", Toast.LENGTH_SHORT).show();

    if ((ContextCompat.checkSelfPermission(this,
            Manifest.permission.READ_CONTACTS)) !=
            PackageManager.PERMISSION_GRANTED) {
        Toast.makeText(this, "Requesting...", Toast.LENGTH_SHORT).show();
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.READ_CONTACTS},
                REQ_CODE_READ_CONTACTS);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

    switch (requestCode) {
        case REQ_CODE_READ_CONTACTS:
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                //Main activity should these value of the permissinGranted
                permissionGranted = true;
                Toast.makeText(this, "Permission Granted...", Toast.LENGTH_SHORT).show();
            }
            else {
                Toast.makeText(this, "Test", Toast.LENGTH_SHORT).show();
                permissionGranted = false;
            }
    }

}

Solution

  • Because the conditional statement with if (permissionGranted) ... runs right after requestPermissions(), and due to threading (main), the following lines of code would run right after as in it'd run even before the permission dialog is displayed. That said, you'd want to set up querying the database in a method where it'd be invoked during runtime in the main thread for Android versions below 6.0 and upon granting permissions in the onRequestPermissionsResult() callback method for Android 6.0 and above.

    Also, remember that requesting permissions at runtime is only for Android 6.0 and above, so consider reconfiguring your conditional statement since your boolean flag, permissionGranted, will always be false for versions lower than 6.0.