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

Android Studio开发中如何实现应用内电话管理及通话挂断功能

Android 实现通话挂断/拒接方案

你当前使用的ACTION_CALL拨号代码在Android 6.0以上版本需要动态申请CALL_PHONE权限才能正常运行,否则会触发权限异常崩溃。
关于通话挂断/拒接功能,Android系统没有提供可直接跳转的Intent实现,需要根据系统版本区分调用对应API,具体实现逻辑如下:

前置权限配置

首先在AndroidManifest.xml中声明所需权限:

<!-- 读取通话状态基础权限,所有版本必需 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Android 9.0+ 挂断通话必需权限 -->
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<!-- Android 8.1及以下版本挂断通话必需权限 -->
<uses-permission android:name="android.permission.CALL_PHONE" />

所有危险权限在Android 6.0以上版本都需要在代码中动态申请,拿到授权后再调用挂断逻辑。

分版本实现逻辑

Android 9.0(API 28)及以上版本

该版本开始系统开放了官方公开的挂断API,稳定性最高,不需要反射:

TelecomManager telecomManager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
// 先判断当前是否存在进行中的通话
if (telecomManager != null && telecomManager.isInCall()) {
    try {
        // 调用官方API终止当前通话
        boolean callSuccess = telecomManager.endCall();
        // callSuccess为true代表挂断指令已被系统接收
    } catch (SecurityException e) {
        // 未拿到权限的异常处理
        e.printStackTrace();
    }
}

Android 6.0(API 23)~ Android 8.1(API 27)

该版本区间没有公开的挂断API,需要通过反射调用系统隐藏的ITelephony接口实现,绝大多数厂商ROM都保留了该隐藏接口,兼容性较好:

public void endCall() {
    try {
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        Method getITelephony = TelephonyManager.class.getDeclaredMethod("getITelephony");
        getITelephony.setAccessible(true);
        Object iTelephony = getITelephony.invoke(telephonyManager);
        Method endCall = iTelephony.getClass().getDeclaredMethod("endCall");
        endCall.setAccessible(true);
        endCall.invoke(iTelephony);
    } catch (Exception e) {
        e.printStackTrace();
        // 部分深度定制ROM修改了隐藏接口,可在此处加降级逻辑
    }
}

Android 6.0以下版本(API < 23)

直接使用上述反射ITelephony的方案即可,该版本区间权限为安装时自动授予,无需动态申请,兼容性接近100%。

补充说明

  • 拒接响铃中的来电、挂断已接通的通话使用的是同一套endCall逻辑,不需要单独做区分。如果需要判断当前通话状态,可通过TelephonyManager.getCallState()获取:
    • TelephonyManager.CALL_STATE_IDLE:当前无通话
    • TelephonyManager.CALL_STATE_RINGING:来电响铃中,此时调用endCall为拒接来电
    • TelephonyManager.CALL_STATE_OFFHOOK:通话已接通,此时调用endCall为挂断通话
  • Android 10及以上版本限制了后台应用调用电话相关API,调用挂断逻辑时你的应用需要处于前台,或者绑定了前台服务,否则系统会直接拦截调用。
  • 不建议使用模拟按键、无障碍服务模拟点击的方案实现挂断,稳定性极差,且容易被系统安全机制判定为恶意行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:18:17