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

Flutter应用后台通知点击无法跳转指定页面问题求助

解决Flutter后台通知点击无法跳转指定页面的问题

问题核心原因

应用处于关闭状态时,点击后台通知会触发冷启动,此时全局navigatorKey尚未初始化完成,原有的点击回调无法获取到可用的导航上下文;同时冷启动场景下,Awesome Notifications的默认回调机制无法自动触发页面跳转,需要主动处理启动时的初始通知数据。

具体解决方案

1. 冷启动时主动获取初始通知数据

在应用启动阶段(main函数),检查是否存在因点击通知触发启动的情况,直接根据通知数据跳转目标页面。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化Awesome Notifications通道配置
  await AwesomeNotifications().initialize(
    'resource://drawable/ic_stat_onesignal_default',
    [
      NotificationChannel(
        channelKey: 'high_importance_channel',
        channelName: '高优先级通知通道',
        channelDescription: '用于展示重要推送通知',
        importance: NotificationImportance.High,
        defaultColor: Colors.blue,
      )
    ]
  );

  // 获取冷启动时的初始通知点击数据
  ReceivedAction? initialAction = await AwesomeNotifications().getInitialNotificationAction(
    removeFromActionEvents: true
  );

  runApp(MyApp(initialAction: initialAction));
}

class MyApp extends StatelessWidget {
  static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
  final ReceivedAction? initialAction;

  const MyApp({super.key, this.initialAction});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: navigatorKey,
      home: _determineInitialPage(initialAction),
    );
  }

  // 根据初始通知数据决定启动页面
  Widget _determineInitialPage(ReceivedAction? action) {
    if (action != null) {
      if (action.buttonKeyPressed.isEmpty) {
        return const Secondscreen();
      } else {
        return Home(data: action.buttonKeyPressed);
      }
    }
    // 默认加载主页
    return const Home(data: null);
  }
}

2. 修正通知点击回调逻辑

移除无效的BuildContext参数,仅使用全局navigatorKey,并确保回调在后台环境中能正确执行:

@pragma("vm:entry-point")
static Future<void> onActionReceivedMethod(ReceivedAction receivedAction) async {
  // 确保后台环境中Awesome Notifications初始化完成
  await AwesomeNotifications().initialize(
    'resource://drawable/ic_stat_onesignal_default',
    [
      NotificationChannel(
        channelKey: 'high_importance_channel',
        channelName: '高优先级通知通道',
        channelDescription: '用于展示重要推送通知',
        importance: NotificationImportance.High,
      )
    ]
  );

  if (receivedAction.channelKey == 'high_importance_channel') {
    Fluttertoast.showToast(msg: '${receivedAction.channelKey}');
  }

  // 检查导航键是否就绪,避免空指针
  if (MyApp.navigatorKey.currentState != null) {
    if (receivedAction.buttonKeyPressed.isEmpty) {
      print("跳转至预约页面");
      MyApp.navigatorKey.currentState?.pushReplacement(
        MaterialPageRoute(builder: (_) => const Secondscreen())
      );
    } else {
      MyApp.navigatorKey.currentState?.pushReplacement(
        MaterialPageRoute(builder: (_) => Home(data: receivedAction.buttonKeyPressed))
      );
    }
  }
}

3. 完善后台通知创建逻辑

在Firebase后台回调中,将通知数据存入payload字段,确保点击时能完整获取跳转参数:

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  await AwesomeNotifications().createNotification(
    content: NotificationContent(
      id: int.parse(message.data["id"]),
      channelKey: 'high_importance_channel',
      title: message.data["title"],
      body: message.data["body"],
      icon: "resource://drawable/ic_stat_onesignal_default",
      payload: message.data, // 携带所有通知数据到payload
    ),
    actionButtons: [
      NotificationActionButton(
        key: 'MARK_DONE',
        label: '稍后提醒',
        icon: "resource://drawable/ic_stat_onesignal_default",
        enabled: true,
      )
    ],
  );
}

4. 确认AndroidManifest配置有效性

当前配置已满足基础要求,但需确保:

  • android:launchMode="singleTop"保持不变,避免重复创建Activity
  • FLUTTER_NOTIFICATION_CLICK的intent-filter正确配置在MainActivity内
  • Firebase默认通知通道ID与Awesome Notifications的channelKey完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:23:15