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

Flutter Local Notification动作按钮点击无响应,如何触发API调用?

解决Flutter Local Notifications + FCM 动作按钮无响应问题

1. 正确配置通知动作按钮

创建通知时,必须为动作按钮指定唯一的actionIdentifier,并设置适配后台操作的参数:

final androidDetails = AndroidNotificationDetails(
  'api_call_channel',
  'API调用通知通道',
  channelDescription: '用于触发API调用的通知通道',
  actions: [
    AndroidNotificationAction(
      'trigger_api_action', // 唯一动作ID,后续用于判断点击事件
      '执行API调用',
      showsUserInterface: false, // 无需打开应用UI
      cancelNotification: true, // 点击后自动取消通知
    ),
  ],
);

final notificationDetails = NotificationDetails(android: androidDetails);
await flutterLocalNotificationsPlugin.show(
  0,
  '待处理任务',
  '点击按钮完成操作',
  notificationDetails,
);

2. 监听动作按钮点击事件

前台/后台活跃状态

初始化LocalNotifications时,通过onDidReceiveNotificationResponse监听点击:

final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

await flutterLocalNotificationsPlugin.initialize(
  InitializationSettings(
    android: AndroidInitializationSettings('@mipmap/ic_launcher'),
    iOS: DarwinInitializationSettings(),
  ),
  onDidReceiveNotificationResponse: (response) async {
    // 匹配动作ID,触发API调用
    if (response.actionId == 'trigger_api_action') {
      await _callTargetApi();
    }
  },
);

应用被杀死状态

在main函数中提前初始化通知插件,并检查启动时的通知响应,同时配置后台回调:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
  await flutterLocalNotificationsPlugin.initialize(
    InitializationSettings(
      android: AndroidInitializationSettings('@mipmap/ic_launcher'),
      iOS: DarwinInitializationSettings(),
    ),
    onDidReceiveNotificationResponse: (response) async {
      if (response.actionId == 'trigger_api_action') {
        await _callTargetApi();
      }
    },
    onDidReceiveBackgroundNotificationResponse: _backgroundNotificationTap,
  );

  // 检查应用是否由动作按钮点击启动
  final initialResponse = await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
  if (initialResponse?.actionId == 'trigger_api_action') {
    await _callTargetApi();
  }

  runApp(MyApp());
}

// Android后台回调必须加此注解,避免打包时被混淆
@pragma('vm:entry-point')
void _backgroundNotificationTap(NotificationResponse response) {
  if (response.actionId == 'trigger_api_action') {
    // 后台隔离环境中执行API调用,确保不依赖UI资源
    _callTargetApiInBackground();
  }
}

3. API调用适配场景

  • 前台/后台活跃:直接使用常规的网络请求方法(如http或dio)即可。
  • 后台隔离环境:避免使用UI相关依赖,确保网络请求代码独立,可通过compute函数处理耗时操作:
Future<void> _callTargetApiInBackground() async {
  await compute(_performApiCall, null);
}

Future<void> _performApiCall(_) async {
  try {
    final response = await http.post(
      Uri.parse('https://your-api-url.com/action'),
      body: {'data': 'notification_action'},
    );
    // 处理API响应
  } catch (e) {
    // 捕获异常
  }
}

4. 平台配置补充

  • Android:在AndroidManifest.xml中确保添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • iOS:在Info.plist中开启远程通知后台模式:
<key>UIBackgroundModes</key>
<array>
  <string>remote-notification</string>
</array>

5. 调试要点

  • 打印response.actionId确认是否捕获到动作点击事件。
  • 分别测试应用前台、后台、被杀死三种状态下的动作按钮响应。
  • 检查通知通道是否正确创建,动作按钮是否显示在通知上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:12:48