onRequestPermissionsResult未在对话框片段中调用

Dha*_*tel 55 android android-fragments android-dialogfragment android-6.0-marshmallow

我已经开始研究Android M运行时权限了.在这里,我面临的问题是,如果requestPermissionsDialog Fragment类中调用,则onRequestPermissionsResult不会在同一个Dialog fragment类中调用.但是如果requestPermissionsActivity类或FragmentonRequestPermissionsResult调用,则在同一个类中调用方法.

这是我的示例代码:

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;
    }

} 
Run Code Online (Sandbox Code Playgroud)

在代码中我调用requestPermissionsDialog Fragment类的方法.所以我期待在同一个班级得到结果.

任何帮助表示赞赏.提前致谢!


编辑: 我在这里添加更多细节,以便对其他人更有帮助.以前我使用getChildFragmentManager()来显示DialogFragment.

ContactPickerDialog dialog = new ContactPickerDialog();
dialog.show(getChildFragmentManager(), "Contact Picker");
Run Code Online (Sandbox Code Playgroud)

但由于@CommonWare要求我使用activity来显示DialogFragment.我做了以下更改,它的工作原理.

ContactPickerDialog dialog = new ContactPickerDialog();
dialog.show(getActivity().getSupportFragmentManager(), "Contact Picker");
Run Code Online (Sandbox Code Playgroud)

min*_*pif 107

如果您在Fragment支持库中,请requestPermissions()直接致电,并onRequestPermissionsResult()回复您的Fragment .

如果调用ActivityCompat.requestPermissions(),那么它的ActivityonRequestPermissionsResult()将被召回.

  • @dexxtr显然,因为运行时权限请求从API 23开始. (9认同)
  • 谢谢你.我确定希望http://developer.android.com/training/permissions/requesting.html提到`android.support.v4.app.Fragment#requestPermissions`甚至存在 (5认同)
  • 我没有看到`onRequestPermissionsResult()`是由于'Fragment.requestPermissions()而被触发的. (3认同)

Com*_*are 55

Android中似乎存在一个错误,其中嵌套片段不支持onRequestPermissionsResult()回调.对于a DialogFragment,解决方法似乎是让片段想要显示对话框调用托管活动的方法,并且活动显示DialogFragment自身.


Yog*_*ity 13

问题似乎已在Android支持库23.3.0及更高版本中得到修复.

如果您正在使用Support v4 Fragments,嵌套片段现在将收到onRequestPermissionsResult()的回调.

编辑:@AndrewS,这是你可以更新的方式.

在build.gradle(app)文件中,更改以下行以使用最新的支持库24.0.0,它是最新版本:

dependencies {
    compile 'com.android.support:appcompat-v7:24.0.0'
}
Run Code Online (Sandbox Code Playgroud)


Ole*_*ndr 5

编辑:

我建议使用新版本的支持库23.3.0,因为谷歌修复了没有调用的问题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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Eri*_* B. 5

我遇到了没有嵌套片段的问题,该活动在其中显示对话框片段,并且结果未通过。

添加
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
到活动onRequestPermissionsResult()解决了问题。