You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:50:21