flutter消息推送客戶端集成方案詳解
一、背景
公司一個CRM APP項目是用Flutter寫的,根據業務要求,需要集成消息推送功能。所謂的消息推送就是系統會根據某些行為自動推送信息,手機的通知欄會接收到信息,點擊可以打開app的某個指定頁面。
二、第三方消息推送——個推
為瞭追求效率,我們不打算從底層開始寫,而是挑選瞭第三方消息推送平臺——個推。所以這隻是一個基於個推平臺的消息推送集成方案,僅供參考。
1、簡介
個推是一個數據智能服務商,不僅有消息推送服務,還有用戶畫像、數據統計等服務。目前我們隻使用瞭消息推送服務.
2、註冊開通
要使用服務,首先需要去個推官網進行賬號註冊。
註冊完後可以新增應用/服務,選擇個推-消息推送。
新建應用,填寫android和iOS包名
然後找到應用管理,在操作菜單欄中選擇去集成。這裡可以下載演示的DEMO進行安裝。也可以直接根據提供的App Key 直接在項目中集成。
3、自定義消息推送——透傳
個推的消息推送分為“通知消息”和“消息透傳”。
通知消息:指定通知標題和內容後,由個推 SDK 自動處理在系統通知欄中展示通知欄消息。
消息透傳:即自定義消息,消息體格式客戶可以自己定義,如純文本、json 串等。透傳消息個推隻傳遞數據,不做任何處理,客戶端接收到透傳消息後需要自己去做後續動作處理,如通知欄展示、彈框等。
我們選擇瞭消息透傳的方式進行開發。
三、項目集成
創建好個推消息推送服務後,就可以開始在項目中集成瞭
1、個推客戶端flutter插件
在flutter項目的pubspec.yaml文件中添加個推sdk依賴
getuiflut: ^0.2.13 #個推SDK
2、Android和IOS配置
1)Android
打開android/app/build.gradle 文件修改如下內容
android { // ... defaultConfig { manifestPlaceholders = [ //填寫你的個推應用app id GETUI_APPID: "H58mSiMN6L9zpMxmawsoP9", ] } } dependencies: { //個推SDK implementation 'com.getui:gtsdk:3.2.11.0' //個推核心組件 implementation 'com.getui:gtc:3.1.10.0' }
2) iOS
啟用notification:xcode主工程配置 > Signing & Capabilities > +Push Noticifations
3、通知欄插件flutter_local_notifications
因為使用的是消息透傳,通知欄的消息需要我們自己處理。這裡推薦使用flutter_local_notifications
,如果flutter 3x以上的版本,它同時支持macOS、linux的系統通知。 在flutter項目的pubspec.yaml文件中添加依賴
flutter_local_notifications: ^9.7.0 #本地推送
android需要在AndroidManifest.xml 添加 INTERNET 權限
<uses-permission android:name="android.permission.INTERNET" />
4、個推消息與通知欄整合
在flutter的main.dart加載個推的主入口
void main() { // 個推管理初始化 GetuiflutManage(); // ... }
創建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'; /// 個推管理 class GetuiflutManage { static final GetuiflutManage _internal = GetuiflutManage._(); factory GetuiflutManage() => _internal; GetuiflutManage._() { _initPlatform(); } /// 客戶端id String? get clientId => _clientId; String? _clientId; /// 初始化個推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(); /// 監聽本地推送通知內容點擊 ln.selectNotification.listen((value) { GetuiflutHandle.handleNavigate(value); }); /// 個推事件處理 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"); /// 離線則不再次發送 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()); } } }
創建getuiflut_handle.dart個推處理工具函數。
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(); /// 個推處理工具 class GetuiflutHandle { /// 獲取實例 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); /// 進行本地消息推送 ln.send( title: payload.aps?.alert?.title ?? '', body: payload.aps?.alert?.body ?? '', payload: value, ); } // ... }
創建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._() { /// 安卓應用通知顯示的圖標,註意android/app/src/main/res/drawable目錄 /// 添加對應的app_icon.png圖標文件 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消息推送客戶端集成方案。隻要過程順利你現在已經可以利用個推平臺進行透傳消息推送瞭。但這隻是開始,我們仍有很多問題並未解決:
1、通知欄收到消息,點擊跳轉到目標app頁面要如何處理?
2、安卓機子app離線瞭收不到消息怎麼辦?
3、服務端如何集成個推?服務端如何精準推送到目標用戶?
以上就是flutter消息推送客戶端集成方案詳解的詳細內容,更多關於flutter消息推送客戶端集成的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- 大型項目裡Flutter測試應用實例集成測試深度使用詳解
- Windows下Flutter+Idea環境搭建及配置
- Flutter 創建私有公共插件的步驟
- Flutter 給列表增加下拉刷新和上滑加載更多功能
- Flutter路由fluro引入配置和使用的具體方法