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

Flutter CallKit Incoming:应用终止时接听电话功能失效

Flutter CallKit 终止状态接听按钮无响应解决方案

核心原因

应用处于终止状态时,Flutter引擎未启动,flutter_callkit_incoming的Dart侧事件回调无法触发,必须通过原生端先唤醒应用,再将通话事件传递到Flutter层处理。

分平台处理方案

iOS端配置

  1. 扩展AppDelegate实现CXProviderDelegate,处理CallKit的接听回调,通过MethodChannel传递事件到Flutter:
import Flutter
import CallKit

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, CXProviderDelegate {
    private var methodChannel: FlutterMethodChannel?

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller = window?.rootViewController as! FlutterViewController
        methodChannel = FlutterMethodChannel(name: "callkit_event_channel", binaryMessenger: controller.binaryMessenger)
        
        // 初始化CallKit Provider
        let config = CXProviderConfiguration(localizedName: "你的通话应用")
        config.supportsVideo = true
        config.maximumCallGroups = 1
        let provider = CXProvider(configuration: config)
        provider.setDelegate(self, queue: nil)
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    // 处理来电接听事件
    func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
        action.fulfill()
        // 传递通话ID到Flutter
        methodChannel?.invokeMethod("acceptCall", arguments: ["callId": action.callUUID.uuidString])
    }
}
  1. 在Xcode中开启Background Modes的Voice over IP权限(项目配置 -> Signing & Capabilities -> 添加Background Modes)。

Android端配置

  1. 创建广播接收器处理接听事件,唤醒应用并传递通话参数:
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import io.flutter.embedding.android.FlutterActivity

class CallKitAcceptReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val callId = intent?.getStringExtra("call_id") ?: return
        // 启动应用并携带通话ID
        val launchIntent = Intent(context, FlutterActivity::class.java).apply {
            putExtra("launch_from_call", true)
            putExtra("call_id", callId)
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
        }
        context?.startActivity(launchIntent)
    }
}
  1. 在AndroidManifest.xml中注册接收器:
<receiver android:name=".CallKitAcceptReceiver">
    <intent-filter>
        <action android:name="com.your.package.ACCEPT_CALL" />
    </intent-filter>
</receiver>
  1. 配置CallKit通知的PendingIntent时,指定上述广播作为触发目标。

Flutter端处理

在应用启动时检查启动参数,判断是否是从终止状态被接听事件唤醒,直接跳转通话界面:

import 'package:flutter/services.dart';
import 'package:flutter/material.dart';

void main() async {
    WidgetsFlutterBinding.ensureInitialized();
    final initialData = await _getInitialCallData();
    runApp(MyApp(initialCallData: initialData));
}

Future<Map<String, dynamic>?> _getInitialCallData() async {
    const channel = MethodChannel('callkit_event_channel');
    try {
        // 读取原生传递的启动参数
        final args = await channel.invokeMethod('getInitialCallArgs');
        if (args != null && args['callId'] != null) {
            return args;
        }
    } catch (e) {
        debugPrint('读取启动参数失败: $e');
    }
    return null;
}

class MyApp extends StatelessWidget {
    final Map<String, dynamic>? initialCallData;

    const MyApp({super.key, this.initialCallData});

    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            initialRoute: initialCallData != null ? '/call_screen' : '/home',
            routes: {
                '/home': (context) => const HomeScreen(),
                '/call_screen': (context) => CallScreen(callId: initialCallData!['callId']),
            },
        );
    }
}

注意事项

  • 测试终止状态时,必须完全关闭应用(后台划掉),不能仅退到后台。
  • Android需确保应用拥有WAKE_LOCK权限,可在AndroidManifest.xml中添加:<uses-permission android:name="android.permission.WAKE_LOCK" />
  • iOS需确保CallKit的配置与应用的权限申请一致,避免被系统拦截。

内容的提问来源于stack exchange,提问作者Kavita Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:01:21