Flutter应用后台/终止状态接收Firebase通知时自动打开指定页面方法
Flutter 后台/进程终止状态下接收FCM唤起指定页面落地实现方案
这个方案覆盖应用前台、后台存活、进程完全杀死三种状态,效果对齐callKeep类来电唤醒交互,所有步骤都是生产环境验证过的可落地方案。
前置依赖准备
在pubspec.yaml中添加以下依赖(均为当前维护状态稳定的版本,无兼容性问题):
firebase_messaging:处理FCM消息收发逻辑flutter_callkit_incoming:实现系统级来电弹窗,支持锁屏、杀进程状态下的全屏提醒,替代维护停滞的callKeep插件- 路由层使用项目原有路由即可,要求支持全局无context跳转(如果没有可以自行配置
GlobalKey<NavigatorState>实现)
原生端必要配置
这部分是实现杀进程唤醒的核心,跳过会直接导致功能失效。
安卓端配置
- 打开
android/app/src/main/AndroidManifest.xml,在manifest根节点下添加以下权限:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
- 找到MainActivity的注册节点,将
android:launchMode属性设置为singleTop,避免重复启动应用实例。 - 注意:小米、华为、OPPO、vivo等国产ROM默认限制应用后台弹出界面、自启动权限,首次启动应用时需要引导用户手动开启这两个权限,否则杀进程状态下无法正常唤起。
iOS端配置
- 提前申请VoIP推送证书,不要使用普通APNs证书:普通APNs推送在应用进程被杀时无法执行自定义代码,只有VoIP推送具备后台/杀进程唤醒应用的能力。
- 打开
ios/Runner/Info.plist,添加以下权限和后台模式配置:
<key>UIBackgroundModes</key> <array> <string>voip</string> <string>remote-notification</string> <string>fetch</string> </array> <key>NSUserNotificationsUsageDescription</key> <string>需要通知权限展示来电提醒</string>
- 注意iOS系统规则:收到VoIP推送后必须立刻弹出CallKit系统来电界面,若多次收到推送不弹窗,系统会直接禁用该应用的VoIP推送权限。
核心业务逻辑实现
1. FCM消息规则配置
要实现唤醒能力,发送的FCM消息必须满足以下要求:
- 必须是纯data类型消息,不要携带
notification字段:携带notification字段的消息会被系统直接拦截生成系统通知,不会进入自定义消息处理逻辑,杀进程状态下完全无法触发代码执行。 - 消息优先级设置为
high,iOS端对应开启content_available: true。 - 标准消息体示例:
{ "to": "目标设备FCM token", "priority": "high", "content_available": true, "data": { "type": "incoming_call", "target_route": "/call_page", "caller_name": "张三", "caller_id": "10086", "call_uuid": "随机生成的唯一call id" } }
2. 消息接收与唤醒逻辑
分三个状态处理消息:
- 前台状态:收到FCM data消息后,直接调用
flutter_callkit_incoming展示系统级来电弹窗,不需要唤起应用。 - 后台存活状态:和前台逻辑一致,直接触发CallKit弹窗,注册弹窗点击事件回调。
- 进程杀死状态:安卓端原生FirebaseMessagingService收到高优先级data消息后,不需要等Flutter引擎初始化,直接在原生层弹出CallKit全屏来电通知;iOS端收到VoIP推送后按系统要求立刻弹出CallKit来电界面。用户点击弹窗的接听按钮时,自动启动应用,同时将消息携带的路由参数传递给Flutter层。
3. 路由跳转逻辑
- 应用冷启动时,第一时间调用
FlutterCallkitIncoming.getLaunchCallParams()获取启动参数:如果参数不为空,说明是从杀进程状态下点击来电通知启动的,等首帧渲染完成后直接跳转到参数指定的页面,跳过正常首页流程。 - 注册CallKit全局事件监听:
- 监听接听事件:如果应用已经在前台/后台存活,直接跳转到指定页面
- 监听挂断事件:关闭弹窗,不做页面跳转
- 全局路由必须配置无context跳转能力,避免因为当前没有可用context导致跳转失败。
常见踩坑说明
- 不要在FCM后台消息回调中执行耗时超过10秒的操作,安卓端后台服务有执行时长限制,超时会被系统直接杀死。
- 测试杀进程场景时,不要用adb am force-stop命令杀应用,部分安卓ROM下adb强制停止的应用会被禁止自启动,和用户手动划掉杀进程的逻辑不一致,容易出现测试结果和实际用户场景不符的问题。
- iOS端不要尝试绕过CallKit实现后台唤起,审核会被拒,同时也不符合系统规则。
内容的提问来源于stack exchange,提问作者Santosh Kumar
相关产品推荐
相关产品推荐

