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

Android设备拦截所有号码仅放行白名单号码的API及实现方案问询

Android 实现“拦截所有来电,仅放行白名单号码”的方案

刚好我之前做过类似的需求,给你梳理下Android官方支持的两种靠谱方案,完全能实现你要的「拦截所有来电,仅放行白名单」的效果:

一、使用官方CallScreeningService API(推荐,Android 8.0+)

这是Android官方专门为来电筛选提供的API,也是目前最合规、最稳定的方案,能在来电响铃前直接处理,不会出现延迟或者系统拦截的问题。

实现步骤:

  1. 注册服务:在AndroidManifest.xml中声明你的筛选服务,需要绑定BIND_SCREENING_SERVICE权限:
<service
    android:name=".MyCallScreeningService"
    android:permission="android.permission.BIND_SCREENING_SERVICE">
    <intent-filter>
        <action android:name="android.telecom.CallScreeningService" />
    </intent-filter>
</service>
  1. 实现筛选逻辑:继承CallScreeningService,在onScreenCall方法里判断来电号码是否在白名单,不在就直接拦截:
public class MyCallScreeningService extends CallScreeningService {
    @Override
    public void onScreenCall(Call.Details callDetails) {
        // 获取来电号码(注意处理带区号/特殊格式的情况)
        String incomingNumber = callDetails.getHandle().getSchemeSpecificPart();
        // 替换成你的白名单数据(可从本地存储/云端动态获取)
        Set<String> whiteList = new HashSet<>(Arrays.asList("138xxxx1234", "139xxxx5678"));
        
        CallResponse.Builder responseBuilder = new CallResponse.Builder();
        if (!whiteList.contains(incomingNumber)) {
            // 拦截配置:拒绝来电+不响铃+不显示通知
            responseBuilder.setDisallowCall(true)
                          .setRejectCall(true)
                          .setSkipNotification(true);
        } else {
            // 放行白名单号码
            responseBuilder.setAllowCall(true);
        }
        // 提交处理结果
        respondToCall(callDetails, responseBuilder.build());
    }
}
  1. 申请权限:需要在运行时申请READ_PHONE_STATE权限,系统会自动引导用户授权你的应用作为来电筛选器。

二、通过TelephonyManager监听来电(兼容旧版本,Android 8.0以下)

如果需要兼容Android 7及以下版本,可以通过监听来电状态广播的方式实现,但在高版本系统中限制较多(比如隐式广播不能静态注册)。

实现要点:

  1. 动态注册广播接收器:Android 8.0+禁止静态注册ACTION_PHONE_STATE_CHANGED广播,所以需要在代码中动态注册:
// 在Activity或Service中完成注册
CallReceiver callReceiver = new CallReceiver();
IntentFilter filter = new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(callReceiver, filter);
  1. 实现拦截逻辑:在广播接收器中判断来电状态,拦截非白名单号码:
public class CallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            // 当电话响铃时触发处理
            if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
                String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
                Set<String> whiteList = new HashSet<>(Arrays.asList("138xxxx1234", "139xxxx5678"));
                
                if (!whiteList.contains(incomingNumber)) {
                    // 高版本需要ANSWER_PHONE_CALLS权限才能结束通话
                    TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
                    if (telecomManager != null && ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
                        telecomManager.endCall();
                    }
                }
            }
        }
    }
}
  1. 权限注意:需要申请READ_PHONE_STATE、ANSWER_PHONE_CALLS(Android 8.0+)权限,部分国产机型可能需要额外开启系统级的“电话拦截”权限。

补充说明

  • 白名单建议存储在本地数据库或SharedPreferences中,方便用户随时修改维护。
  • 对于无号码的未知来电,可以统一拦截或者根据需求单独处理。
  • 高版本系统中,CallScreeningService是官方唯一推荐的来电拦截方案,广播方式可能会被系统限制或出现响应延迟。

内容的提问来源于stack exchange,提问作者recoup8063

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:23:08