flutter中用workmanager实现android和ios系统的后台通知功能

前言

相比于workmanager,firebase_messaging更成熟,用的更多,不过 workmanager 实现简单一点,适合快速开发的小任务。

workmanager 的使用

先设置好 callbackDispatcher 和 Workmanager().executeTask 来执行任务,在具体位置调用 Workmanager().registerOneOffTask 来触发事件。

流程

通过 Workmanager().initialize() 启动,使用 Workmanager().registerOneOffTask() 或 Workmanager().registerPeriodicTask() 注册任务。

方法

本地推送可使用 workmanager,但可能由于系统限制导致功能不稳定,比如在 ios 系统用 workmanager 就不稳定。firebase_messaging更成熟,用的人多,更稳定。也可以修改平台原生代码,以 ios 为例,修改 flutter 项目中的 swift 文件。

代码示例

// 注册后台任务。这个函数用在触发通知的位置。
void triggerErrorMessage(String dn) {
  if (Platform.isAndroid) {
    if (kDebugMode) {
      print("是安卓系统");
    }
    Workmanager().registerOneOffTask(
      "notification_task",  // taskId
      "notification_task",  // taskName
      inputData: {
        'channelName': '后台通知',    // 通知的渠道名称
        'id': '0',                   // 唯一ID
        'title': '后台通知',          // 通知标题 
        'body': '后台通知的内容',     // 通知内容
      },
    );
  } else if (Platform.isIOS) {
    if (kDebugMode) {
      print("是ios系统");
    }
    Workmanager().registerOneOffTask(
      "notification_task",  // 这里是taskName,与安卓系统的有区别,下面一行的参数意义还不确定
      "notification_task",
      inputData: {
        'channelName': '后台通知',
        'id': '1',
        'title': '后台通知',
        'body': '后台通知的内容',
      },
    );
  }
}

// 在应用启动的 main() 中要初始化插件 workmanager
Workmanager().initialize(
  callbackDispatcher,     // 后台任务回调函数
  isInDebugMode: true,    // 调试模式。为 true 的话会默认创建一个通知渠道(安卓系统)
);
// 执行后台任务。
@pragma('vm:entry-point')
void callbackDispatcher() {
  Workmanager().executeTask((taskName, inputData) async {
    try {
      switch (taskName) {
        case 'notification_task':
          final String title = inputData?['title'];
          final String body = inputData?['body'];
          final String channelName = inputData?['channelName'];
          final String id = inputData?['id'];

          if (Platform.isIOS) {
            await _handleIOSNotification(title, body, id);
          } else if (Platform.isAndroid) {
            await _handleAndroidNotification(title, body, id);
          }
          break;

        default:
          if (kDebugMode) {
            print('未知任务: $taskName');
          }
      }
    } catch (e, s) {
      if (kDebugMode) {
        print('在执行后台任务时发生异常: $e');
        print('堆栈跟踪: $s');
      }
      // 返回 false 表示任务失败
      return Future.value(false);
    }
    return Future.value(true);
  });
}

// IOS 通知处理
Future<void> _handleIOSNotification(
    String title, String body, int id) async {
  try {
    // iOS需要在主isolate中初始化,这里尝试重新初始化
    const DarwinInitializationSettings initializationSettingsIOS =
        DarwinInitializationSettings(
      requestAlertPermission: false,
      requestBadgePermission: false,
      requestSoundPermission: false,
    );

    // 创建插件实例
    final FlutterLocalNotificationsPlugin notificationsPlugin =
        FlutterLocalNotificationsPlugin();

    // iOS 通知详情
    const DarwinNotificationDetails iOSPlatformChannelSpecifics =
        DarwinNotificationDetails(
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
    );

    // 创建通知详情
    const NotificationDetails platformDetails = NotificationDetails(
      iOS: iOSPlatformChannelSpecifics,
    );

    // 显示通知
    await notificationsPlugin.show(
      id, 
      title, 
      body, 
      platformDetails,
      payload: "message"
    );
  } catch (e) {
    if (kDebugMode) {
      print('iOS 通知发送失败: $e');
    }
  }
}

// Android 通知处理
Future<void> _handleAndroidNotification(
    String title, String body, int id) async {
  try {
    // 直接在这个隔离里初始化通知插件
    const AndroidInitializationSettings
        initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/ic_launcher');
    const InitializationSettings initializationSettings =
        InitializationSettings(
            android: initializationSettingsAndroid);

    final FlutterLocalNotificationsPlugin notificationsPlugin =
        FlutterLocalNotificationsPlugin();
    // 初始化通道
    await notificationsPlugin.initialize(initializationSettings);

    // 创建通知详情
    const AndroidNotificationDetails androidDetails =
        AndroidNotificationDetails(
      '后台通知',     // channelId
      '后台通知',     // channelName
      importance: Importance.max,
      priority: Priority.max,
      fullScreenIntent: true,
    );
    const NotificationDetails platformDetails =
        NotificationDetails(android: androidDetails);

    // 使用当前隔离初始化的插件显示通知
    await notificationsPlugin.show(
      id,       
      title,    
      body,     
      platformDetails,
      payload: "message",
    );
  } catch (e) {
    if (kDebugMode) {
      print('iOS 通知发送失败: $e');
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值