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

如何在Android Oreo中以编程方式挂断电话?

嘿,在Android Oreo(API 26)及更高版本里,你原来依赖的反射getITelephony()的方法已经行不通啦——谷歌从Oreo开始收紧了对电话相关API的权限限制,私有方法的反射调用会被系统拦截。下面给你两种靠谱的实现方案,适配不同版本:

方法1:使用官方TelecomManager API(推荐)

这是谷歌推荐的正规方式,兼容性最好,步骤如下:

1. 声明权限

首先在AndroidManifest.xml里添加必要的权限:

<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.CALL_PHONE" />

注意:ANSWER_PHONE_CALLS在API 26+需要动态申请,用户手动授权后才能使用。

2. 实现挂断逻辑

编写代码判断系统版本,针对Oreo及以上使用TelecomManager,低版本 fallback 到原来的反射方法:

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 android.widget.Toast;
import java.lang.reflect.Method;

public class CallUtils {
    public static boolean killCall(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Android Oreo及以上使用TelecomManager
            TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
            
            // 检查权限是否已授权
            if (context.checkSelfPermission(Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(context, "需要授予挂断电话权限", Toast.LENGTH_SHORT).show();
                // 这里可以触发动态权限申请流程
                return false;
            }
            
            try {
                telecomManager.endCall();
                return true;
            } catch (SecurityException e) {
                e.printStackTrace();
                Toast.makeText(context, "挂断电话失败:权限不足", Toast.LENGTH_SHORT).show();
                return false;
            }
        } else {
            // 低版本使用反射方法(兼容API 25及以下)
            try {
                TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                Class<?> telephonyClass = Class.forName(telephonyManager.getClass().getName());
                Method getITelephonyMethod = telephonyClass.getDeclaredMethod("getITelephony");
                getITelephonyMethod.setAccessible(true);
                
                Object iTelephony = getITelephonyMethod.invoke(telephonyManager);
                Method endCallMethod = iTelephony.getClass().getDeclaredMethod("endCall");
                endCallMethod.invoke(iTelephony);
                
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                Toast.makeText(context, "挂断电话失败:反射调用出错", Toast.LENGTH_SHORT).show();
                return false;
            }
        }
    }
}

关键注意点

  • 动态申请权限:在调用killCall()之前,要先检查ANSWER_PHONE_CALLS权限是否已获取,如果没有,需要调用Activity.requestPermissions()发起申请。
  • Android 10+兼容:如果你的App需要支持API 29及以上,TelecomManager.endCall()会被废弃,需要改用TelecomManager.endCall(String callId),这时候需要获取当前通话的ID,并且需要MANAGE_OWN_CALLS权限或者将App设置为默认电话应用。
方法2:使用广播接收器(不推荐,兼容性差)

有些旧设备可能支持通过发送特定Intent来挂断电话,但这种方式在Oreo及以上基本被厂商限制,仅作参考:

// 仅部分旧设备有效
Intent intent = new Intent("android.intent.action.CALL");
intent.setData(Uri.parse("tel:"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);

这种方式依赖厂商实现,稳定性无法保证,不建议在生产环境使用。


内容的提问来源于stack exchange,提问作者Ali Akram

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:08:53