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

Android SDK30下如何通过编程方式实现来电拒接

问题根因

你当前使用的反射调用com.android.internal.telephony.ITelephony#endCall的方案在API 30(Android 11)上完全失效,核心原因两点:

  • Android 9之后系统持续收紧隐藏API访问限制,第三方应用直接反射调用internal包下的非公开接口会被系统直接拦截
  • 从API 28开始系统已经公开提供了正式的挂断电话API,老的隐藏接口本身也已经被系统废弃,不再对第三方应用开放
    你写的反射代码本身也存在逻辑错误:通过ServiceManager拿系统服务的路径对第三方应用锁死,调用asInterface时传入null参数根本拿不到有效的服务代理对象,自然无法触发挂断操作。
前置配置

首先在AndroidManifest.xml中添加必须的权限:

<!-- Android 9+ 接听/挂断电话必须的核心权限 -->
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<!-- 读取通话状态必备权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 兼容Android 8及以下版本需要的权限 -->
<uses-permission android:name="android.permission.CALL_PHONE" />

注意:ANSWER_PHONE_CALLS属于危险权限,必须在代码中动态申请,未获得授权时挂断逻辑会直接被系统拒绝。

可用实现代码

直接丢弃你之前的无效反射逻辑,使用系统公开的TelecomManager接口实现,仅在Android 8以下版本用反射做兼容兜底:

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import androidx.core.content.ContextCompat;
import java.lang.reflect.Method;

public class CallUtils {
    public static void disconnectCall(Context context) {
        // 权限校验,未授权直接终止操作
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS)
                != PackageManager.PERMISSION_GRANTED) {
            return;
        }

        // Android 9及以上走官方公开API,无隐藏接口限制
        TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && telecomManager != null) {
            if (telecomManager.endCall()) {
                return;
            }
        }

        // 仅Android 8及以下老版本用反射逻辑兜底
        try {
            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Class<?> iTelephonyCls = Class.forName("com.android.internal.telephony.ITelephony");
            Method getITelephonyMethod = TelephonyManager.class.getDeclaredMethod("getITelephony");
            getITelephonyMethod.setAccessible(true);
            Object iTelephonyProxy = getITelephonyMethod.invoke(telephonyManager);
            Method endCallMethod = iTelephonyCls.getDeclaredMethod("endCall");
            endCallMethod.setAccessible(true);
            endCallMethod.invoke(iTelephonyProxy);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
注意事项
  • 权限申请顺序:先申请READ_PHONE_STATE权限,拿到授权后再申请ANSWER_PHONE_CALLS,否则权限申请会被系统驳回
  • 不要尝试发送ACTION_CANCEL_CALL广播实现挂断,该广播仅允许系统默认拨号应用发送,第三方自定义来电屏应用无发送权限
  • 测试请使用真机,部分安卓模拟器阉割了Telecom服务实现,会出现API调用返回失败的问题,模拟器测试结果不具备参考性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:03:23