flutter消息推送客戶端集成方案詳解
一、背景
公司一個(gè)CRM APP項(xiàng)目是用Flutter寫的,根據(jù)業(yè)務(wù)要求,需要集成消息推送功能。所謂的消息推送就是系統(tǒng)會(huì)根據(jù)某些行為自動(dòng)推送信息,手機(jī)的通知欄會(huì)接收到信息,點(diǎn)擊可以打開app的某個(gè)指定頁面。
二、第三方消息推送——個(gè)推
為了追求效率,我們不打算從底層開始寫,而是挑選了第三方消息推送平臺(tái)——個(gè)推。所以這只是一個(gè)基于個(gè)推平臺(tái)的消息推送集成方案,僅供參考。
1、簡(jiǎn)介
個(gè)推是一個(gè)數(shù)據(jù)智能服務(wù)商,不僅有消息推送服務(wù),還有用戶畫像、數(shù)據(jù)統(tǒng)計(jì)等服務(wù)。目前我們只使用了消息推送服務(wù).
2、注冊(cè)開通
要使用服務(wù),首先需要去個(gè)推官網(wǎng)進(jìn)行賬號(hào)注冊(cè)。
注冊(cè)完后可以新增應(yīng)用/服務(wù),選擇個(gè)推-消息推送。
新建應(yīng)用,填寫android和iOS包名
然后找到應(yīng)用管理,在操作菜單欄中選擇去集成。這里可以下載演示的DEMO進(jìn)行安裝。也可以直接根據(jù)提供的App Key 直接在項(xiàng)目中集成。
3、自定義消息推送——透?jìng)?/h3>
個(gè)推的消息推送分為“通知消息”和“消息透?jìng)?rdquo;。
通知消息:指定通知標(biāo)題和內(nèi)容后,由個(gè)推 SDK 自動(dòng)處理在系統(tǒng)通知欄中展示通知欄消息。
消息透?jìng)鳎杭醋远x消息,消息體格式客戶可以自己定義,如純文本、json 串等。透?jìng)飨€(gè)推只傳遞數(shù)據(jù),不做任何處理,客戶端接收到透?jìng)飨⒑笮枰约喝プ龊罄m(xù)動(dòng)作處理,如通知欄展示、彈框等。
我們選擇了消息透?jìng)鞯姆绞竭M(jìn)行開發(fā)。
三、項(xiàng)目集成
創(chuàng)建好個(gè)推消息推送服務(wù)后,就可以開始在項(xiàng)目中集成了
1、個(gè)推客戶端flutter插件
在flutter項(xiàng)目的pubspec.yaml文件中添加個(gè)推sdk依賴
getuiflut: ^0.2.13 #個(gè)推SDK
2、Android和IOS配置
1)Android
打開android/app/build.gradle 文件修改如下內(nèi)容
android { // ... defaultConfig { manifestPlaceholders = [ //填寫你的個(gè)推應(yīng)用app id GETUI_APPID: "H58mSiMN6L9zpMxmawsoP9", ] } } dependencies: { //個(gè)推SDK implementation 'com.getui:gtsdk:3.2.11.0' //個(gè)推核心組件 implementation 'com.getui:gtc:3.1.10.0' }
2) iOS
啟用notification:xcode主工程配置 > Signing & Capabilities > +Push Noticifations
3、通知欄插件flutter_local_notifications
因?yàn)槭褂玫氖窍⑼競(jìng)?,通知欄的消息需要我們自己處理。這里推薦使用flutter_local_notifications
,如果flutter 3x以上的版本,它同時(shí)支持macOS、linux的系統(tǒng)通知。 在flutter項(xiàng)目的pubspec.yaml文件中添加依賴
flutter_local_notifications: ^9.7.0 #本地推送
android需要在AndroidManifest.xml 添加 INTERNET 權(quán)限
<uses-permission android:name="android.permission.INTERNET" />
4、個(gè)推消息與通知欄整合
在flutter的main.dart加載個(gè)推的主入口
void main() { // 個(gè)推管理初始化 GetuiflutManage(); // ... }
創(chuàng)建getuiflut_manage.dart文件
import 'dart:io'; import 'package:crm_flutter/common/logger.dart'; import 'package:crm_flutter/common/notifications/getuiflut_handle.dart'; import 'package:getuiflut/getuiflut.dart'; /// 密鑰 const appId = 'aaaaaabbbbbccccccdddddd'; const appKey = 'aaaaaabbbbbccccccdddddd'; const appSecret = 'aaaaaabbbbbccccccdddddd'; /// 個(gè)推管理 class GetuiflutManage { static final GetuiflutManage _internal = GetuiflutManage._(); factory GetuiflutManage() => _internal; GetuiflutManage._() { _initPlatform(); } /// 客戶端id String? get clientId => _clientId; String? _clientId; /// 初始化個(gè)推sdk Future<void> _initGetuiSdk() async { if (Platform.isIOS) { Getuiflut().startSdk( appId: appId, appKey: appKey, appSecret: appSecret, ); } if (Platform.isAndroid) { try { Getuiflut.initGetuiSdk; } catch (e) { e.toString(); } } getClientId(); } /// 初始化 Future<void> _initPlatform() async { _initGetuiSdk(); /// 監(jiān)聽本地推送通知內(nèi)容點(diǎn)擊 ln.selectNotification.listen((value) { GetuiflutHandle.handleNavigate(value); }); /// 個(gè)推事件處理 Getuiflut().addEventHandler( onReceiveClientId: (String cid) async { logger.debugPrint('cid: ${cid}'); _clientId = cid; }, onReceiveMessageData: (Map<String, dynamic> msg) async { logger.debugPrint("fonReceiveMessageData: $msg"); GetuiflutHandle.push(msg['payload']); }, onReceivePayload: (Map<String, dynamic> message) async { logger.debugPrint("flutter onReceivePayload: $message"); /// 離線則不再次發(fā)送 if (message['offLine']) return; GetuiflutHandle.push(message['payloadMsg']); }, onReceiveNotificationResponse: (Map<String, dynamic> message) async { GetuiflutHandle.handleNavigate(message['payload']); }, ); } Future<void> getClientId() async { try { _clientId = await Getuiflut.getClientId; logger.debugPrint('cid: ${_clientId}'); } catch (e) { logger.debugPrint(e.toString()); } } }
創(chuàng)建getuiflut_handle.dart個(gè)推處理工具函數(shù)。
import 'dart:convert'; import 'package:crm_flutter/common/global.dart'; import 'package:crm_flutter/common/logger.dart'; import 'package:crm_flutter/common/notifications/clientid_bind.dart'; import 'package:crm_flutter/common/notifications/local_notifications.dart'; import 'package:crm_flutter/common/notifications/router_map.dart'; import 'package:crm_flutter/common/login/user_data_helper.dart'; import 'package:crm_flutter/psmb/model/push_payload_model.dart'; import 'package:crm_flutter/routes/routes.dart'; import 'package:flutter/material.dart'; /// 本地通知 final LocalNotifications ln = LocalNotifications(); /// 個(gè)推處理工具 class GetuiflutHandle { /// 獲取實(shí)例 static PushPayloadModel payloadInstance(String value) { Map<String, dynamic> payloadMap = json.decode(value); return PushPayloadModel.fromJson(payloadMap); } /// 通知欄推送 static void push(String value) { PushPayloadModel payload = GetuiflutHandle.payloadInstance(value); /// 進(jìn)行本地消息推送 ln.send( title: payload.aps?.alert?.title ?? '', body: payload.aps?.alert?.body ?? '', payload: value, ); } // ... }
創(chuàng)建local_notifications.dart 文件
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:rxdart/subjects.dart'; /// 本地通知 class LocalNotifications { static final FlutterLocalNotificationsPlugin np = FlutterLocalNotificationsPlugin(); static final LocalNotifications _internal = LocalNotifications._(); factory LocalNotifications() => _internal; final BehaviorSubject<String?> selectNotification = BehaviorSubject<String?>(); LocalNotifications._() { /// 安卓應(yīng)用通知顯示的圖標(biāo),注意android/app/src/main/res/drawable目錄 /// 添加對(duì)應(yīng)的app_icon.png圖標(biāo)文件 var android = const AndroidInitializationSettings('app_icon'); var ios = const IOSInitializationSettings(); np.initialize(InitializationSettings(android: android, iOS: ios), onSelectNotification: (String? payload) async { selectNotification.add(payload); }); } /// push消息 void send({ required String title, required String body, String? payload, String channelId = '1', String channelName = 'crm_psmb', }) { var androidDetails = AndroidNotificationDetails(channelId, channelName, importance: Importance.max, priority: Priority.high); var iosDetails = const IOSNotificationDetails(); var details = NotificationDetails(android: androidDetails, iOS: iosDetails); np.show( DateTime.now().millisecondsSinceEpoch >> 10, title, body, details, payload: payload, ); } }
最后
以上就是flutter消息推送客戶端集成方案。只要過程順利你現(xiàn)在已經(jīng)可以利用個(gè)推平臺(tái)進(jìn)行透?jìng)飨⑼扑土?。但這只是開始,我們?nèi)杂泻芏鄦栴}并未解決:
1、通知欄收到消息,點(diǎn)擊跳轉(zhuǎn)到目標(biāo)app頁面要如何處理?
2、安卓機(jī)子app離線了收不到消息怎么辦?
3、服務(wù)端如何集成個(gè)推?服務(wù)端如何精準(zhǔn)推送到目標(biāo)用戶?
以上就是flutter消息推送客戶端集成方案詳解的詳細(xì)內(nèi)容,更多關(guān)于flutter消息推送客戶端集成的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android獲取手機(jī)系統(tǒng)版本等信息的方法
這篇文章主要介紹了Android獲取手機(jī)系統(tǒng)版本等信息的方法,涉及Android獲取手機(jī)版本中各種常見信息的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04Android LinearLayout實(shí)現(xiàn)自動(dòng)換行效果
這篇文章主要為大家詳細(xì)介紹了Android LinearLayout實(shí)現(xiàn)自動(dòng)換行效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08ActivityManagerService廣播注冊(cè)與發(fā)送示例解析
這篇文章主要為大家介紹了ActivityManagerService廣播注冊(cè)與發(fā)送示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Android仿拉手網(wǎng)團(tuán)購(gòu)App我的收藏界面實(shí)例代碼
這篇文章主要介紹了Android仿拉手團(tuán)購(gòu)網(wǎng)App我的收藏界面實(shí)例代碼,需要的朋友可以參考下2017-05-05Android實(shí)現(xiàn)掃一掃識(shí)別數(shù)字功能
這篇文章主要介紹了Android實(shí)現(xiàn)掃一掃識(shí)別數(shù)字功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-09-09