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

Flutter中APP后台/关闭时视频通话通知弹窗及跳转优化问题

解决方案:视频通话通知弹窗与推送跳转优化

一、实现类似WhatsApp的通话通知弹窗

普通本地通知无法达到通话类APP的弹窗效果,需针对Android和iOS分别处理:

Android端配置

  • 创建高优先级通知渠道并开启全屏意图:
    使用flutter_local_notifications初始化时,指定高重要性的渠道,同时开启fullScreenIntent,确保通知能以悬浮/全屏形式弹出:
    const AndroidNotificationChannel callChannel = AndroidNotificationChannel(
      'call_request_channel',
      '视频通话请求',
      description: '接收来自好友的视频通话邀请',
      importance: Importance.high,
      priority: Priority.high,
      enableVibration: true,
      enableLights: true,
      fullScreenIntent: true,
    );
    
    await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(callChannel);
    
  • 发送FCM Data类型消息:后台/APP关闭状态下,必须发送Data消息(而非Notification消息),这样消息会直接进入Flutter的onBackgroundMessage回调,由你主动触发本地通知,而非系统默认展示普通通知。
  • 添加系统悬浮权限:在AndroidManifest.xml中增加权限:
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    

iOS端配置

iOS普通推送无法弹出系统级通话弹窗,必须使用VoIP推送+CallKit:

  • 开启VoIP推送权限:在Apple开发者后台为APP启用VoIP Services,Xcode中开启Background Modes里的Voice over IP选项。
  • 使用PushKit监听推送:借助flutter_voip_push_notification等插件接收VoIP推送,收到请求后通过CallKit框架发起系统通话请求,自动触发类似WhatsApp的弹窗。注意:VoIP推送仅可用于通话场景,否则会被审核拒绝。

二、关闭APP时点击推送直接跳转目标页面

核心是在APP初始化阶段捕获启动消息,直接指定路由:

  1. FCM消息携带路由参数:发送推送时在data字段中加入目标路由和必要参数:

    {
      "data": {
        "route": "/video-call",
        "callerId": "user_123",
        "callToken": "abc_def"
      },
      "to": "DEVICE_PUSH_TOKEN"
    }
    
  2. 初始化时处理启动消息:在main函数中,获取APP被杀死状态下点击推送的消息,直接跳转到目标页面:

    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp();
    
      // 处理APP关闭后点击推送的场景
      RemoteMessage? initialMsg = await FirebaseMessaging.instance.getInitialMessage();
      String? targetRoute = initialMsg?.data['route'];
    
      runApp(MyApp(initialRoute: targetRoute));
    }
    
    class MyApp extends StatelessWidget {
      final String? initialRoute;
      const MyApp({super.key, this.initialRoute});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          initialRoute: initialRoute ?? '/splash',
          routes: {
            '/splash': (ctx) => const SplashScreen(),
            '/home': (ctx) => const HomeScreen(),
            '/video-call': (ctx) => VideoCallScreen(
                  callerId: ModalRoute.of(ctx)?.settings.arguments?['callerId'],
                ),
          },
        );
      }
    }
    
  3. Android启动模式优化:在AndroidManifest.xml的MainActivity中设置启动模式为singleTask,避免重复创建页面栈:

    <activity
        android:name=".MainActivity"
        android:launchMode="singleTask"
        android:exported="true">
        <!-- 其他配置 -->
    </activity>
    

iOS端无需额外配置,getInitialMessage会自动捕获APP关闭状态下的推送点击事件,直接生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:02:08