123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import 'dart:convert';
- import 'dart:io';
- import 'package:firebase_messaging/firebase_messaging.dart';
- import 'package:flutter_local_notifications/flutter_local_notifications.dart';
- import 'package:router/componentRouter/component_service_manager.dart';
- import 'package:shared/utils/log_utils.dart';
- // 定义一个回调函数类型
- typedef TokenCallback = void Function(String token);
- class FcmUtils {
- //FCM SDK对象
- final _firebaseMessaging = FirebaseMessaging.instance;
- //Notifications插件对象
- final _localNotifications = FlutterLocalNotificationsPlugin();
- //Android 8+ 的消息通道
- final _androidChannel = const AndroidNotificationChannel(
- 'Normal', //设置 Channel ID
- 'Channel Normal Android', //设置 Channel 名称
- importance: Importance.defaultImportance); //设置该 Channel 的优先级
- // 初始化,获取设备token
- Future<void> initNotifications({
- TokenCallback? onToken, // Token回调函数
- }) async {
- //申请动态通知权限
- await _firebaseMessaging.requestPermission();
- //获取 FCM Token
- final fCMToken = await _firebaseMessaging.getToken();
- if (fCMToken != null) {
- Log.d("FCM -> Token:$fCMToken");
- onToken?.call(fCMToken); // 将初始 Token 通过回调传递
- }
- //刷新 FCM Token 的监听
- _firebaseMessaging.onTokenRefresh.listen((newToken) {
- Log.d("FCM onTokenRefresh -> Token:$newToken");
- onToken?.call(newToken); // 将刷新后的 Token 通过回调传递
- });
- //拿到 FCM Token 之后初始化一些监听
- _initPushNotifications();
- _initLocalNotifications();
- }
- /// Notifications 插件初始化,监听前台消息
- Future _initLocalNotifications() async {
- const iOS = DarwinInitializationSettings();
- // @drawable/ic_launcher是应用的图标,路径是:android/app/src/main/res/mipmap/ic_launcher.png
- const android = AndroidInitializationSettings('@mipmap/ic_launcher');
- // Notifications 插件只需要处理 Android 和 iOS 平台的配置
- const settings = InitializationSettings(android: android, iOS: iOS);
- // Notifications 插件初始化
- await _localNotifications.initialize(settings, onDidReceiveNotificationResponse: (NotificationResponse response) {
- // android 前台消息点击回调
- final message = RemoteMessage.fromMap(jsonDecode(response.payload!));
- Log.d(response);
- // 处理收到消息
- handleMessage(message);
- });
- //Android 8 以上会通过 Channel 创建对应的通知渠道
- final platform = _localNotifications.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>();
- await platform?.createNotificationChannel(_androidChannel);
- }
- /// FCM 初始化接收消息的各种回调
- Future _initPushNotifications() async {
- await _firebaseMessaging.setForegroundNotificationPresentationOptions(alert: true, badge: true, sound: true);
- // 打开app时,会执行该回调,获取消息(通常是程序终止时,点击消息打开app的回调)
- _firebaseMessaging.getInitialMessage().then(
- (RemoteMessage? message) {
- if (message == null) return; // 没有消息不执行后操作
- handleMessage(message);
- },
- );
- // 后台程序运行时,点击消息触发
- FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) => handleMessage(message));
- // 前台消息,android不会弹出通知框,所以需要 Notifications 插件自定义本地通知(iOS没有前台消息,iOS的前台消息和后台运行时一样的效果)
- FirebaseMessaging.onMessage.listen((message) {
- Log.d("前台收到的消息 -> message:${message.data}");
- final notification = message.notification;
- if (notification == null) return;
- if (Platform.isIOS) return;
- _localNotifications.show(
- notification.hashCode,
- notification.title,
- notification.body,
- NotificationDetails(
- android: AndroidNotificationDetails(
- _androidChannel.id,
- _androidChannel.name,
- icon: '@mipmap/ic_launcher',
- )),
- payload: jsonEncode(message.toMap()));
- });
- // 后台处理,后台程序运行时收到消息,不打开app也会执行的回调
- // FirebaseMessaging.onBackgroundMessage(FirebaseApi.handleBackgroundMessage);
- }
- // 处理收到的消息,比如跳转页面或者其他处理
- void handleMessage(RemoteMessage message) {
- final dataJson = message.data;
- Log.d("点击消息的处理 handleMessage -> data:$dataJson");
- // 1、加入unit成功 ApprovedJoinUnitNotification
- // 2、加入unit失败 RejectedJoinUnitNotification
- // 3、online form批准了 ApprovedApplyOnlineFormNotification
- // 4、online form拒绝了 RejectedApplyOnlineFormNotification
- // 5、facility 预定成功了(不需要,因为支付了就是预定成功了)
- // 6、facility 预定失败了(长时间未支付,被系统取消了) FacilityBookingNotPaidCancelNotification
- // 7、每月物业费账单生成了
- // 8、每月停车费账单生成了
- // 9、服务订单长时间未支付 PaidServiceOrderNotPaidCancelNotification
- String? type = dataJson['type'];
- if (type == 'ApprovedApplyOnlineFormNotification' || type == 'RejectedApplyOnlineFormNotification') {
- //去 Form 详情
- ComponentServiceManager().formService.startFormDetailPage(dataJson['estate_online_form_id'], dataJson['id'], dataJson['online_form_type_id']);
- }
- }
- // static Future<void> handleBackgroundMessage(RemoteMessage message) async {
- // print('后台消息');
- // // BotToast.showText(text: '后台消息:${message.toString()}');
- // print('title:${message.notification?.title}');
- // print('body:${message.notification?.body}');
- // print('payload:${message.data}');
- // print('message:${message}');
- // }
- }
|