Android API29来电拦截器:如何从Call.Details提取电话号码?
解决CallScreeningService中无法读取完整电话号码的问题
我来帮你搞定这个在Android API 29下读取Call.Details电话号码的问题!你看到日志里的tel:**********其实是系统的模糊保护机制,不是单纯的权限问题,下面一步步给你解决:
1. 补充API 29+专属权限
Android Q(API 29)把读取电话号码的权限从READ_PHONE_STATE拆分出来了,你需要额外添加READ_PHONE_NUMBERS权限:
在Manifest里加入:
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
这个是危险权限,必须动态申请,比如在你的MainActivity里加这段代码:
private static final int REQUEST_READ_PHONE_NUMBERS = 1001; // 在应用启动时或合适时机申请权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_NUMBERS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_NUMBERS}, REQUEST_READ_PHONE_NUMBERS); } } // 处理权限申请结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_READ_PHONE_NUMBERS) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.i("Permission", "READ_PHONE_NUMBERS 权限已授予"); } else { Log.w("Permission", "READ_PHONE_NUMBERS 权限被拒绝,无法读取完整号码"); } } }
2. 正确提取电话号码的方式
别再依赖callDetails.toString()了,系统会模糊这里的敏感信息,要通过Call.Details.getHandle()获取PhoneNumberHandle,再提取号码:
修改你的onScreenCall方法:
@RequiresApi(api = Build.VERSION_CODES.Q) @Override public void onScreenCall(Call.Details callDetails) { CallResponse.Builder response = new CallResponse.Builder(); PhoneNumberHandle phoneHandle = callDetails.getHandle(); if (phoneHandle != null) { String fullPhoneNumber = phoneHandle.getNumber(); Log.i("CallScreeningService", "获取到完整号码:" + fullPhoneNumber); } else { Log.w("CallScreeningService", "无法获取电话号码,可能是权限不足或系统限制"); } // 必须调用respondToCall返回响应,否则系统会默认处理通话 respondToCall(callDetails, response.build()); }
3. 关键:设置你的应用为默认来电筛选应用
这一步很容易被忽略!即使权限都齐了,如果你的应用没被设为系统默认的来电筛选应用,还是拿不到完整号码。让用户按这个路径设置:
设置 > 应用 > 电话 > 来电筛选和阻止 > 选择你的应用
额外注意事项
PROCESS_OUTGOING_CALLS权限在API 29已经被废弃了,你用CallScreeningService处理呼出电话是正确的选择,不用再维护这个权限。- 可以在系统设置的应用权限页面,手动检查所有申请的权限是否真的被授予。
内容的提问来源于stack exchange,提问作者Jaitnium
相关产品推荐
相关产品推荐

