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

flutter_callkit_incoming:APP终止状态下接受呼叫无法跳转通话页面

解决Flutter终止状态下接到来电通知后无法跳转通话页面的问题

核心问题在于APP终止状态下,Firebase唤醒APP后FlutterCallkitIncoming的事件监听还未完成初始化,导致接听事件无法被捕获;同时启动阶段没有主动读取呼叫数据触发跳转。以下是针对性解决方案:

1. 捕获APP启动时的唤醒通知参数

在APP初始化入口(比如main函数或首页的initState),添加代码检查是否由Firebase呼叫通知唤醒,并读取对应呼叫数据:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  
  // 获取启动时触发APP的通知数据
  RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
  if (initialMessage != null) {
    var actionType = getNotiActionType(initialMessage.data);
    if (actionType == NotiActionType.incoming_calls) {
      // 读取数据库中最新的呼叫记录
      var latestNoti = await Notification.getLatestNotification(
        dataColumnKey: Notification.actionKey,
        dataColumnValue: Notification.actionValueIncomingCall,
      );
      if (latestNoti != null) {
        // 存储呼叫参数,等待APP初始化完成后跳转
        GlobalValue().setPendingCallProps(await CallNotificationProps.fromDatabase(latestNoti));
      }
    }
  }

  runApp(const MyApp());
}

2. 初始化Callkit监听后处理待跳转的呼叫

在你初始化FlutterCallkitIncoming.onEvent的位置,添加启动时的待处理呼叫检查逻辑:

FlutterCallkitIncoming.onEvent.listen((CallEvent? callEvent) async {
  var callNoti = CallNotification(
    callNotification: CallNotificationProps.getEmptyProps,
    deviceToken: "",
  );

  // 优先处理APP终止状态唤醒的待跳转呼叫
  var pendingProps = GlobalValue().getPendingCallProps();
  if (pendingProps != null) {
    callNoti.callNotification = pendingProps;
    await Navigator.pushNamed(
      context, callScreenRoute,
      arguments: {"call_props": callNoti}
    );
    // 清空待处理标记
    GlobalValue().setPendingCallProps(null);
    return;
  }

  switch (callEvent?.event) {
    case Event.actionCallIncoming:
      var latestNoti = await noti.Notification.getLatestNotification(
        dataColumnKey: noti.Notification.actionKey,
        dataColumnValue: noti.Notification.actionValueIncomingCall,
      );
      var actionType = getNotiActionType(latestNoti?.data);
      if (actionType == NotiActionType.incoming_calls) {
        callNoti.callNotification = await CallNotificationProps.fromDatabase(latestNoti);
      }
      break;
    case Event.actionCallAccept:
      await Navigator.pushNamed(
        context, callScreenRoute,
        arguments: {"call_props": callNoti}
      );
      break;
  }
});

3. 优化Firebase后台消息处理逻辑

确保后台处理Firebase消息时,正确初始化Firebase并完成呼叫数据存储:

@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(); // 后台环境需重新初始化Firebase
  if (message.notification != null) {
    var apiActionType = getNotiActionType(message.data);
    if (apiActionType == NotiActionType.incoming_calls) {
      await FirebaseApi.handleIncomingCallNoti(message);
    } else {
      await Notification.insertDatabase(
        title: message.notification!.title!,
        message: message.notification!.body!,
        data: message.data,
        receiveDatetime: DateTime.now(),
      );
    }
  }
}

关键说明

  • 终止状态下APP被Firebase唤醒时,getInitialMessage()能获取到触发唤醒的通知数据,以此追溯呼叫信息
  • 用全局变量暂存待处理的呼叫参数,等待APP完成初始化、路由栈准备就绪后再执行跳转
  • 后台处理Firebase消息必须重新初始化Firebase,否则数据库操作会失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:59:56