如何在Flutter应用后台/终止时收到来电通知自动启动并跳转指定页面?
Flutter后台/终止状态下通过来电通知唤醒应用并跳转指定页面
针对你需要实现的来电通知唤醒应用并跳转页面的需求,分Android和iOS平台给出具体实现方案,结合你已有的flutter_local_notifications和MethodChannel配置落地:
Android 实现步骤
1. 配置通知的 PendingIntent(原生层)
创建来电通知时,给通知绑定能唤醒应用的PendingIntent并携带跳转参数,确保应用在后台/终止状态下能被唤起:
// Kotlin 示例代码(Android 原生) val intent = Intent(this, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK putExtra("route", "/call_page") // 传递跳转路由标识 } // Android 12+ 必须指定 FLAG_IMMUTABLE/FLAG_MUTABLE val pendingIntent = PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) // 将该 PendingIntent 关联到 flutter_local_notifications 的通知配置中
用户点击通知后,应用会被唤醒并启动MainActivity;若需自动触发(需注意Android后台启动限制),可通过广播或服务主动调用该PendingIntent。
2. 处理启动/唤醒时的参数传递
- 应用终止状态:在
MainActivity的onCreate中读取Intent参数,通过MethodChannel传递给Flutter:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) intent?.extras?.getString("route")?.let { route -> val channel = MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, "app_route_channel") channel.invokeMethod("navigateToRoute", route) } }
- 应用后台状态:重写
onNewIntent方法处理参数:
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) intent?.extras?.getString("route")?.let { route -> val channel = MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, "app_route_channel") channel.invokeMethod("navigateToRoute", route) } }
3. Flutter 层接收参数并跳转
在Flutter初始化时监听MethodChannel回调,触发页面跳转:
final MethodChannel _routeChannel = MethodChannel('app_route_channel'); final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); void main() async { WidgetsFlutterBinding.ensureInitialized(); // 监听原生传递的路由指令 _routeChannel.setMethodCallHandler((call) async { if (call.method == 'navigateToRoute') { String route = call.arguments as String; Navigator.pushNamed(navigatorKey.currentContext!, route); } }); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( navigatorKey: navigatorKey, initialRoute: '/', routes: { '/': (context) => const HomePage(), '/call_page': (context) => const CallPage(), }, ); } }
iOS 实现步骤
iOS系统对后台唤醒有严格限制,普通通知需用户点击才能唤起应用;仅VoIP场景可通过PushKit实现无交互自动唤醒,分两种情况处理:
情况1:普通来电通知(需用户点击)
1. 配置通知的 userInfo 参数
在iOS原生创建通知时,给UNMutableNotificationContent添加路由参数:
// Swift 示例代码(iOS 原生) let content = UNMutableNotificationContent() content.title = "来电通知" content.body = "有新的来电" content.userInfo = ["route": "/call_page"] // 携带跳转标识 let request = UNNotificationRequest(identifier: "call_notification", content: content, trigger: nil) UNUserNotificationCenter.current().add(request)
2. 处理通知点击事件
- 应用终止状态:在
AppDelegate的didFinishLaunchingWithOptions中读取参数:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { if let notification = launchOptions?[.remoteNotification] as? [String: Any], let route = notification["route"] as? String { let channel = FlutterMethodChannel(name: "app_route_channel", binaryMessenger: window?.rootViewController as! FlutterBinaryMessenger) channel.invokeMethod("navigateToRoute", arguments: route) } GeneratedPluginRegistrant.register(with: self) return true }
- 应用后台状态:实现
UNUserNotificationCenterDelegate的回调方法:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { if let route = response.notification.request.content.userInfo["route"] as? String { let channel = FlutterMethodChannel(name: "app_route_channel", binaryMessenger: window?.rootViewController as! FlutterBinaryMessenger) channel.invokeMethod("navigateToRoute", arguments: route) } completionHandler() }
情况2:VoIP来电(自动唤醒应用)
若为VoIP场景,需使用PushKit框架,配合flutter_voip_push_notification库实现:
- 在iOS开发者后台开启VoIP推送权限,配置APNs证书。
- 原生层实现
PKPushRegistryDelegate,在didReceiveIncomingPushWith方法中唤醒应用并传递来电参数给Flutter。 - Flutter层监听VoIP推送回调,直接跳转至来电页面。
关键注意事项
- Android 12+ 必须指定
PendingIntent的FLAG_IMMUTABLE或FLAG_MUTABLE,否则会触发崩溃。 - iOS普通通知无法自动打开应用,仅VoIP场景可实现终止状态下的自动唤醒。
- 确保
flutter_local_notifications配置正确:Android需在AndroidManifest.xml中声明通知渠道,iOS需主动请求通知权限。
内容的提问来源于stack exchange,提问作者Syeda Romaisa
相关产品推荐
相关产品推荐

