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

如何从CallLog.Calls获取通话断开原因及外呼时的获取方案

关于Android通话断开原因的获取方案

我来帮你梳理下Android平台上获取通话断开原因的可行思路,刚好你提到的外呼场景有明确的解决方案:

1. 原生CallLog.Calls能拿到断开原因吗?

很遗憾,原生系统的CallLog.Calls并没有提供直接存储通话断开原因的字段。默认的通话日志只记录了通话类型(呼出/呼入/未接)、时长、号码这些基础信息,没法直接拿到“网络问题”“对方主动挂断”这类具体原因。当然,有些手机厂商的定制ROM可能会自己扩展这个字段,但这不是标准行为,没法在所有设备上通用。

2. 外呼场景下获取断开原因的靠谱方式

如果是你自己的应用发起外呼,有两种精准的方案可以拿到断开原因:

a. 用Telecom API监听通话全生命周期

从Android 5.0(API 21)开始,系统提供了Telecom API,你可以通过Call.Callback来监听通话的每一个状态变化,包括断开时的具体原因:

  • 当你发起外呼后,通话会进入CALL_STATE_RINGING(对方响铃)状态,一旦通话断开,onDisconnect回调会触发,你可以通过DisconnectCause对象拿到具体的断开原因码。
  • 比如DisconnectCause.NETWORK_FAILURE就是网络问题导致中断,DisconnectCause.REJECTED是对方拒接,DisconnectCause.CANCELED是己方主动挂断,完全能满足你“记录网络问题、忽略对方挂断”的需求。

给你一段示例代码参考:

Call.Callback callCallback = new Call.Callback() {
    @Override
    public void onDisconnect(Call call, DisconnectCause disconnectCause) {
        super.onDisconnect(call, disconnectCause);
        int causeCode = disconnectCause.getCode();
        if (causeCode == DisconnectCause.NETWORK_FAILURE) {
            // 把网络问题记录到你的数据表
            saveCallLogToDatabase("网络异常导致通话中断");
        } else if (causeCode == DisconnectCause.REJECTED) {
            // 对方主动挂断,按需求忽略
        }
        // 其他断开原因可以根据业务逻辑处理
    }
};

// 绑定回调到TelecomManager
TelecomManager telecomManager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
if (telecomManager != null) {
    telecomManager.addCallCallback(callCallback);
}

b. 旧版本兼容:用PhoneStateListener监听状态

如果你的应用需要兼容Android 5.0以下的系统,可以用旧的PhoneStateListener来监听通话状态变化。不过这种方式的局限性比较大,只能拿到状态切换(比如从响铃回到空闲),没法直接拿到精确的断开原因,需要结合通话时长等信息推断,不如Telecom API精准。

3. 要注意的权限问题

不管用哪种方案,都需要申请对应的权限:

  • Android 10及以上需要READ_PHONE_STATE、CALL_PHONE,部分场景还需要ACCESS_FINE_LOCATION;
  • 低版本系统主要是READ_PHONE_STATE和CALL_PHONE权限,记得要动态申请,不然会被系统拒绝访问。

内容的提问来源于stack exchange,提问作者Kumar Elubandi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:47:17