Android应用未请求READ_PHONE_STATE等权限,求排查问题原因
问题原因分析与修复方案
我来帮你拆解下这个问题的核心原因,以及对应的修复方法:
核心问题1:条件判断逻辑错误
你代码里的判断条件用了&&运算符:
if (permissionCheck != PackageManager.PERMISSION_GRANTED && permissionCheck1 != PackageManager.PERMISSION_GRANTED && permissionCheck2 != PackageManager.PERMISSION_GRANTED)
这表示只有当三个权限全部未被授予时,才会进入权限请求分支。但如果其中任意一个权限已经被授予(比如READ_PHONE_STATE已经有了),代码就会直接跳到else分支,去执行获取手机号和操作联系人的逻辑——这时候READ_CONTACTS和WRITE_CONTACTS还没被授权,自然就会抛出SecurityException。
核心问题2:多次调用requestPermissions的冲突
Android系统不支持同时弹出多个权限请求弹窗。当你连续三次调用ActivityCompat.requestPermissions()时,系统只会处理最后一次的请求(前面的请求会被直接忽略),这就导致你看不到READ_CONTACTS和WRITE_CONTACTS的授权弹窗,权限自然无法被授予。
修复后的代码示例
正确的做法是一次性请求所有需要的权限,并在权限授权结果回调中处理后续逻辑:
// 定义需要申请的权限集合 String[] requiredPermissions = { android.Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS }; // 收集未被授予的权限 List<String> permissionsToRequest = new ArrayList<>(); for (String permission : requiredPermissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { permissionsToRequest.add(permission); } } // 如果存在未授权的权限,一次性发起请求 if (!permissionsToRequest.isEmpty()) { // 使用统一的请求码,方便后续回调处理 ActivityCompat.requestPermissions(this, permissionsToRequest.toArray(new String[0]), 100); } else { // 所有权限已授予,执行业务逻辑 performAuthorizedOperations(); } // 重写权限请求结果回调方法 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { boolean allPermissionsGranted = true; // 检查所有权限的授权结果 for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allPermissionsGranted = false; break; } } if (allPermissionsGranted) { performAuthorizedOperations(); } else { // 处理权限被拒绝的情况,比如提示用户 Toast.makeText(this, "需要授予所有权限才能继续操作", Toast.LENGTH_SHORT).show(); } } } // 封装授权后的业务逻辑 private void performAuthorizedOperations() { TelephonyManager tMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); mPhoneNumber = tMgr.getLine1Number(); // 在这里添加操作联系人的逻辑 }
额外注意点
- 别忘了在
AndroidManifest.xml中声明这些权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" />
- 针对Android 10及以上版本,
READ_PHONE_STATE权限的获取还有额外限制,可能需要用户手动跳转到设置页面授权。
内容的提问来源于stack exchange,提问作者Ron Arel
相关产品推荐
相关产品推荐

