import 'dart:convert'; import 'dart:io'; import 'dart:math'; import 'package:chat/data/UserData.dart'; import 'package:chat/generated/i18n.dart'; import 'package:chat/home/InfoList.dart'; import 'package:chat/home/ProgramDetail.dart'; import 'package:chat/home/rich_title.dart'; import 'package:chat/models/received_notification.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_app_badger/flutter_app_badger.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:jpush_flutter/jpush_flutter.dart'; import 'package:rxdart/rxdart.dart'; import 'MessageMgr.dart'; class LocalNotificationUtil { static bool isBackground = false; ///是否在后台 static int badgerCount = 0; ///角标计数 BuildContext mContext; factory LocalNotificationUtil() => _getInstance(); static LocalNotificationUtil get instance => _getInstance(); static LocalNotificationUtil _instance; static const String PAYLOAD_DATE = 'date'; static const String PAYLOAD_FRIENDS = 'friends'; /// date+@+节目id static const String PAYLOAD_OTHER = 'other'; JPush jpush = new JPush(); /// 其他 LocalNotificationUtil._internal() { // 初始化 } static LocalNotificationUtil _getInstance() { if (_instance == null) { _instance = new LocalNotificationUtil._internal(); } return _instance; } FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // Streams are created so that app can respond to notification-related events since the plugin is initialised in the `main` function BehaviorSubject didReceiveLocalNotificationSubject = BehaviorSubject(); BehaviorSubject selectNotificationSubject = BehaviorSubject(); void initJPush() { ///ios一定要加这句 jpush.applyPushAuthority( new NotificationSettingsIOS(sound: true, alert: true, badge: true)); jpush.addEventHandler( // 接收通知回调方法。 onReceiveNotification: (Map message) async { print("flutter onReceiveNotification: $message"); Map jExtra = message['extras']; print('onOpenNotification jExtra:$jExtra'); if (jExtra.containsKey('cn.jpush.android.EXTRA')) { ///android Map map = json.decode(jExtra['cn.jpush.android.EXTRA']); //申请好友推送 if (map['Type'] == 6) { MessageMgr().emit('do_friend_apply'); } return; } else { ///ios //申请好友推送 if (jExtra['Type'] == 6) { MessageMgr().emit('do_friend_apply'); } } }, // 点击通知回调方法。 onOpenNotification: (Map message) async { print("flutter onOpenNotification: $message"); print("flutter onOpenNotification extras: ${message['extras']}"); // flutter onOpenNotification: {aps: {alert: {title: ddd, body: 大幅度发}, badge: 1, sound: default}, payload: other@1, extras: {payload: other@1}, _j_uid: 33833979419, _j_msgid: 29273440739312177, _j_business: 1} Map jExtra = message['extras']; print('onOpenNotification jExtra:$jExtra'); if (jExtra.containsKey('cn.jpush.android.EXTRA')) { ///android Map map = json.decode(jExtra['cn.jpush.android.EXTRA']); print('map: $map'); String payload = getPayload(map); print('onOpenNotification payload:$payload'); goPage(payload); return; } else { ///ios print("flutter jExtra : $jExtra"); String payload = getPayload(jExtra); print('onOpenNotification payload:$payload'); goPage(payload); } }, // 接收自定义消息回调方法。 onReceiveMessage: (Map message) async { print("flutter自定义 onReceiveMessage: $message"); }, ); jpush.setup( appKey: "13dd603952a6632d1dd3ac54", channel: "theChannel", production: true, debug: true, // 设置是否打印 debug 日志 ); jpush.getRegistrationID().then((rid) { print('jpush getRegistrationID $rid '); }); } void setAlias() { print('flutter jpush setAlias ${UserData().basicInfo.userId.toString()}'); try{ jpush.setAlias(UserData().basicInfo.userId.toString()).then((map) {}); jpush.addTags( ["yueliao", 'yueliao_' + UserData().language.toString()], ).then((map) {}); if (Platform.isIOS) { jpush.getLaunchAppNotification().then((map) { print('getLaunchAppNotification $map'); Map jExtra = map['extras']; String payload = getPayload(jExtra); print('onOpenNotification payload:$payload'); goPage(payload); FlutterAppBadger.removeBadge(); }).catchError((error) { print('getLaunchAppNotificationerror $error'); }); } }catch(e){ } } void removeAlias() { JPush jpush = new JPush(); jpush.deleteAlias(); jpush.stopPush(); } void initState(BuildContext context) { this.mContext = context; if (hasInit) { return; } hasInit = true; didReceiveLocalNotificationSubject.stream .listen((ReceivedNotification receivedNotification) async { print('ios低版本推送点击:${receivedNotification.payload}'); await showDialog( context: mContext, builder: (BuildContext context) => CupertinoAlertDialog( title: receivedNotification.title != null ? Text(receivedNotification.title) : null, content: receivedNotification.body != null ? Text(receivedNotification.body) : null, actions: [ CupertinoDialogAction( isDefaultAction: false, child: Text(I18n.of(mContext).cancel), onPressed: () async { Navigator.of(mContext, rootNavigator: true).pop(); }, ), CupertinoDialogAction( isDefaultAction: true, child: Text(I18n.of(mContext).determine), onPressed: () async { Navigator.of(mContext, rootNavigator: true).pop(); goPage(receivedNotification.payload); }, ), ], ), ); }); print('点击事件----selectNotificationSubject --'); selectNotificationSubject.stream.listen((String payload) async { print('这里---推送点击'); goPage(payload); }); setAlias(); } static bool hasInit = false; void initLocalPush() async { // needed if you intend to initialize in the `main` function WidgetsFlutterBinding.ensureInitialized(); // NOTE: if you want to find out if the app was launched via notification then you could use the following call and then do something like // change the default route of the app // var notificationAppLaunchDetails = // await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails(); var initializationSettingsAndroid = AndroidInitializationSettings('ic_launcher_1'); ///android推送图标在drawable文件夹 var initializationSettingsIOS = IOSInitializationSettings( onDidReceiveLocalNotification: (int id, String title, String body, String payload) async { print('onDidReceiveLocalNotification $payload'); didReceiveLocalNotificationSubject.add(ReceivedNotification( id: id, title: title, body: body, payload: payload)); }); var initializationSettings = InitializationSettings( initializationSettingsAndroid, initializationSettingsIOS); print('点击事件初始化'); bool isOK = await flutterLocalNotificationsPlugin.initialize( initializationSettings, onSelectNotification: (String payload) async { print('AAA这里---推送点击'); selectNotificationSubject.add(payload); }); print('点击事件初始化----$isOK'); } String getPayload(Map notifition) { String payload = 'default'; int type = int.parse(notifition['Type'].toString()); print('onOpenNotification type:$type'); switch (type) { case 1: payload = PAYLOAD_DATE + '@' + notifition['Id'].toString(); break; case 2: payload = PAYLOAD_OTHER + '@' + InfoType.Apply.toString(); break; case 3: payload = PAYLOAD_OTHER + '@' + InfoType.Apply.toString(); break; case 4: payload = PAYLOAD_OTHER + '@' + InfoType.Money.toString(); break; case 5: payload = PAYLOAD_OTHER + '@' + InfoType.System.toString(); break; case 6: payload = PAYLOAD_FRIENDS + '@' + InfoType.Apply.toString(); break; case 7: payload = PAYLOAD_OTHER + '@' + InfoType.System.toString(); break; default: payload = 'default'; break; } return payload; } void goPage(String payload) { print('goPage payload: $payload'); print('### 开始跳转'); if (payload != null) { if (payload == 'default') { return; } if (payload.startsWith(PAYLOAD_DATE)) { Navigator.of(mContext).push( MaterialPageRoute( builder: (mContext) { return ProgramDetailPage( programId: int.parse(payload.split('@')[1]), ); }, ), ); } else if (payload.startsWith(PAYLOAD_FRIENDS)) { MessageMgr().emit('goto_new_friends'); } else { int type = int.parse(payload.split('@')[1]); String title = ''; switch (type) { case InfoType.Apply: title = I18n.of(mContext).application_notice; break; case InfoType.Money: title = I18n.of(mContext).wallet_reminder; break; case InfoType.System: title = I18n.of(mContext).appName; break; } Navigator.of(mContext).push( new MaterialPageRoute( builder: (context) { return InfoListPage( title: title, type: type, ); }, ), ); } print('notification payload: ' + payload); } } Future show(String title, String content, {int id}) async { if (!isBackground || !UserData().privatyMsgPushSwitch) { // print('程序在前台,不发生推送通知 || 用户关闭推送'); return; } showNotification(title, content, id: id); } Future showOtherNotification( Map notifition, String defaultTitle, String defaultContent) async { int type = notifition['Type']; String payload = 'default'; bool needPush = true; switch (type) { case 1: needPush = UserData().newDateSwitch; payload = PAYLOAD_DATE + '@' + notifition['Id'].toString(); break; case 2: needPush = UserData().applyCheckSwitch; payload = PAYLOAD_OTHER + '@' + InfoType.Apply.toString(); break; case 3: needPush = UserData().acceptCheckSwitch; payload = PAYLOAD_OTHER + '@' + InfoType.Apply.toString(); break; case 4: needPush = UserData().checkPhotoSwitch; payload = PAYLOAD_OTHER + '@' + InfoType.Money.toString(); break; case 5: needPush = UserData().codeSucessSwitch; payload = PAYLOAD_OTHER + '@' + InfoType.System.toString(); break; case 6: // needPush = UserData().codeSucessSwitch; payload = PAYLOAD_FRIENDS + '@' + InfoType.Apply.toString(); break; case 7: payload = PAYLOAD_OTHER + '@' + InfoType.System.toString(); break; default: payload = 'default'; break; } print('showOtherNotification payload $payload'); if (selectNotificationSubject == null) { print('selectNotificationSubject == null'); } else { print('selectNotificationSubject 不空'); } if (flutterLocalNotificationsPlugin == null) { print('flutterLocalNotificationsPlugin == null'); } else { print('flutterLocalNotificationsPlugin 不空'); } if (needPush) { showNotification(defaultTitle, defaultContent, payload: payload); } } void showNotification(String title, String content, {payload = 'default', int id}) async { if (id == null) { id = Random().nextInt(1000); } var androidPlatformChannelSpecifics = AndroidNotificationDetails( '668123', 'com.cyhd.henhoandroid.push', 'private message push', importance: Importance.Max, priority: Priority.High, ticker: title); var iOSPlatformChannelSpecifics = IOSNotificationDetails(); var platformChannelSpecifics = NotificationDetails( androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics); print('payload- $payload'); await flutterLocalNotificationsPlugin .show(id, title, content, platformChannelSpecifics, payload: payload); badgerCount++; FlutterAppBadger.updateBadgeCount(badgerCount); ///等极光修复了iOS本地推送点击事件后改为下面的方法 // var fireDate = DateTime.fromMillisecondsSinceEpoch( // DateTime.now().millisecondsSinceEpoch + 3000); // var localNotification = LocalNotification( // id: 234, // title: 'fadsfa', // buildId: 1, // content: 'fdas', // fireTime: fireDate, // subtitle: 'fasf', // badge: 5, // extra: {"fa": "0"}); // JPush jpush = new JPush(); // jpush.sendLocalNotification(localNotification); } Future cleanAllNotifications() async { await flutterLocalNotificationsPlugin.cancelAll(); FlutterAppBadger.removeBadge(); JPush jpush = new JPush(); if (Platform.isIOS) { jpush.setBadge(0); } badgerCount = 0; FlutterAppBadger.updateBadgeCount(badgerCount); } void startPush() { JPush jpush = new JPush(); jpush.resumePush(); } void pausePush() { JPush jpush = new JPush(); jpush.stopPush(); } void dispose() { // if(didReceiveLocalNotificationSubject !=null && selectNotificationSubject !=null){ // didReceiveLocalNotificationSubject.close(); // selectNotificationSubject.close(); // } } }