Hibok
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

441 linhas
14 KiB

  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'dart:math';
  4. import 'package:chat/data/UserData.dart';
  5. import 'package:chat/generated/i18n.dart';
  6. import 'package:chat/home/InfoList.dart';
  7. import 'package:chat/home/ProgramDetail.dart';
  8. import 'package:chat/models/received_notification.dart';
  9. import 'package:flutter/cupertino.dart';
  10. import 'package:flutter/material.dart';
  11. import 'package:flutter_app_badger/flutter_app_badger.dart';
  12. import 'package:flutter_local_notifications/flutter_local_notifications.dart';
  13. import 'package:jpush_flutter/jpush_flutter.dart';
  14. import 'package:rxdart/rxdart.dart';
  15. import 'MessageMgr.dart';
  16. class LocalNotificationUtil {
  17. static bool isBackground = false;
  18. ///是否在后台
  19. static int badgerCount = 0;
  20. ///角标计数
  21. BuildContext mContext;
  22. factory LocalNotificationUtil() => _getInstance();
  23. static LocalNotificationUtil get instance => _getInstance();
  24. static LocalNotificationUtil _instance;
  25. static const String PAYLOAD_DATE = 'date';
  26. static const String PAYLOAD_FRIENDS = 'friends';
  27. /// date+@+节目id
  28. static const String PAYLOAD_OTHER = 'other';
  29. /// 其他
  30. LocalNotificationUtil._internal() {
  31. // 初始化
  32. }
  33. static LocalNotificationUtil _getInstance() {
  34. if (_instance == null) {
  35. _instance = new LocalNotificationUtil._internal();
  36. }
  37. return _instance;
  38. }
  39. FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
  40. FlutterLocalNotificationsPlugin();
  41. // Streams are created so that app can respond to notification-related events since the plugin is initialised in the `main` function
  42. BehaviorSubject<ReceivedNotification> didReceiveLocalNotificationSubject =
  43. BehaviorSubject<ReceivedNotification>();
  44. BehaviorSubject<String> selectNotificationSubject = BehaviorSubject<String>();
  45. void initJPush() {
  46. JPush jpush = new JPush();
  47. ///ios一定要加这句
  48. jpush.applyPushAuthority(
  49. new NotificationSettingsIOS(sound: true, alert: true, badge: true));
  50. jpush.addEventHandler(
  51. // 接收通知回调方法。
  52. onReceiveNotification: (Map<String, dynamic> message) async {
  53. print("flutter onReceiveNotification: $message");
  54. },
  55. // 点击通知回调方法。
  56. onOpenNotification: (Map<String, dynamic> message) async {
  57. print("flutter onOpenNotification: $message");
  58. print("flutter onOpenNotification extras: ${message['extras']}");
  59. // 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}
  60. Map jExtra = message['extras'];
  61. print('onOpenNotification jExtra:$jExtra');
  62. if (jExtra.containsKey('cn.jpush.android.EXTRA')) {
  63. ///android
  64. Map map = json.decode(jExtra['cn.jpush.android.EXTRA']);
  65. print('map: $map');
  66. String payload = getPayload(map);
  67. print('onOpenNotification payload:$payload');
  68. goPage(payload);
  69. return;
  70. } else {
  71. ///ios
  72. print("flutter jExtra : $jExtra");
  73. String payload = getPayload(jExtra);
  74. print('onOpenNotification payload:$payload');
  75. goPage(payload);
  76. }
  77. },
  78. // 接收自定义消息回调方法。
  79. onReceiveMessage: (Map<String, dynamic> message) async {
  80. print("flutter自定义 onReceiveMessage: $message");
  81. },
  82. );
  83. jpush.setup(
  84. appKey: "13dd603952a6632d1dd3ac54",
  85. channel: "theChannel",
  86. production: false,
  87. debug: true, // 设置是否打印 debug 日志
  88. );
  89. jpush.getRegistrationID().then((rid) {
  90. print('jpush getRegistrationID $rid ');
  91. });
  92. }
  93. void setAlias() {
  94. JPush jpush = new JPush();
  95. print('flutter jpush setAlias ${UserData().basicInfo.userId.toString()}');
  96. jpush.setAlias(UserData().basicInfo.userId.toString()).then((map) {});
  97. jpush.addTags(
  98. ["yueliao", 'yueliao_' + UserData().language.toString()],
  99. ).then((map) {});
  100. if (Platform.isIOS) {
  101. jpush.getLaunchAppNotification().then((map) {
  102. print('getLaunchAppNotification $map');
  103. Map jExtra = map['extras'];
  104. String payload = getPayload(jExtra);
  105. print('onOpenNotification payload:$payload');
  106. goPage(payload);
  107. FlutterAppBadger.removeBadge();
  108. }).catchError((error) {
  109. print('getLaunchAppNotificationerror $error');
  110. });
  111. }
  112. }
  113. void removeAlias() {
  114. JPush jpush = new JPush();
  115. jpush.deleteAlias();
  116. jpush.stopPush();
  117. }
  118. void initState(BuildContext context) {
  119. this.mContext = context;
  120. if (hasInit) {
  121. return;
  122. }
  123. hasInit = true;
  124. didReceiveLocalNotificationSubject.stream
  125. .listen((ReceivedNotification receivedNotification) async {
  126. print('ios低版本推送点击:${receivedNotification.payload}');
  127. await showDialog(
  128. context: mContext,
  129. builder: (BuildContext context) => CupertinoAlertDialog(
  130. title: receivedNotification.title != null
  131. ? Text(receivedNotification.title)
  132. : null,
  133. content: receivedNotification.body != null
  134. ? Text(receivedNotification.body)
  135. : null,
  136. actions: [
  137. CupertinoDialogAction(
  138. isDefaultAction: false,
  139. child: Text(I18n.of(mContext).cancel),
  140. onPressed: () async {
  141. Navigator.of(mContext, rootNavigator: true).pop();
  142. },
  143. ),
  144. CupertinoDialogAction(
  145. isDefaultAction: true,
  146. child: Text(I18n.of(mContext).determine),
  147. onPressed: () async {
  148. Navigator.of(mContext, rootNavigator: true).pop();
  149. goPage(receivedNotification.payload);
  150. },
  151. ),
  152. ],
  153. ),
  154. );
  155. });
  156. print('点击事件----selectNotificationSubject --');
  157. selectNotificationSubject.stream.listen((String payload) async {
  158. print('这里---推送点击');
  159. goPage(payload);
  160. });
  161. setAlias();
  162. }
  163. static bool hasInit = false;
  164. void initLocalPush() async {
  165. // needed if you intend to initialize in the `main` function
  166. WidgetsFlutterBinding.ensureInitialized();
  167. // 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
  168. // change the default route of the app
  169. // var notificationAppLaunchDetails =
  170. // await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
  171. var initializationSettingsAndroid =
  172. AndroidInitializationSettings('ic_launcher_1');
  173. ///android推送图标在drawable文件夹
  174. var initializationSettingsIOS = IOSInitializationSettings(
  175. onDidReceiveLocalNotification:
  176. (int id, String title, String body, String payload) async {
  177. print('onDidReceiveLocalNotification $payload');
  178. didReceiveLocalNotificationSubject.add(ReceivedNotification(
  179. id: id, title: title, body: body, payload: payload));
  180. });
  181. var initializationSettings = InitializationSettings(
  182. initializationSettingsAndroid, initializationSettingsIOS);
  183. print('点击事件初始化');
  184. bool isOK =await flutterLocalNotificationsPlugin.initialize(initializationSettings,
  185. onSelectNotification: (String payload) async {
  186. print('AAA这里---推送点击');
  187. selectNotificationSubject.add(payload);
  188. });
  189. print('点击事件初始化----$isOK');
  190. }
  191. String getPayload(Map notifition) {
  192. String payload = 'default';
  193. int type = int.parse(notifition['Type'].toString());
  194. print('onOpenNotification type:$type');
  195. switch (type) {
  196. case 1:
  197. payload = PAYLOAD_DATE + '@' + notifition['Id'].toString();
  198. break;
  199. case 2:
  200. payload = PAYLOAD_OTHER + '@' + InfoType.Apply.toString();
  201. break;
  202. case 3:
  203. payload = PAYLOAD_OTHER + '@' + InfoType.Apply.toString();
  204. break;
  205. case 4:
  206. payload = PAYLOAD_OTHER + '@' + InfoType.Money.toString();
  207. break;
  208. case 5:
  209. payload = PAYLOAD_OTHER + '@' + InfoType.System.toString();
  210. break;
  211. case 6:
  212. payload = PAYLOAD_FRIENDS + '@' + InfoType.Apply.toString();
  213. break;
  214. case 7:
  215. payload = PAYLOAD_OTHER + '@' + InfoType.System.toString();
  216. break;
  217. default:
  218. payload = 'default';
  219. break;
  220. }
  221. return payload;
  222. }
  223. void goPage(String payload) {
  224. print('goPage payload: $payload');
  225. print('### 开始跳转');
  226. if (payload != null) {
  227. if (payload == 'default') {
  228. return;
  229. }
  230. if (payload.startsWith(PAYLOAD_DATE)) {
  231. Navigator.of(mContext).push(
  232. MaterialPageRoute(
  233. builder: (mContext) {
  234. return ProgramDetailPage(
  235. programId: int.parse(payload.split('@')[1]),
  236. );
  237. },
  238. ),
  239. );
  240. } else if (payload.startsWith(PAYLOAD_FRIENDS)) {
  241. MessageMgr().emit('goto_new_friends');
  242. } else {
  243. int type = int.parse(payload.split('@')[1]);
  244. String title = '';
  245. switch (type) {
  246. case InfoType.Apply:
  247. title = I18n.of(mContext).application_notice;
  248. break;
  249. case InfoType.Money:
  250. title = I18n.of(mContext).wallet_reminder;
  251. break;
  252. case InfoType.System:
  253. title = I18n.of(mContext).appName;
  254. break;
  255. }
  256. Navigator.of(mContext).push(
  257. new MaterialPageRoute(
  258. builder: (context) {
  259. return InfoListPage(
  260. title: title,
  261. type: type,
  262. );
  263. },
  264. ),
  265. );
  266. }
  267. print('notification payload: ' + payload);
  268. }
  269. }
  270. Future<void> show(String title, String content,{int id}) async {
  271. if (!isBackground || !UserData().privatyMsgPushSwitch) {
  272. print('程序在前台,不发生推送通知 || 用户关闭推送');
  273. return;
  274. }
  275. showNotification(title, content,id: id);
  276. }
  277. Future<void> showOtherNotification(
  278. Map notifition, String defaultTitle, String defaultContent) async {
  279. int type = notifition['Type'];
  280. String payload = 'default';
  281. bool needPush = true;
  282. switch (type) {
  283. case 1:
  284. needPush = UserData().newDateSwitch;
  285. payload = PAYLOAD_DATE + '@' + notifition['Id'].toString();
  286. break;
  287. case 2:
  288. needPush = UserData().applyCheckSwitch;
  289. payload = PAYLOAD_OTHER + '@' + InfoType.Apply.toString();
  290. break;
  291. case 3:
  292. needPush = UserData().acceptCheckSwitch;
  293. payload = PAYLOAD_OTHER + '@' + InfoType.Apply.toString();
  294. break;
  295. case 4:
  296. needPush = UserData().checkPhotoSwitch;
  297. payload = PAYLOAD_OTHER + '@' + InfoType.Money.toString();
  298. break;
  299. case 5:
  300. needPush = UserData().codeSucessSwitch;
  301. payload = PAYLOAD_OTHER + '@' + InfoType.System.toString();
  302. break;
  303. case 6:
  304. // needPush = UserData().codeSucessSwitch;
  305. payload = PAYLOAD_FRIENDS + '@' + InfoType.Apply.toString();
  306. break;
  307. case 7:
  308. payload = PAYLOAD_OTHER + '@' + InfoType.System.toString();
  309. break;
  310. default:
  311. payload = 'default';
  312. break;
  313. }
  314. print('showOtherNotification payload $payload');
  315. if(selectNotificationSubject==null){
  316. print('selectNotificationSubject == null');
  317. }else{
  318. print('selectNotificationSubject 不空');
  319. }
  320. if(flutterLocalNotificationsPlugin==null){
  321. print('flutterLocalNotificationsPlugin == null');
  322. }else{
  323. print('flutterLocalNotificationsPlugin 不空');
  324. }
  325. if (needPush) {
  326. showNotification(defaultTitle, defaultContent, payload: payload);
  327. }
  328. }
  329. void showNotification(String title, String content,
  330. {payload = 'default',int id}) async {
  331. if(id == null){
  332. id = Random().nextInt(1000);
  333. }
  334. var androidPlatformChannelSpecifics = AndroidNotificationDetails(
  335. '668123', 'com.cyhd.henhoandroid.push', 'private message push',
  336. importance: Importance.Max, priority: Priority.High, ticker: title);
  337. var iOSPlatformChannelSpecifics = IOSNotificationDetails();
  338. var platformChannelSpecifics = NotificationDetails(
  339. androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
  340. print('payload- $payload');
  341. await flutterLocalNotificationsPlugin.show(
  342. id, title, content, platformChannelSpecifics,
  343. payload: payload);
  344. badgerCount++;
  345. FlutterAppBadger.updateBadgeCount(badgerCount);
  346. ///等极光修复了iOS本地推送点击事件后改为下面的方法
  347. // var fireDate = DateTime.fromMillisecondsSinceEpoch(
  348. // DateTime.now().millisecondsSinceEpoch + 3000);
  349. // var localNotification = LocalNotification(
  350. // id: 234,
  351. // title: 'fadsfa',
  352. // buildId: 1,
  353. // content: 'fdas',
  354. // fireTime: fireDate,
  355. // subtitle: 'fasf',
  356. // badge: 5,
  357. // extra: {"fa": "0"});
  358. // JPush jpush = new JPush();
  359. // jpush.sendLocalNotification(localNotification);
  360. }
  361. Future<void> cleanAllNotifications() async {
  362. await flutterLocalNotificationsPlugin.cancelAll();
  363. FlutterAppBadger.removeBadge();
  364. JPush jpush = new JPush();
  365. if (Platform.isIOS) {
  366. jpush.setBadge(0);
  367. }
  368. badgerCount = 0;
  369. FlutterAppBadger.updateBadgeCount(badgerCount);
  370. }
  371. void startPush(){
  372. JPush jpush = new JPush();
  373. jpush.resumePush();
  374. }
  375. void pausePush(){
  376. JPush jpush = new JPush();
  377. jpush.stopPush();
  378. }
  379. void dispose() {
  380. // if(didReceiveLocalNotificationSubject !=null && selectNotificationSubject !=null){
  381. // didReceiveLocalNotificationSubject.close();
  382. // selectNotificationSubject.close();
  383. // }
  384. }
  385. }