Android 8.1(API 27)中requestPermissions无法获取通话日志读写权限
解决Android通话记录权限请求失效的问题
我看了你的代码和配置,问题核心出在权限请求的方式上——你连续调用两次requestPermissions且用了同一个请求码,这会导致系统只处理最后一次请求,第一次的权限申请直接被覆盖了,自然就失效了。另外你也没处理权限请求的回调,没法确认权限是否真的被授予。下面给你一步步的修复方案:
1. 合并权限请求,一次性申请所需权限
把READ_CALL_LOG和WRITE_CALL_LOG放在同一个权限数组里,只调用一次requestPermissions,系统会弹出统一的权限申请对话框,不会出现互相覆盖的情况:
public void EnableRuntimePermissionToAccessCallLogs() { Log.i(TAG,"EnableRuntimePermissionToAccessCallLogs called"); // 检查两个权限是否都已授予 boolean hasReadPermission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_GRANTED; boolean hasWritePermission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_CALL_LOG) == PackageManager.PERMISSION_GRANTED; if (!hasReadPermission || !hasWritePermission) { Log.i(TAG,"请求通话记录读写权限"); // 一次性请求两个权限,使用唯一的请求码(避免和其他请求冲突) ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG}, 100); Log.i(TAG,"权限请求已发起"); } else { Log.i(TAG,"通话记录权限已授予"); // 这里写权限已授予后的逻辑,比如读取通话记录 } Log.i(TAG,"EnableRuntimePermissionToAccessCallLogs called 2"); }
2. 实现权限请求的回调函数
必须重写onRequestPermissionsResult方法,处理用户的权限选择结果,否则你无法知道权限是否成功授予:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { // 检查每个权限的授予结果 boolean readGranted = false; boolean writeGranted = false; for (int i = 0; i < permissions.length; i++) { if (Manifest.permission.READ_CALL_LOG.equals(permissions[i])) { readGranted = grantResults[i] == PackageManager.PERMISSION_GRANTED; } else if (Manifest.permission.WRITE_CALL_LOG.equals(permissions[i])) { writeGranted = grantResults[i] == PackageManager.PERMISSION_GRANTED; } } if (readGranted && writeGranted) { Log.i(TAG,"通话记录读写权限已成功授予"); // 权限授予成功,执行你的业务逻辑 } else { Log.i(TAG,"通话记录权限被拒绝"); // 可以提示用户需要权限才能使用功能,或者引导用户去设置里开启权限 } } }
3. 额外注意事项
- 如果你是在Fragment中调用的方法,确保
getActivity()返回的是有效的上下文,避免空指针问题。 - 不要重复使用同一个请求码,建议给每个权限请求分配唯一的码(比如100、101等),避免和其他功能的权限请求冲突。
- Android 11及以上版本对通话记录权限的申请逻辑没有大变化,只要保持Manifest声明+动态申请的流程即可。
按照上面的修改,你的权限请求功能应该就能正常工作了,试试吧!
内容的提问来源于stack exchange,提问作者Rares Stan
相关产品推荐
相关产品推荐

