集成华为推送
按照本指南集成 华为推送服务(Push Kit),让融云 SDK 支持从华为推送服务获取推送通知。
在集成第三方推送前,请确保已在融云控制台配置 Android 应用 ID。详见推送集成概述。
在融云控制台配置华为推送
如果想通过华为推送接收融云即时通讯服务的推送通知,您需要在融云控制台上提供您的华为推送应用的详细信息。
-
前往华为 AppGallery Connect 网站,点击我的项目,在项目列表中找到您的项目,上方导航栏选择需要查看信息的应用。
如下图所示,test-push 是项目名称,huawei-app-1 是已关联到该项目的应用。
提示如果没有华为开发者账号,或尚未创建项目和应用,请先创建账号、项目和应用。详见华为开发者文档创建账号、创建应用。请确保项目下已关联了应用,启用了推送服务,并配置签名证书指纹。如您对华为控制台上配置推送服务的流程有任何疑问,可参见华为官方开发者文档配置 AppGallery Connect。
您需要记录下应用下的 Client ID(同 App ID) 和 Client Secret。
-
打开融云控制台,在应用标识页面点击设置推送,找到 Android > 华为推送,填入上一步获取的 Client ID、Client Secret。
-
(可选)配置自定义点击消息动作的 Intent。详见华为官方开发者文档自定义点 击消息动作。
- 注意 intent 的格式必须要以
end
结尾。 - 自定义 intent 后,需按照定义 intent 在
AndroidManifest.xml
的 Activity 中配置如下intent-filter
。
- 注意 intent 的格式必须要以
-
(可选)配置推送角标数。详见华为官方开发者文档桌面角标。
- badgeAddNum:应用角标累加数字非应用角标实际显示数字,为大于0小于100的整数。例如,某应用当前有N条未读消息,若 add_num 设置为3,则每发一次消息,应用角标显示的数字累加3,为 N+3。
- Activity:应用入口 Activity 类全路径。样例:com.example.hmstest.MainActivity
-
(可选)配置默认的华为推送通道的消息自分类标识,例如
IM
。App 根据华为要求完成自分类权益申请 或 申请特殊权限 后配置字段有效。详见华为推送官方文档消息分类标准。配置成功后,当前包名接收的华为推送通知默认均会携带该字段。注意,如果客户端或服务端发送消息时配置了华为推送 Category,则使用发消息时指定的配置。 -
配置推送通知标题。设置默认的推送通知标题。一般情况下客户端发 送消息转 Push 时不使用此标题设置。在调用融云服务端 API
/push.json
、/push/user.json
、/push/custom.json
接口推送通知时,如未传入通知标题,则使用该处设置的标题。从服务端发消息时,如果发送用户 ID 在融云服务端没有用户名,也会使用此 “推送通知标题”。 -
保存设置。所有设置 30 分钟后生效。
您已完成需要融云控制台华为推送配置的全部内容。现在可以设置客户端集成。
配置客户端接收华为推送
首先,需要将华为推送客户端 SDK 添加到您的 Android 项目。
根据华为开发者文档集成 HMS Core SDK,您需要将 “agconnect-services.json” 文件添加到您的 App 中。点击 agconnect-services.json 下载配置文件。
将下载好的 agconnect-servics.json
文件放到 app 模块下的根目录,如下图:
导入华为推送 SDK
华为推送客户端 SDK 需要从华为 Maven 仓库获取。Android Studio的代码库配置在 Gradle 插件 7.0 以下版本、7.0 版本和 7.1 及以上版本有所不同。详见华为官方开发者文档集成 HMS Core SDK中的「配置 HMS Core SDK 的 Maven 仓库地址」。
本步骤中以 Gradle 插件 7.0 以下版本为例。打开在 project 的 build.gradle
中添加如下内容。
allprojects {
repositories {
//Add Huawei Maven
maven {url 'http://developer.huawei.com/repo/'}
}
}
buildscript{
repositories {
//Add Huawei Maven
maven { url 'http://developer.huawei.com/repo/' }
}
dependencies {
// Add this line
classpath 'com.huawei.agconnect:agcp:1.6.1.300'
}
}
“buildscript > dependencies” 下需要添加 AGC 插件配置,请您参见华为官方开发者文档 AGC 插件依赖关系选择合适的 AGC 插件版本。
添加华为 Maven 仓库后,您可以在 App 的 build.gradle
中添加依赖,直接引入华为推送客户端 SDK。建议您集成的SDK使用最新版本号,版本号索引请参见华为官方开发者文档推送服务 SDK 版本更新说明。
在 app 模块的 build.gradle
添加如下内容:
dependencies {
// Add this line
implementation 'com.huawei.hms:push:6.7.0.300'
}
...
// Add to the bottom of the file
apply plugin: 'com.huawei.agconnect'
华为 Push SDK 依赖说明:最新版本 Push SDK 需要终端设备上安装HMS Core(APK)4.0.0.300 及以上版本;如果用户手机没有安装,您的应用调用 HMS Core 时,会自动引导用户提示安装。
默认支持 HMS Core(APK)的手机包括:部分 EMUI 4.0 和 4.1 的手机,以及 EMUI 5.0 及之后的华为手机。
使用融云 SDK 提供的华为推送 Service
为了接收华为推送透传消息和获取推送 Token,必须实现一个继承自华为 Push Kit 基础类 HmsMessageService 的 service。融云 SDK 已经实现了该 service,您只需要将融云提供的 HMSPushService
注册到 AndroidManifest.xml 文件中,注册内容如下:
在 AndroidManifest.xml
中添加如下配置信息
<service
android:name="io.rong.push.platform.hms.HMSPushService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
以上步骤也可参考华为官方开发者文档配置 Manifest 文件。
启用华为推送服务
请在初始化融云 SDK 之前启用华为推送服务。融云 SDK 将向华为推送服务注册、并将获取的华为推送 Token 上报给融云服务端。
PushConfig 为所有推送配置相关的入口类。
PushConfig config = new PushConfig.Builder()
.enableHWPush(true)
.XXX //此处忽略其它三方推送配置
.build();
RongPushClient.setPushConfig(config); //将推送相关配置设置到 SDK
拦截并解析推送点击 Intent
华为通知栏推送方式下,当用户点击通知时,华为系统会通过隐式调用的方式发出 intent,可通过拦截解析 intent,获取用户点击行为以及携带的数据。
-
默认传递的 intent 如下:
intent://您的包名/conversationlist?isFromPush=true#Intent;scheme=rong;launchFlags=0x4000000;end
intent 会同时携带一些附加数据,比如在调用
RongIMClient.getInstance.sendMessage()
时传递的参数 pushData ; 使用控制台的广播推送功能时,自定义的键值对等。使用默认 intent 跳转,在主工程中的
AndroidManifest.xml
的 Activity 中配置如下intent-filter
,点击通知即可跳转到此 Activity.<activity
android:name="您的会话列表 activity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="${applicationId}"
android:pathPrefix="/conversationlist"
android:scheme="rong" />
</intent-filter>
</activity> -
在跳转界面获取并解析 intent 携带数据。
Intent intent = getIntent();
if (intent.getData().getScheme().equals("rong") && intent.getData().getQueryParameter("isFromPush") != null) {
if (intent.getData().getQueryParameter("isFromPush").equals("true")) {
String options = getIntent().getStringExtra("options"); // 获取 intent 里携带的附加数据
NLog.d(TAG, "options:", options);
try{
JSONObject jsonObject = new JSONObject(options);
if(jsonObject.has("appData")) { // appData 对应的是客户端 sendMessage() 时的参数 pushData
NLog.d(TAG, "pushData:", jsonObject.getString("appData"));
}
if(jsonObject.has("rc")) {
JSONObject rc = jsonObject.getJSONObject("rc");
NLog.d(TAG, "rc:", rc);
String targetId = rc.getString("tId"); // 该推送通知对应的目标 id.
String pushId = rc.getString("id"); // 控制台使用广播推送功能发出的推送通知,会有该字段,代表该推送的唯一 id, 需要调用下面接口,上传用户打开事件。
if(!TextUtils.isEmpty(pushId)) {
RongPushClient.recordNotificationEvent(pushId); // 上传用户打开事件,以便进行推送打开率的统计。
NLog.d(TAG, "pushId:", pushId);
}
if (rc.has("ext") && rc.getJSONObject("ext") != null) {
String ext = rc.getJSONObject("ext").toString(); // 使用控制台的广播推送功能时,填充的自定义键值对。
NLog.d(TAG, "ext:", ext);
}
}
} catch (JSONException e) {
}
enterActivity();
}
}
自定义铃声设置
Android 8.0 及以上手机支持设置通知渠道功能,在此基础上同时支持设置通道的自定义铃声功能。详细说明参见配置推送铃声
音频文件需要打包到应用中,存放在应用 /res/raw/ 目录,存储的声音文件需要有扩展名,但是不要把扩展名写在 uri 中。HMS 相关错误码说明可参考:错误码说明
角标未读数
融云不维护应用角标数量,融云客户端 SDK 不支持控制角标展示。如需了解与厂商推送通知相关的角标控制实现,可参考知识库文档推送角标。
常见问题
处理透传消息
融云 SDK 没有对华为的透传消息进行处理,如果用户通过华为推送运营平台使用了华为透传消息推送,可以继承 HMSPushService 实现 onMessageReceived 方法,并替换清单文件的 io.rong.push.platform.hms.HMSPushService。
无法获取 token 的异常情况
由于华为 4.0 推送需要华为手机 HMS Core 应用升级到 3.0 以上,2.0 的手机无法正常获取到 token 需要用户主动升级。下面是引导用户升级的代码示例,开发者可根据自身需求集成。
继承 PushMessageReceiver
重写 onThirdPartyPushState
public class SealNotificationReceiver extends PushMessageReceiver {
public static boolean needUpdate = false;
@Override
public boolean onNotificationMessageArrived(Context context, PushType pushType, PushNotificationMessage message) {
return false;
}
@Override
public boolean onNotificationMessageClicked(Context context, PushType pushType, PushNotificationMessage message) {
return false;
}
//华为获取 token 异常回调此方法
@Override
public void onThirdPartyPushState(PushType pushType, String action, long resultCode) {
super.onThirdPartyPushState(pushType, action, resultCode);
if (pushType.equals(PushType.HUAWEI)) {
if (resultCode == CommonCode.ErrorCode.CLIENT_API_INVALID) {
//设置标记位,引导用户升级
needUpdate = true;
}
}
}
}
注册监听
<!-- push start-->
<receiver
android:name=".push.SealNotificationReceiver"
android:exported="false">
<intent-filter>
<action android:name="io.rong.push.intent.MESSAGE_ARRIVED" />
<action android:name="io.rong.push.intent.MESSAGE_CLICKED" />
<action android:name="io.rong.push.intent.THIRD_PARTY_PUSH_STATE" />
</intent-filter>
</receiver>
当需要更新 HMS Core ,主动调用 RongPushClient.resolveHMSCoreUpdate() 方法,注意要传递 activity
if (SealNotificationReceiver.needUpdate) {
//重置标记位,防止多次弹窗提醒
SealNotificationReceiver.needUpdate = false;
RongPushClient.resolveHMSCoreUpdate(this);
}
删除配置(如配置过 2.x 版本及更早版本的华为推送)
如果您是首次接入华为推送,您无需删除配置。
如果您配置过 2.x 版本及更早版本的华为推送,请参见如下示例,删除从 "HMS 配置开始" 到 "HMS配置结束" 注释间的全部配置。
///HMS 配置开始
<meta-data
android:name="com.huawei.hms.client.appid"
android:value="10535759" />
<meta-data
android:name="firebase_messaging_auto_init_enabled"
android:value="false" />
<meta-data
android:name="firebase_analytics_collection_enabled"
android:value="false" />
<!-- BridgeActivity定义了HMS-SDK中一些跳转所需要的透明页面-->
<activity
android:name="com.huawei.hms.activity.BridgeActivity"
android:configChanges="orientation|locale|screenSize|layoutDirection|fontScale"
android:excludeFromRecents="true"
android:exported="false"
android:hardwareAccelerated="true"
android:theme="@android:style/Theme.Translucent">
<meta-data
android:name="hwc-theme"
android:value="androidhwext:style/Theme.Emui.Translucent" />
</activity>
<!-- 解决华为移动服务升级问题的透明界面(必须声明)-->
<activity
android:name="io.rong.push.platform.hms.common.HMSAgentActivity"
android:configChanges="orientation|locale|screenSize|layoutDirection|fontScale"
android:excludeFromRecents="true"
android:exported="false"
android:hardwareAccelerated="true"
android:theme="@android:style/Theme.Translucent">
<meta-data
android:name="hwc-theme"
android:value="androidhwext:style/Theme.Emui.Translucent" />
</activity>
<provider
android:name="com.huawei.hms.update.provider.UpdateProvider"
android:authorities="cn.rongcloud.im.hms.update.provider"
android:exported="false"
android:grantUriPermissions="true">
</provider>
<!-- 第三方相关 :接收Push消息(注册、Push消息、Push连接状态)广播 -->
<receiver android:name="io.rong.push.platform.hms.HMSReceiver">
<intent-filter>
<!-- 必须,用于接收token -->
<action android:name="com.huawei.android.push.intent.REGISTRATION" />
<!-- 必须,用于接收消息 -->
<action android:name="com.huawei.android.push.intent.RECEIVE" />
<!-- 可选,用于点击通知栏或通知栏上的按钮后触发onEvent回调 -->
<action android:name="com.huawei.android.push.intent.CLICK" />
<!-- 可选,查看push通道是否连接,不查看则不需要 -->
<action android:name="com.huawei.intent.action.PUSH_STATE" />
</intent-filter>
</receiver>
<receiver android:name="com.huawei.hms.support.api.push.PushEventReceiver">
<intent-filter>
<!-- 接收通道发来的通知栏消息,兼容老版本Push -->
<action android:name="com.huawei.intent.action.PUSH" />
</intent-filter>
</receiver>
///HMS 配置结束
移动端推送注册的 log 表明成功,查询消息流转也成功下发,但还是收不到推送
这个问题是因为调起 activity 的 intent 所指向的 activity,没有在 manifest 配属性导致的,偶现与一些 EMUI 版本。请参考如下步骤:
-
如果没有自定义点击跳转的 intent,那么需要在您的会 话列表界面所在的 activity 在 manifest的配置中加 android:exported="true" 这个flag
-
如果配置了自定义跳转的 intent,需要在相应要跳入的 activity 在 manifest 的配置中加 android:exported="true" 这个 flag