API | 说明 |
构造函数(TimUiKitPushPlugin) | 实例化一个 Push 插件对象,并确定是否使用 Google FCM |
init | 初始化插件,绑定点击通知回调事件及传入厂商渠道信息 |
uploadToken | 自动获取设备 Token 及证书 ID,自动上传至腾讯云 IM 服务端 |
clearToken | 清除服务端上本设备的推送 Token,达到屏蔽通知的效果 |
requireNotificationPermission | 申请推送权限 |
setBadgeNum | |
clearAllNotification | 清除通知栏内,当前应用,所有的通知 |
getDevicePushConfig | 获取当前厂商的推送相关信息,含机型/证书ID/Token |
getDevicePushToken | 获取当前厂商的推送 Token |
getOtherPushType | 获取厂商信息 |
getBuzId | 获取当前厂商对应的腾讯云控制台上注册的证书 ID |
createNotificationChannel | 为 Android 机型创建通知 Channel 渠道,详见 Google 官方文档 |
clearAllNotification | 清除通知栏内,当前应用,所有的通知 |
displayNotification | 在客户端本地,手动创建一条消息通知 |
displayDefaultNotificationForMessage | 在客户端本地,按照默认的规则,自动为一个 V2TimMessage 创建一个消息通知 |
tuikit
)。com.tencent.flutter.tim_ui_kit_push_plugin.pushActivity.OPPOMessageActivity
。tencent_im_push://${替换成您的包名}/message?#Intent;scheme=tencent_im_push;launchFlags=0x4000000;end
keystore.jks
密钥文件,得到该 keystore 的 SHA256 值,填入华为推送平台中。zipalign -v -p 4 构建生成的apk.apk 打包生成的apk_aligned.apkapksigner sign --ks keystore.jks --ks-pass pass:您创建的keystore密码 --out 最终签名 完成的apk.apk 打包生成的apk_aligned.apk
android/app
目录下。角标参数
请填写 Android 应用入口 Activity 类,如我们 DEMO 的 com.tencent.flutter.tuikit
,否则华为通道下发通知的角标设置将不生效。
点击后续动作
请选择打开应用。tencent_im_push://${替换成您的包名}/honorMessage?#Intent;scheme=tencent_im_push;launchFlags=0x4000000;end
版本类型 | 包名 | Google FCM 支持 | 国内厂商原生支持 | 描述 |
中国大陆版 | 否 | 是 | Android 离线推送仅走国内厂商原生通道 | |
国际版 | 是 | 是 | 在配置 Google FCM 相关信息,且当前设备 Google FCM 可用的情况下,优先使用 Google FCM 通道,其次再尝试国内厂商通道 |
// 国内版flutter pub add tencent_chat_push_for_china// 国际版flutter pub add tim_ui_kit_push_plugin
PushAppInfo
类,汇总起来。后续步骤需要传入此对象。static final PushAppInfo appInfo = PushAppInfo(hw_buz_id: , // 华为证书IDmi_app_id: , // 小米APPIDmi_app_key: , // 小米APPKeymi_buz_id: , // 小米证书IDmz_app_id: , // 魅族APPIDmz_app_key: , // 魅族APPKeymz_buz_id: , // 魅族证书IDvivo_buz_id: , // vivo证书IDoppo_app_key: , // OPPO APPKeyoppo_app_secret: , // OPPO APP Secretoppo_buz_id: , // OPPO证书IDoppo_app_id: , // OPPO APPIDgoogle_buz_id: , // Google FCM证书IDapple_buz_id: , // Apple证书IDhonor_buz_id: , // 荣耀证书ID);
android/app/src/main/AndroidManifest.xml
文件,在 application
中新增usesCleartextTraffic
字段。<applicationandroid:usesCleartextTraffic="true" // 增加本行><!-- possibly other elements --></application>
firebase_core
的依赖,使用1.12.0版本。dependencies:firebase_core: 1.12.0
flutter pub get
完成安装。// 安装Firebase CLInpm install -g firebase-toolscurl -sL https://firebase.tools | bashdart pub global activate flutterfire_cli// 生成配置文件flutterfire configure
main()
方法中初始化 FirebaseAPP。WidgetsFlutterBinding.ensureInitialized();await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform,);
android/build.gradle
。buildscript {repositories {google()jcenter()maven {url 'https://developer.huawei.com/repo/'} // 添加华为 maven 仓库地址}dependencies {// 其他classpath配置classpath 'com.huawei.agconnect:agcp:1.3.1.300' // 添加华为推送 gradle 插件依赖}// Set release signing and passwords in the same build configuration filesigningConfigs {release {storeFile file('<keystore_file>')storePassword '<keystore_password>'keyAlias '<key_alias>'keyPassword '<key_password>'}}buildTypes {// debug模式也要使用证书编译,否则华为指纹验证不通过debug {signingConfig signingConfigs.release}release {signingConfig signingConfigs.release}}}
android/build.gradle
文件,在allprojects>repositories下添加华为依赖仓库地址:allprojects {repositories {google()jcenter()maven {url 'https://developer.huawei.com/repo/'} // 添加华为 maven 仓库地址}}
android/app
目录下。android/app/build.gradle
文件,添加以下配置:// app 其他 gradle 插件apply plugin: 'com.huawei.agconnect' // HMS SDK gradle 插件android {// app 配置内容}
android/app/src/main/AndroidManifest.xml
文件,如下添加 uses-permission 。<uses-permission android:name = "com.huawei.android.launcher.permission.CHANGE_BADGE "/>
android/app/build.gradle
文件,如下配置 vivo 的 APPID 和 AppKey。android: {defaultConfig {manifestPlaceholders = [....vivo_APPID: "填入您申请的vivo AppKey"vivo_APPKEY:"填入您申请的vivo AppID",.....]}}
android/app/src/main/AndroidManifest.xml
文件,在 <application>
中,如下添加meta-data。<meta-dataandroid:name="com.vivo.push.api_key"android:value="填入您申请的vivo AppKey" /><meta-dataandroid:name="com.vivo.push.app_id"android:value="填入您申请的vivo AppID" /></application>
android/app/src/main/AndroidManifest.xml
文件,如下添加 uses-permission 。<uses-permission android:name="com.vivo.notification.permission.BADGE_ICON" />
android/app/src/main/AndroidManifest.xml
文件,在 <application></application>
中,如下添加meta-data。<meta-dataandroid:name="com.hihonor.push.app_id"android:value="填入您申请的荣耀 AppID"" /></application>
android/app/build.gradle
文件,添加如下代码。repositories {maven { url 'https://developer.hihonor.com/repo/' } // 新增}
android/app/src/main/AndroidManifest.xml
文件,如下添加 uses-permission 。<uses-permission android:name = "com.hihonor.android.launcher.permission.CHANGE_BADGE" />
android/app/build.gradle
文件,在 defaultConfig
中加入包名。defaultConfig {applicationId "${替换成您的包名}"...}
android/app/src/main/AndroidManifest.xml
文件,配置各厂商权限列表。<!--小米 开始--><permissionandroid:name="${替换成您的包名}.permission.MIPUSH_RECEIVE"android:protectionLevel="signature" /><uses-permission android:name="${替换成您的包名}.permission.MIPUSH_RECEIVE" /><!--小米 结束--><!--OPPO 开始--><uses-permission android:name="com.coloros.mcs.permission.RECIEVE_MCS_MESSAGE" /><uses-permission android:name="com.heytap.mcs.permission.RECIEVE_MCS_MESSAGE" /><!--OPPO 结束--><!--魅族 开始--><!-- 可选,用于兼容 Flyme5 且推送服务是旧版本的情况--><uses-permission android:name="android.permission.READ_PHONE_STATE" /><!-- 兼容 Flyme5 的权限配置--><uses-permission android:name="com.meizu.flyme.push.permission.RECEIVE" /><permission android:name="${替换成您的包名}.push.permission.MESSAGE"android:protectionLevel="signature"/><uses-permission android:name="${替换成您的包名}.push.permission.MESSAGE" /><!-- 兼容 Flyme3 的权限配置--><uses-permission android:name="com.meizu.c2dm.permission.RECEIVE" /><permission android:name="${替换成您的包名}.permission.C2D_MESSAGE" android:protectionLevel="signature"/><uses-permission android:name="${替换成您的包名}.permission.C2D_MESSAGE"/><!--魅族 结束-->
init
方法。该步骤会完成初始化各厂商通道,并申请厂商通知权限。final TimUiKitPushPlugin cPush = TimUiKitPushPlugin(isUseGoogleFCM: bool, // 是否启用Google Firebase Cloud Messaging,默认true启用。中国大陆版无此参数。);await cPush.init(pushClickAction: pushClickAction, // 单击通知后的事件回调,会在STEP6讲解appInfo: PushConfig.appInfo, // 传入STEP1做的appInfo);
createNotificationChannel
方法即可。cPush.createNotificationChannel(channelId: "new_message",channelName: "消息推送",channelDescription: "推送新聊天消息");
requireNotificationPermission
方法即可。cPush.requireNotificationPermission();
final TimUiKitPushPlugin cPush = TimUiKitPushPlugin(isUseGoogleFCM: true, // 中国大陆版无此参数);Future.delayed(const Duration(seconds: 5), () async {final bool isUploadSuccess =await ChannelPush.uploadToken(PushConfig.appInfo);print("Push token upload result: $isUploadSuccess");});
setBadgeNum( int badgeNum )
方法,将最新未读数同步至桌面角标。此处本插件支持配置iOS, XIAOMI(MIUI6 - MIUI 11机型), HUAWEI, HONOR, vivo 及 OPPO 设备角标。/// App@overridevoid didChangeAppLifecycleState(AppLifecycleState state) async {print("--" + state.toString());int? unreadCount = await _getTotalUnreadCount();switch (state) {case AppLifecycleState.inactive:TencentImSDKPlugin.v2TIMManager.getOfflinePushManager().doBackground(unreadCount: unreadCount ?? 0);if(unreadCount != null){cPush.setBadgeNum(unreadCount);}break;case AppLifecycleState.resumed:TencentImSDKPlugin.v2TIMManager.getOfflinePushManager().doForeground();break;case AppLifecycleState.paused:TencentImSDKPlugin.v2TIMManager.getOfflinePushManager().doBackground(unreadCount: unreadCount ?? 0);if(unreadCount != null){cPush.setBadgeNum(unreadCount);}break;}}
OfflinePushInfo offlinePushInfo
字段。OfflinePushInfo({this.title = '', // 推送通知标题。留空字符串时,按照优先级,IM后台自动替换成 sender的昵称 => sender ID。因此,如无特殊需求,该字段建议留空,可达到和微信一致的效果this.desc = '', // 推送第二行小字部分this.disablePush = false,this.ext = '', // 推送内额外信息,对方可于单击通知跳转时拿到。建议传含Conversation信息的JSON,用于收件方跳转至对应Chat。可参见下方TUIKit的实例代码。this.androidOPPOChannelID = '', // OPPO的channel ID});
TIMUIKitChat
组件TIMUIKitChatConfig
中,使用notificationTitle
/notificationOPPOChannelID
/notificationBody
/notificationExt
/notificationIOSSound
定义自定义推送。详情如下:TIMUIKitChat(config: TIMUIKitChatConfig(notificationTitle: "",// 推送通知标题。留空字符串时,按照优先级,IM后台自动替换成sender的昵称 => sender ID。因此,如无特殊需求,该字段建议留空notificationOPPOChannelID: "", // 用于推送消息的OPPO配置Channel IDnotificationBody: (V2TimMessage message, String convID, ConvType convType) {return "您根据给出的参数自定义的第二行通知";},notificationExt: (V2TimMessage message, String convID, ConvType convType) {// 您根据给出的参数自定义的EXT字段:此处建议传conversation id,JSON格式,即如下所示String createJSON(String convID){return "{\\"conversationID\\": \\"$convID\\"}";}String ext = (convType == ConvType.c2c? createJSON("c2c_${message.sender}"): createJSON("group_$convID"));return ext;}))
clearAllNotification()
方法即可。BuildContext? _cachedContext;final TimUiKitPushPlugin cPush = TimUiKitPushPlugin(isUseGoogleFCM: true, // 中国大陆版无此参数);@overridevoid initState() {super.initState();_cachedContext = context;}void handleClickNotification(Map<String, dynamic> msg) async {String ext = msg['ext'] ?? "";Map<String, dynamic> extMsp = jsonDecode(ext);String convId = extMsp["conversationID"] ?? "";// 此处建议判断当前打开的页面是否是将要跳转的Conversation。// 如果是,建议阻止跳转,以避免进入多个相同页面。final targetConversationRes = await TencentImSDKPlugin.v2TIMManager.getConversationManager().getConversation(conversationID: convId);V2TimConversation? targetConversation = targetConversationRes.data;if(targetConversation != null){cPush.clearAllNotification();Navigator.push(_cachedContext ?? context,MaterialPageRoute(builder: (context) => Chat(selectedConversation: targetConversation,),));}}
call
方法第三个参数中,传入offlinePush
对象即可。final user = await sdkInstance.getLoginUser();final myId = user.data;OfflinePushInfo offlinePush = OfflinePushInfo(title: "",desc: "邀请您语音通话",ext: "{\\"conversationID\\": \\"c2c_$myId\\"}",disablePush: false,ignoreIOSBadge: false,androidOPPOChannelID: PushConfig.OPPOChannelID);_calling?.call(widget.selectedConversation.userID!, CallingScenes.Audio, offlinePush);
Push Notification
的 Capability。
flutter pub get
安装好插件后进入 iOS 目录,执行:pod install
安装依赖库。ios/Runner/AppDelegate.swift
文件didFinishLaunchingWithOptions
方法中。可参考我们的 DEMO。
Objective-C:if (@available(iOS 10.0, *)) {[UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;}
if #available(iOS 10.0, *) {UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate}
info.plist
加入如下字段。<key>flutter_apns.disable_firebase_core</key><false/>
init
方法。该步骤会完成初始化各厂商通道,并申请厂商通知权限。该步骤建议在应用启动后就执行调用。final TimUiKitPushPlugin cPush = TimUiKitPushPlugin(isUseGoogleFCM: true, // 中国大陆版无此参数);cPush.init(pushClickAction: pushClickAction, // 单击通知后的事件回调,会在STEP6讲解appInfo: PushConfig.appInfo, // 传入STEP1做的appInfo);
OfflinePushInfo offlinePushInfo
字段。OfflinePushInfo({// ..其他配置this.iOSSound = "", // iOS离线推送声音设置, 当 iOSSound = kIOSOfflinePushNoSound,表示接收时不会播放声音。 当 iOSSound = kIOSOfflinePushDefaultSound,表示接收时播放系统声音。 如果要自定义 iOSSound,需要先把语音文件链接进 Xcode 工程,然后把语音文件名(带后缀)设置给 iOSSound。this.ignoreIOSBadge = false,});
TIMUIKitChat
组件TIMUIKitChatConfig
中,使用notificationTitle
/notificationOPPOChannelID
/notificationBody
/notificationExt
/notificationIOSSound
定义自定义推送。详情如下:TIMUIKitChat(config: TIMUIKitChatConfig(// ..其他配置notificationIOSSound: "", // iOS离线推送声音设置, 当 iOSSound = kIOSOfflinePushNoSound,表示接收时不会播放声音。 当 iOSSound = kIOSOfflinePushDefaultSound,表示接收时播放系统声音。 如果要自定义 iOSSound,需要先把语音文件链接进 Xcode 工程,然后把语音文件名(带后缀)设置给 iOSSound。))
setBadgeNum
方法外,还需要禁用 IM SDK 的自动设置角标功能,避免冲突。代码如下:TencentImSDKPlugin.v2TIMManager.callExperimentalAPI(api: 'disableBadgeNumber',param: true);
{"From_Account": "Admin", // 建议配置成管理员账户"MsgRandom": 3674128,"MsgLifeTime": 120,"MsgBody": [{"MsgType": "TIMTextElem","MsgContent": {"Text": "Push Test"}}],"OfflinePushInfo": {"PushFlag": 0,"Title": "推送信息的标题","Desc": "离线推送内容","Ext": "这是透传的内容,会通过点击回调的方式,使您拿到,您可用于自定义跳转等操作。请使用JSON格式","AndroidInfo": { // Android设备推送配置"Sound": "android.mp3"},"ApnsInfo": { // 苹果iOS设备推送配置"Sound": "apns.mp3","BadgeMode": 1, // 这个字段缺省或者为 0 表示需要计数,为 1 表示本条消息不需要计数,即右上角图标数字不增加"Title":"apns title", // apns title"SubTitle":"apns subtitle", // apns subtitle"Image":"www.image.com" // image url}}}
conversationID
,如果在处理单击回调跳转(可参见 步骤6)时需要其他字段,请自行修改 JS 代码。
npm install axios
npm install js-md5
后node testvivo
。推送结果会显示在 log 最后一行。
sendMessage
的时候设置offlinePushInfo
的desc
字段,推送的时候会默认展示 desc 信息。displayNotification
自定义通知,及 displayDefaultNotificationForMessage
根据消息生成默认通知,您可按需使用。// 国内版flutter pub add tencent_chat_push_for_china// 国际版flutter pub add tim_ui_kit_push_plugin
@mipmap/ic_launcher
存在且为您的应用 Icon。完整路径:android/app/src/main/res/mipmap/ic_launcher.png
mipmap
目录右键,New
=> Image Asset
)。
ios/Runner/AppDelegate.swift
或 ios/Runner/AppDelegate.m
文件中, didFinishLaunchingWithOptions
函数内,添加如下代码。可参考我们的 DEMO。if (@available(iOS 10.0, *)) {[UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;}
if #available(iOS 10.0, *) {UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate}
cPush
插件类,供后续调用。final TimUiKitPushPlugin cPush = TimUiKitPushPlugin(isUseGoogleFCM: true, // 中国大陆版无此参数);cPush.init(// 此处绑定点击通知的跳转函数,下文会介绍pushClickAction: onClickNotification,);
V2TimAdvancedMsgListener
V2TimAdvancedMsgListener
,可忽略本部分;若无,请在 IM login 后,挂载监听。final advancedMsgListener = V2TimAdvancedMsgListener(onRecvNewMessage: (V2TimMessage newMsg) {// 这里完成监听回调触发事件// 请在这里调用下一步提及的触发本地消息通知API},});TencentImSDKPlugin.v2TIMManager.getMessageManager().addAdvancedMsgListener(listener: advancedMsgListener);
displayNotification
自定义通知,及 displayDefaultNotificationForMessage
根据消息生成默认通知,选一个合适的API。channelID
及 channelName
。若还未创建 Android Push Channel ,请使用插件 createNotificationChannel
API创建。cPush.createNotificationChannel(channelId: "new_message",channelName: "消息推送",channelDescription: "推送新聊天消息");
displayNotification
title
, body
, 及 ext
用于点击跳转信息,三个参数。您可以根据需要自行解析收到的 V2TimMessage
,生成这三个字段。displayDefaultNotificationForMessage
的代码。cPush.displayNotification(channelID: "new_message",channelName: "消息推送",title: "",body: "",ext: "");
displayDefaultNotificationForMessage
V2TimMessage
,生成通知。V2TimMessage
即可。cPush.displayDefaultNotificationForMessage(message: message, channelID: "new_message", channelName: "消息推送");
displayDefaultNotificationForMessage
,或在 displayNotification
中使用与default相同的ext生成函数,此时的ext结构为:"conversationID": "对应的conversation"
。clearAllNotification()
方法即可。BuildContext? _cachedContext;final TimUiKitPushPlugin cPush = TimUiKitPushPlugin(isUseGoogleFCM: true, // 中国大陆版无此参数);@overridevoid initState() {super.initState();_cachedContext = context;}void onClickNotification(Map<String, dynamic> msg) async {String ext = msg['ext'] ?? "";Map<String, dynamic> extMsp = jsonDecode(ext);String convId = extMsp["conversationID"] ?? "";// 若当前的会话与要跳转至的会话一致,则不跳转// 此处建议您自行判断下,用户当前打开的页面final targetConversationRes = await TencentImSDKPlugin.v2TIMManager.getConversationManager().getConversation(conversationID: convId);V2TimConversation? targetConversation = targetConversationRes.data;if(targetConversation != null){cPush.clearAllNotification();Navigator.push(_cachedContext ?? context,MaterialPageRoute(builder: (context) => Chat(selectedConversation: targetConversation,),));}}
ext
结构,则需自实现点击跳转函数。onRecvNewMessage
内定义,触发推送通知的时机及场景。
本页内容是否解决了您的问题?