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

Flutter中如何获取电话通话状态,判断通话是否断开或被接听?

针对通话状态监听、接听判断及断开检测的需求,分Android和iOS平台给出具体实现方案:

Android 平台实现

监听通话状态

通过TelephonyManager结合广播接收器监听状态变化:

  1. 自定义广播接收器,监听android.intent.action.PHONE_STATE系统动作
  2. 在接收器的onReceive方法中,从Intent中提取状态参数,判断当前通话状态:
    • TelephonyManager.EXTRA_STATE_IDLE:无活跃通话(已断开)
    • TelephonyManager.EXTRA_STATE_OFFHOOK:通话中(已被接听)
    • TelephonyManager.EXTRA_STATE_RINGING:来电响铃(未接听)

代码示例(Kotlin)

class CallStatusReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val currentState = intent?.getStringExtra(TelephonyManager.EXTRA_STATE)
        when (currentState) {
            TelephonyManager.EXTRA_STATE_IDLE -> {
                // 通话已断开,执行你的业务操作
            }
            TelephonyManager.EXTRA_STATE_OFFHOOK -> {
                // 通话已被接听,执行你的业务操作
            }
            TelephonyManager.EXTRA_STATE_RINGING -> {
                // 来电响铃,可做前置处理
            }
        }
    }
}

权限与注册

需要在AndroidManifest.xml中声明权限并注册接收器:

<!-- 必要权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 可选,用于读取历史通话记录辅助判断 -->
<uses-permission android:name="android.permission.READ_CALL_LOG" />

<receiver android:name=".CallStatusReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
</receiver>

注意:Android 10及以上版本需要动态申请READ_PHONE_STATE权限。

iOS 平台实现

iOS提供两种方案,推荐用CallKit(适配新版本系统):

方案1:CoreTelephony(iOS 13及以下兼容)

通过CTCallCenter监听蜂窝通话状态:

import CoreTelephony

let callCenter = CTCallCenter()
callCenter.callEventHandler = { call in
    switch call.callState {
    case .connected:
        // 通话已接听
    case .disconnected:
        // 通话已断开
    case .incoming:
        // 来电未接听
    case .dialing:
        // 拨号中
    default:
        break
    }
}

⚠️ iOS 14及以上CTCallCenter已被废弃,建议使用CallKit。

方案2:CallKit(推荐,全版本适配)

实现CXCallObserverDelegate监听所有通话(含VoIP和蜂窝):

import CallKit

class CallStatusObserver: NSObject, CXCallObserverDelegate {
    private let callObserver = CXCallObserver()
    
    override init() {
        super.init()
        callObserver.setDelegate(self, queue: DispatchQueue.main)
    }
    
    func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
        if call.hasEnded {
            // 通话已断开
        }
        if call.isConnected {
            // 通话已被接听
        }
        if call.isIncoming && !call.isConnected {
            // 来电未接听
        }
        if call.isOutgoing && !call.isConnected {
            // 拨号中未接通
        }
    }
}

// 使用时初始化即可
let observer = CallStatusObserver()
核心判断逻辑总结
  • 通话是否已接听:Android触发EXTRA_STATE_OFFHOOK状态,iOS触发isConnected(CallKit)或.connected(CoreTelephony)状态时,判定为已接听。
  • 通话是否已断开:Android触发EXTRA_STATE_IDLE状态,iOS触发hasEnded(CallKit)或.disconnected(CoreTelephony)状态时,判定为已断开。

内容的提问来源于stack exchange,提问作者Kanu Thakor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:09:24