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

如何在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库实现:

  1. 在iOS开发者后台开启VoIP推送权限,配置APNs证书。
  2. 原生层实现PKPushRegistryDelegate,在didReceiveIncomingPushWith方法中唤醒应用并传递来电参数给Flutter。
  3. Flutter层监听VoIP推送回调,直接跳转至来电页面。

关键注意事项

  • Android 12+ 必须指定PendingIntent的FLAG_IMMUTABLE或FLAG_MUTABLE,否则会触发崩溃。
  • iOS普通通知无法自动打开应用,仅VoIP场景可实现终止状态下的自动唤醒。
  • 确保flutter_local_notifications配置正确:Android需在AndroidManifest.xml中声明通知渠道,iOS需主动请求通知权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:00:05