Android设备拦截所有号码仅放行白名单号码的API及实现方案问询
Android 实现“拦截所有来电,仅放行白名单号码”的方案
刚好我之前做过类似的需求,给你梳理下Android官方支持的两种靠谱方案,完全能实现你要的「拦截所有来电,仅放行白名单」的效果:
一、使用官方CallScreeningService API(推荐,Android 8.0+)
这是Android官方专门为来电筛选提供的API,也是目前最合规、最稳定的方案,能在来电响铃前直接处理,不会出现延迟或者系统拦截的问题。
实现步骤:
- 注册服务:在
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>
- 实现筛选逻辑:继承
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()); } }
- 申请权限:需要在运行时申请
READ_PHONE_STATE权限,系统会自动引导用户授权你的应用作为来电筛选器。
二、通过TelephonyManager监听来电(兼容旧版本,Android 8.0以下)
如果需要兼容Android 7及以下版本,可以通过监听来电状态广播的方式实现,但在高版本系统中限制较多(比如隐式广播不能静态注册)。
实现要点:
- 动态注册广播接收器: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);
- 实现拦截逻辑:在广播接收器中判断来电状态,拦截非白名单号码:
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(); } } } } } }
- 权限注意:需要申请
READ_PHONE_STATE、ANSWER_PHONE_CALLS(Android 8.0+)权限,部分国产机型可能需要额外开启系统级的“电话拦截”权限。
补充说明
- 白名单建议存储在本地数据库或SharedPreferences中,方便用户随时修改维护。
- 对于无号码的未知来电,可以统一拦截或者根据需求单独处理。
- 高版本系统中,CallScreeningService是官方唯一推荐的来电拦截方案,广播方式可能会被系统限制或出现响应延迟。
内容的提问来源于stack exchange,提问作者recoup8063
相关产品推荐
相关产品推荐

