Android M权限:onRequestPermissionsResult()未被调用

312
我正在更新我们的应用程序以使用新的 M 运行时权限系统。除了onRequestPermissionsResult()之外,一切正常。我需要在按钮按下时检查权限,如果成功,发送短信。当我授予权限来执行此操作时,对话框关闭,但它直到我再次按下按钮才触发“发送短信”操作。
我已经进行了调试并在onRequestPermissionsResult()方法中设置了断点,但它从未进入该方法。
首先调用此方法:
    private void askForPermission() {
    String[] permissions = new String[]{Manifest.permission.SEND_SMS};
    ActivityCompat.requestPermissions(getActivity(), permissions, PERMISSIONS_CODE);
}

然后我的回调函数看起来像这样:

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

    if (requestCode == PERMISSIONS_CODE) {
        for (int i = 0; i < permissions.length; i++) {
            String permission = permissions[i];
            int grantResult = grantResults[i];

            if (permission.equals(Manifest.permission.SEND_SMS)) {
                if (grantResult == PackageManager.PERMISSION_GRANTED) {
                    onPPSButtonPress();
                } else {
                    requestPermissions(new String[]{Manifest.permission.SEND_SMS}, PERMISSIONS_CODE);
                }
            }
        }
    }
}

有人遇到类似的问题吗? 感谢任何关于此问题的帮助。 谢谢

25个回答

10

这个问题实际上是由NestedFragments引起的。基本上我们有的大多数片段都继承自HostedFragment,而它又继承自CompatFragment。由于存在这些嵌套的片段,导致了问题,最终由项目中的另一位开发人员解决。

他做了一些低级别的东西,比如位切换来解决这个问题,所以我不太确定实际的最终解决方案是什么。


这帮助我解决了我的问题:我必须将onRequestPermissionsResult从父片段重定向到子(嵌套)片段。感谢您的提示! - Murphy

9
 /* use the object of your fragment to call the 
 * onRequestPermissionsResult in fragment after
 * in activity and use different request Code for 
 * both Activity and Fragment */

   if (isFragment)
    mFragment.requestPermissions(permissions.toArray(new
    String[permissions.size()]),requestPermission);

   else
    ActivityCompat.requestPermissions(mActivity,permissions.toArray(new
    String[permissions.size()]),requestPermission);

6
这将有效果..
@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

超级实现调用片段实现而不是框架。 - Mohammad Yahia

5

我有一个类似的问题,不过我是按下一个按钮来拨打电话,触发了callIntent。我先检查权限,如果没有授权我会请求权限,在onRequestPermissionResult中我会再次检查权限并重新调用拨打电话的操作。

 @Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case Constants.PERMISSIONS_REQUEST_CALL_PHONE: {
            if ( grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                checkPermissionsAndCall();
            }
        }
    }
}

public void checkPermissionsAndCall(){
    if (Build.VERSION.SDK_INT > 22) {
        if(ContextCompat.checkSelfPermission(getContext(),
                Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED){
            requestPermissions( new String[]{Manifest.permission.CALL_PHONE}, Constants.PERMISSIONS_REQUEST_CALL_PHONE);
        }
        else{
            callIntent();
        }
    }
}

5
如果您从片段中调用此代码,则它具有自己的requestPermissions方法。
基本概念是,如果您在Activity中,则调用:
ActivityCompat.requestPermissions(this,
                            permissionsList,
                            permissionscode);

如果在Fragment中,只需调用以下代码:

requestPermissions(permissionsList,
                            permissionscode);

1
需要API级别23或更高版本... 在早期版本中使用FragmentCompat.requestPermissions() - Minas Mina

3

2
我有一个惊人的解决方案来实现这个,就是创建一个类似于这样的BaseActivity。
public class BaseActivity extends AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this));


}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1: {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                CustomToast.getInstance().setCustomToast("Now you can share the Hack.");

            } else {
                Toast.makeText(this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

现在,您可以像这样调用代码请求权限

 ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);

现在,每当这种情况发生时,无论是在您的片段还是在任何活动中,基本活动都会被调用。
谢谢。

2

在查看以上答案之前,请确保您的请求代码不为0!!!

检查FragmentActivity.java中onRequestPermissionsResult()的代码:

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
        @NonNull int[] grantResults) {
    int index = (requestCode>>16)&0xffff;
    if (index != 0) {
        index--;

        String who = mPendingFragmentActivityResults.get(index);
        mPendingFragmentActivityResults.remove(index);
        if (who == null) {
            Log.w(TAG, "Activity result delivered for unknown Fragment.");
            return;
        }
        Fragment frag = mFragments.findFragmentByWho(who);
        if (frag == null) {
            Log.w(TAG, "Activity result no fragment exists for who: " + who);
        } else {
            frag.onRequestPermissionsResult(requestCode&0xffff, permissions, grantResults);
        }
    }
}

2
private void showContacts() {
    if (getActivity().checkSelfPermission(Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
    } else {
        doShowContacts();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        doShowContacts();
    }
}

1
你可以使用requestPermissions(PERMISSIONS, MULTIPLE_PERMISSIONS_CODE);。如果你正在使用v4,请不要使用FragmentCompat。

请详细说明为什么。 - Placeable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接