I have started to work on Android M runtime permission. Here I am facing the issue that if requestPermissions
is called from Dialog Fragment
class then onRequestPermissionsResult
not getting called in the same Dialog fragment
class. But if requestPermissions
is called from Activity
class or Fragment
class then onRequestPermissionsResult
method get called in the same class.
Here is my sample code:
public class ContactPickerDialog extends DialogFragment {
private static final int READ_CONTACTS_REQUEST_CODE = 12;
private Context mContext;
private void loadContact() {
if(hasPermission(mContext, Manifest.permission.READ_CONTACTS)){
new ContactSyncTask().execute();
} else {
this.requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, READ_CONTACTS_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
Logger.d("TAG", "dialog onRequestPermissionsResult");
switch (requestCode) {
case READ_CONTACTS_REQUEST_CODE:
// Check Permissions Granted or not
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
new ContactSyncTask().execute();
} else {
// Permission Denied
Toast.makeText(getActivity(), "Read contact permission is denied", Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private static boolean hasPermission(Context context, String permission){
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
}
}
Here in the code I am calling requestPermissions
method of Dialog Fragment
class. So I am expecting to get result in same class.
Any help is appreciated. Thanks in advance!
EDIT: Here I am adding more detail, so that it will be more helpful to others. Previously I have used getChildFragmentManager() to show the DialogFragment.
ContactPickerDialog dialog = new ContactPickerDialog();
dialog.show(getChildFragmentManager(), "Contact Picker");
But As @CommonWare asked me to use activity to show the DialogFragment. I have made following changes and it works.
ContactPickerDialog dialog = new ContactPickerDialog();
dialog.show(getActivity().getSupportFragmentManager(), "Contact Picker");
I had this problem without nested fragments, where the activity was showing the dialog fragment and the result was not getting passed.
Adding
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
to the Activity's
onRequestPermissionsResult()
solved the issue.In addition to the end portion of Nino Handler's answer and for anyone still having issues with this, make sure that if you do override onRequestPermissionsResult in the parent activity/fragment of your dialog fragment, that you call super.onRequestPermissionsResult there.
I was overriding onRequestPermissionsResult in the parent activity of my dialog fragment, but neglected to call the super method there. Once I changed it to call the super method, it properly delegated down to the onRequestPermissionsResult in my dialog fragment.
If you're inside a
Fragment
from support library, callrequestPermissions()
directly, and your Fragment'sonRequestPermissionsResult()
will be called back.If you call
ActivityCompat.requestPermissions()
, then it's theActivity
'sonRequestPermissionsResult()
that will be called back.If you have a look at the documentation of the fragment's
requestPermissions
method you will find out that you still have to declare the permissions in your Manifest:If this is not the case the fragment's own
onRequestPermissionsResult
won't be invoked.Instead, the activity's
onRequestPermissionsResult
is called but won't have any effect.So grating a permission from within a fragment should be done as follows:
1. Declare the permission in your manifest
Enter this before the application tag.
2. Check for the permission in your fragment
3. Wait for the permission result in your fragment
4. Make sure you don't override the activity's
onRequestPermissionsResult
Overriding the activity's
onRequestPermissionsResult
will cause the fragment's one not to react.One thing that helped me was this. When you request permission from a nested fragment use getParent like so
and then override the parent fragment onRequestPermissionResult and check for the corresponding requestCode.
Hope it helps you as well.
If you have problem with nested fragment, you can request permission from parent fragment
and then forward callback to child fragment