Hibok
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

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