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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 12:58:24