onRequestPermissionsResult不在对话框片段中调用
我已经开始使用Android M运行时权限。 在这里,我面临的问题是,如果requestPermissions从Dialog Fragment类被调用,然后onRequestPermissionsResult不被调用在相同的Dialog fragment类。 但是,如果从Activity类或Fragment类调用requestPermissions则onRequestPermissionsResult方法将在同一个类中调用。 
这是我的示例代码:
 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; } } 
 在代码中,我调用了Dialog Fragment类的requestPermissions方法。 所以我期待在同class上得到成绩。 
任何帮助表示赞赏。 提前致谢!
编辑:在这里,我添加更多的细节,这样会对别人更有帮助。 以前我用getChildFragmentManager()来显示DialogFragment。
 ContactPickerDialog dialog = new ContactPickerDialog(); dialog.show(getChildFragmentManager(), "Contact Picker"); 
但作为@CommonWare要求我使用活动来显示DialogFragment。 我做了以下的改变,它的工作。
 ContactPickerDialog dialog = new ContactPickerDialog(); dialog.show(getActivity().getSupportFragmentManager(), "Contact Picker"); 
	
  在Android中似乎有一个错误 ,其中嵌套的片段不支持onRequestPermissionsResult()callback。 对于DialogFragment ,解决方法似乎是让片段想要显示对话框调用托pipe活动的方法,并且该活动显示DialogFragment本身。 
 如果你在支持库的Fragment ,直接调用requestPermissions() ,你的片段的onRequestPermissionsResult()将被callback。 
 如果你调用ActivityCompat.requestPermissions() ,那么它的Activity将会被调用回onRequestPermissionsResult() 。 
这个问题似乎在Android支持库23.3.0及以上版本中得到解决。
如果您使用Support v4 Fragments,嵌套的片段现在将接收到onRequestPermissionsResult()的callback。
编辑:@AndrewS,这里是如何更新。
在您的build.gradle(app)文件中,更改以下行以使用最新版本的最新支持库24.0.0:
 dependencies { compile 'com.android.support:appcompat-v7:24.0.0' } 
如果你有嵌套片段的问题,你可以从父片段请求许可
 getParentFragment().requestPermissions(new String[]{permission}, requestCode); 
然后将callback转发给子片段
 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grants) { List<Fragment> fragments = getChildFragmentManager().getFragments(); if (fragments != null) { for (Fragment fragment : fragments) { if (fragment != null) { fragment.onRequestPermissionsResult(requestCode, permissions, grants); } } } } 
有一件事帮助了我。 当你从一个嵌套的片段请求权限getParent像这样
  fragment.getParentFragment().requestPermissions((new String[] {Manifest.permission.READ_CONTACTS}), requestCode); 
然后覆盖父片段onRequestPermissionResult并检查相应的requestCode。
希望它可以帮助你。
编辑:
 我build议使用新版本的Support Library 23.3.0,因为Google修复了不调用onRequestPermissionsResult ,但是如果由于某些原因您需要使用旧版本,请参阅下面的原始答案。 
原文答案:
我正在使用下一个解决方法(与easyPermissions库一起):
BaseFragment:
 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { /** child v4.fragments aren't receiving this due to bug. So forward to child fragments manually * https://code.google.com/p/android/issues/detail?id=189121 */ super.onRequestPermissionsResult(requestCode, permissions, grantResults); List<Fragment> fragments = getChildFragmentManager().getFragments(); if (fragments != null) { // it is possible that fragment might be null in FragmentManager for (Fragment fragment : fragments) { if (fragment != null) { fragment.onRequestPermissionsResult(requestCode, permissions, grantResults); } } } } 
BaseActivity:
 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { Fragment fragment = getSupportFragmentManager().findFragmentById(getFragmentContainer()) if (fragment != null) { fragment.onRequestPermissionsResult(requestCode&0xff, permissions, grantResults); } } 
用法:
 public class SomeFragment extends BaseFragment implements EasyPermissions.PermissionCallbacks { private static final int PICK_CONTACT = 1; private static final int READ_CONTACTS_PERM = 2; // some code @AfterPermissionGranted(READ_CONTACTS_PERM) private void pickContactWithPermissionsCheck() { if (EasyPermissions.hasPermissions(getContext(), Manifest.permission.READ_CONTACTS)) { // Have permission pickContactForResult(); } else { // Request one permission EasyPermissions.requestPermissions(this, getString(R.string.read_contacts_permission_explanation), READ_CONTACTS_PERM, Manifest.permission.READ_CONTACTS); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // FIXME problem with incorrect requestCode coming to callback for Nested fragments // More information here - https://code.google.com/p/android/issues/detail?id=189121 if (isVisible() && Arrays.asList(permissions).contains(Manifest.permission.READ_CONTACTS)) { requestCode = READ_CONTACTS_PERM; } // EasyPermissions handles the request result. EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } } 
我有这个问题,没有嵌套的片段,其中活动显示对话框片段,结果没有得到通过。
 添加 
 super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
 到Activity的onRequestPermissionsResult()解决了这个问题。 
我这样做了
 public class DialogFragmentSMS extends DialogFragment implements View.OnClickListener { public static DialogFragmentSMS frag; private static View view; private static ViewGroup parent; private EditText editTextMensagem; private String celular; private final static int SMS_REQUEST = 20; public DialogFragmentSMS() { } public static DialogFragmentSMS newInstance(String celular) { Bundle args = new Bundle(); args.putString("celular", celular); frag = new DialogFragmentSMS(); frag.setArguments(args); return frag; } @Override public void onCreate(Bundle saveInstaceState) { super.onCreate(saveInstaceState); } @Override public void onClick(View v) { if (!PermissaoUtils.hasPermission(getActivity(), Manifest.permission.SEND_SMS)) { //PermissaoUtils.requestPermissions(getActivity(), new String[]{Manifest.permission.SEND_SMS}, SMS_REQUEST); frag.requestPermissions(new String[]{Manifest.permission.SEND_SMS}, SMS_REQUEST); }else{ if (validaCampos()) { SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage("0" + celular, null, editTextMensagem.getText().toString(), null, null); Toast.makeText(getActivity(), R.string.sms_enviado, Toast.LENGTH_SHORT).show(); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); frag.dismiss(); } } } 
我的课程权限
 public class PermissaoUtils { public static boolean useRunTimePermissions() { return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1; } public static boolean hasPermission(Activity activity, String permission) { if (useRunTimePermissions()) { return activity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; } return true; } public static void requestPermissions(Activity activity, String[] permission, int requestCode) { if (useRunTimePermissions()) { activity.requestPermissions(permission, requestCode); } } }