Android 8.1 Java申请READ_CALL_LOG权限不弹窗被拒该如何解决?
问题排查及解决方法
授权申请直接被驳回的常见原因
1. 未在清单文件中声明权限
运行时权限申请的前提是你已经在AndroidManifest.xml中提前声明了对应权限,否则系统会直接驳回申请,不会弹出授权窗口。
你需要在清单文件的<manifest>标签层级(不要放在<application>标签内部)添加如下权限声明:
<uses-permission android:name="android.permission.READ_CALL_LOG" />
2. 用户已勾选「不再询问」并拒绝过权限
如果之前已经弹出过授权窗口,用户勾选了不再询问并选择拒绝,后续再申请该权限时系统会直接返回拒绝结果,不会再弹框。
你可以在权限申请回调中增加判断逻辑,检测到该场景时引导用户手动前往应用设置页开启权限,示例代码如下:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限获取成功,可调用接口获取最近呼出号码 String lastOutgoingCall = CallLog.Calls.getLastOutgoingCall(getApplicationContext()); } else { // 判断用户是否勾选了不再询问 if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_CALL_LOG)) { // 弹窗引导用户前往设置开启权限 new AlertDialog.Builder(MainActivity.this) .setTitle("权限必要提示") .setMessage("应用需要读取通话日志权限来获取最近呼出号码,请手动前往设置开启权限") .setPositiveButton("前往设置", (dialog, which) -> { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent); }) .setNegativeButton("取消", null) .show(); } } } }
替代方案
如果你仅需要记录用户通过你当前应用拨出的号码用于重拨,可以在拨号逻辑执行时自行将号码存储到SharedPreferences中,无需申请通话日志权限。
如果你需要获取包括系统拨号应用在内的所有渠道的最近呼出号码,仍然需要通过READ_CALL_LOG权限实现,暂无无需权限的替代方案。
内容的提问来源于stack exchange,提问作者user1922979
相关产品推荐
相关产品推荐

