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

Flutter应用实现Android来电拦截时遇隐藏方法访问权限错误

Android Flutter 来电拦截报错:Accessing hidden method getITelephony() 解决方法

错误详情

Accessing hidden method Landroid/telephony/TelephonyManager;->getITelephony()Lcom/android/internal/telephony/ITelephony; (greylist-max-p, reflection, denied)
E/CallBlocker(19807): Error blocking call: android.telephony.TelephonyManager.getITelephony []

错误原因

这个问题的核心是Android 9(API 28)及以上版本严格限制了系统隐藏API的反射调用。getITelephony()属于Android内部的隐藏方法,被标记为greylist-max-p,意味着从Android P开始,第三方应用通过反射访问该方法会被系统直接拒绝。

解决方案

1. 改用官方合规的来电拦截方案(推荐)

从Android 10(API 29)开始,官方提供了CallScreeningService作为标准的来电拦截接口,完全规避隐藏API的限制:

  • 在AndroidManifest.xml中注册服务:
    <service
        android:name=".CallBlockerService"
        android:permission="android.permission.BIND_SCREENING_SERVICE">
        <intent-filter>
            <action android:name="android.telecom.CallScreeningService" />
        </intent-filter>
    </service>
    
  • 创建继承自CallScreeningService的服务类,重写拦截逻辑:
    public class CallBlockerService extends CallScreeningService {
        @Override
        public void onScreenCall(Call.Details callDetails) {
            // 自定义号码拦截判断逻辑
            boolean shouldBlock = checkBlacklist(callDetails.getHandle().getSchemeSpecificPart());
            
            CallResponse.Builder responseBuilder = new CallResponse.Builder();
            if (shouldBlock) {
                responseBuilder.setDisallowCall(true);
                responseBuilder.setRejectCall(true);
            }
            respondToCall(callDetails, responseBuilder.build());
        }
    
        private boolean checkBlacklist(String phoneNumber) {
            // 这里实现黑名单匹配逻辑
            return false;
        }
    }
    
  • Flutter端通过MethodChannel动态申请READ_PHONE_STATE、ANSWER_PHONE_CALLS权限,触发服务启动。

2. 低版本Android兼容处理(仅适用于API 28及以下)

如果需要支持Android 9及更低版本,可直接使用TelephonyManager的endCall()方法,避免反射调用:

  • 在AndroidManifest.xml添加权限:
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
    
  • 直接调用endCall()实现拦截(注意:Android 9之后该方法也被限制,仅适配低版本)。

3. 权限申请注意事项

  • 所有危险权限(如READ_PHONE_STATE、ANSWER_PHONE_CALLS)必须在运行时动态申请,不能仅依赖清单声明。
  • Android 11及以上版本,还需要申请READ_CALL_LOG权限才能获取完整的来电号码信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:30:04