Android 14升级后Flutter不可移除通知(仿Flipkart)实现求助
Android 14 下 Flutter 实现不可滑动移除、带手动关闭按钮的通知(仿 Flipkart)
核心原理
Android 14 强制要求普通通知允许用户滑动移除,仅前台服务通知可保持不可滑动的持久状态。我们通过启动前台服务+自定义通知布局添加关闭按钮的方式实现需求。
1. 配置 AndroidManifest.xml
添加必要权限并注册前台服务:
<!-- 基础通知权限 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- 前台服务权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- Android 14+ 需指定通知类型的前台服务权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_NOTIFICATION" /> <!-- 注册前台服务 --> <service android:name="com.dexterous.flutterlocalnotifications.ForegroundService" android:foregroundServiceType="notification" />
2. 添加自定义通知布局(Android 端)
在 android/app/src/main/res/layout 下创建 notification_custom_layout.xml,定义带关闭按钮的通知样式:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="16dp"> <ImageView android:id="@+id/notification_icon" android:layout_width="48dp" android:layout_height="48dp" android:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" android:paddingLeft="16dp"> <TextView android:id="@+id/notification_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp" android:textStyle="bold" /> <TextView android:id="@+id/notification_body" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="14sp" android:textColor="@android:color/darker_gray" /> </LinearLayout> <Button android:id="@+id/close_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="关闭" android:background="@android:color/transparent" android:textColor="@android:color/holo_red_light" /> </LinearLayout>
3. Flutter 端实现逻辑
使用 flutter_local_notifications 插件完成通知初始化、显示及关闭处理:
初始化通知插件
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin(); Future<void> initNotifications() async { const AndroidInitializationSettings androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initSettings = InitializationSettings(android: androidInit); await _notificationsPlugin.initialize(initSettings, onDidReceiveNotificationResponse: (NotificationResponse response) { // 处理关闭按钮点击事件 if (response.payload == 'close_notif') { _notificationsPlugin.cancel(0); // 取消指定ID的通知 _stopForegroundService(); // 停止前台服务 } }); } // 停止前台服务 Future<void> _stopForegroundService() async { await _notificationsPlugin.stopForegroundService(); }
显示持久化通知
Future<void> showPersistentNotification() async { const AndroidNotificationDetails androidDetails = AndroidNotificationDetails( 'persistent_channel_id', '持久通知频道', channelDescription: '用于显示不可滑动移除的通知', importance: Importance.max, priority: Priority.high, ongoing: true, // 标记为持续通知 autoCancel: false, enableVibration: false, onlyAlertOnce: true, // 绑定自定义布局 customContentView: RemoteViews( 'com.your.app.package', // 替换为你的应用包名 'layout.notification_custom_layout', ), // 添加关闭按钮动作 actions: [ AndroidNotificationAction( 'close_action', '关闭', payload: 'close_notif', ), ], ); const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails); // 启动前台服务并显示通知 await _notificationsPlugin.startForegroundService( androidDetails, notificationDetails, ); }
关键注意事项
- Android 14 下,非前台服务的通知无法禁止滑动移除,必须使用前台服务实现需求。
- 自定义布局中的包名必须与应用实际包名一致,否则布局无法加载。
- 测试时需确保已授予
POST_NOTIFICATIONS权限,Android 13+ 需动态申请该权限。
内容的提问来源于stack exchange,提问作者codrikaz
相关产品推荐
相关产品推荐

