網站首頁 編程語言 正文
一、背景
公司一個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、服務端如何集成個推?服務端如何精準推送到目標用戶?
原文鏈接:https://juejin.cn/post/7179544035390914618
相關推薦
- 2022-03-28 用python實現超強的加密軟件_python
- 2022-08-18 Qt常用容器類的使用_C 語言
- 2022-09-29 Go語言select語句用法示例_Golang
- 2022-01-09 出現Got permission denied while trying to connect to
- 2023-03-02 SQLServer?清理日志的實現_MsSql
- 2022-09-30 Python實現圖像增強_python
- 2023-01-12 Kotlin注解實現Parcelable序列化流程詳解_Android
- 2022-08-26 .net任務調度框架FluentScheduler簡介_實用技巧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支