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

Android API30及以上Java实现自定义点击挂断呼入/呼出电话的方案求助

解决Android程序化结束通话的问题

你的问题核心是Android 10(API 29)及以上版本严格限制了系统隐藏API的反射访问,getITelephony()属于系统内部非SDK接口,被加入灰名单后反射调用会被系统拒绝,因此抛出NoSuchMethodException。以下是官方支持的替代方案:

官方合法方案:使用TelecomManager

从Android 9(API 28)开始,官方提供了TelecomManager.endCall()方法用于程序化结束通话,这是唯一合规的实现方式。

步骤1:添加权限到AndroidManifest.xml

<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- Android 13+ 如需前台服务控制通话,需添加: -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CALL_SYSTEM" />

步骤2:替换原有反射代码

将你原来的onClick逻辑替换为以下代码:

close_button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Context context = v.getContext();
        TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);

        // 检查权限是否已授予
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
            try {
                // 尝试结束通话
                boolean isHangUpSuccess = telecomManager.endCall();
                if (isHangUpSuccess) {
                    Log.d("HANG UP", "通话已成功挂断");
                } else {
                    Log.d("HANG UP", "挂断失败:当前无活跃通话或权限不足");
                }
            } catch (SecurityException e) {
                Log.e("HANG UP", "权限异常:无法执行挂断操作", e);
            }
        } else {
            // 动态申请权限
            ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ANSWER_PHONE_CALLS}, 1001);
        }

        // 关闭当前Dialog
        CustomDialog.this.getWindow().getAttributes().windowAnimations = R.style.SlidingDialogAnimation;
        CustomDialog.this.finishAndRemoveTask();
    }
});

关键注意事项

  • 权限申请:ANSWER_PHONE_CALLS是危险权限,必须通过动态申请让用户授权,不能仅依赖Manifest声明。
  • 前台要求:Android 10及以上版本中,后台应用无法调用通话控制接口,需确保你的应用处于前台(如当前Dialog显示中),或使用前台服务维持进程状态。
  • 默认拨号应用:如果你的应用设置为系统默认拨号应用,可获得更宽松的通话控制权限,无需额外申请部分权限,但仍需遵循系统规范。

为什么原有反射方案失效?

从Android 9开始,Google推出了非SDK接口限制政策,将getITelephony()这类内部方法加入灰名单/黑名单,禁止第三方应用通过反射调用。Android 10及以上版本进一步加强了该限制,直接拦截此类反射请求,导致你遇到NoSuchMethodException或权限拒绝异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:55:28