跳到主要内容

集成华为推送

按照本指南集成 华为推送服务(Push Kit),让融云 SDK 支持从华为推送服务获取推送通知。

在集成第三方推送前,请确保已在融云控制台配置 Android 应用 ID。详见推送集成概述。

在融云控制台配置华为推送​

如果想通过华为推送接收融云即时通讯服务的推送通知,您需要在融云控制台上提供您的华为推送应用的详细信息。

  1. 前往华为 AppGallery Connect 网站,点击我的项目,在项目列表中找到您的项目,上方导航栏选择需要查看信息的应用。

    如下图所示,test-push 是项目名称,huawei-app-1 是已关联到该项目的应用。

    (width=600)

    提示

    如果没有华为开发者账号,或尚未创建项目和应用,请先创建账号、项目和应用。详见华为开发者文档创建账号、创建应用。请确保项目下已关联了应用,启用了推送服务,并配置签名证书指纹。如您对华为控制台上配置推送服务的流程有任何疑问,可参见华为官方开发者文档配置 AppGallery Connect。

    您需要记录下应用下的 Client ID(同 App ID) 和 Client Secret。

    (height=400)

  2. 在需先按控制台内嵌指南嵌入到管理后台的 IM 服务功能配置页面(page_code: im_service_config)中,进入 离线推送 > 应用标识及推送证书管理 > 设置推送 > Android > 华为推送,填入上一步获取的 Client ID、Client Secret。

    (height=400)

  3. (可选)配置自定义点击消息动作的 Intent。详见华为官方开发者文档自定义点击消息动作。

    • 注意 intent 的格式必须要以 end 结尾。
    • 自定义 intent 后,需按照定义 intent 在 AndroidManifest.xml 的 Activity 中配置如下 intent-filter。
  4. (可选)配置推送角标数。详见华为官方开发者文档桌面角标。

    • badgeAddNum:应用角标累加数字非应用角标实际显示数字,为大于0小于100的整数。例如,某应用当前有N条未读消息,若 add_num 设置为3,则每发一次消息,应用角标显示的数字累加3,为 N+3。
    • Activity:应用入口 Activity 类全路径。样例:com.example.hmstest.MainActivity
  5. (可选)配置默认的华为推送通道的消息自分类标识,例如 IM。App 根据华为要求完成自分类权益申请 或 申请特殊权限 后配置字段有效。详见华为推送官方文档消息分类标准。配置成功后,当前包名接收的华为推送通知默认均会携带该字段。注意,如果客户端或服务端发送消息时配置了华为推送 Category,则使用发消息时指定的配置。

  6. 配置推送通知标题。设置默认的推送通知标题。一般情况下客户端发送消息转 Push 时不使用此标题设置。在调用融云服务端 API /push.json、 /push/user.json、/push/custom.json 接口推送通知时,如未传入通知标题,则使用该处设置的标题。从服务端发消息时,如果发送用户 ID 在融云服务端没有用户名,也会使用此 “推送通知标题”。

  7. 保存设置。所有设置 15 分钟后生效。

您已完成需要融云控制台华为推送配置的全部内容。现在可以设置客户端集成。

配置客户端接收华为推送​

首先,需要将华为推送客户端 SDK 添加到您的 Android 项目。

根据华为开发者文档集成 HMS Core SDK,您需要将 “agconnect-services.json” 文件添加到您的 App 中。点击 agconnect-services.json 下载配置文件。

(height=400)

将下载好的 agconnect-servics.json 文件放到 app 模块下的根目录,如下图:

(height=250)

导入华为推送 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 中添加如下内容。

Groovy
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 添加如下内容:

Groovy
 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 中添加如下配置信息

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 为所有推送配置相关的入口类。

Java
PushConfig config = new PushConfig.Builder()
.enableHWPush(true)
.XXX //此处忽略其它三方推送配置
.build();
RongPushClient.setPushConfig(config); //将推送相关配置设置到 SDK

拦截并解析推送点击 Intent​

华为通知栏推送方式下,当用户点击通知时,华为系统会通过隐式调用的方式发出 intent,可通过拦截解析 intent,获取用户点击行为以及携带的数据。

  1. 默认传递的 intent 如下:

    HTTP
    intent://您的包名/conversationlist?isFromPush=true#Intent;scheme=rong;launchFlags=0x4000000;end

    intent 会同时携带一些附加数据,比如在调用 RongIMClient.getInstance.sendMessage() 时传递的参数 pushData ; 使用控制台的广播推送功能时,自定义的键值对等。

    使用默认 intent 跳转,在主工程中的 AndroidManifest.xml 的 Activity 中配置如下 intent-filter,点击通知即可跳转到此 Activity.

    xml
    <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 即为要隐式跳转的页面设置。详见华为官方开发者文档自定义点击消息动作。可在融云控制台,在 服务管理 -> 应用标识 -> Android -> 华为推送设置 栏目中自定义设置。

  2. 在跳转界面获取并解析 intent 携带数据。

    Java
    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

Java
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;
}
}
}
}

注册监听

xml
<!-- 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

Java
if (SealNotificationReceiver.needUpdate) {
//重置标记位,防止多次弹窗提醒
SealNotificationReceiver.needUpdate = false;
RongPushClient.resolveHMSCoreUpdate(this);
}

删除配置(如配置过 2.x 版本及更早版本的华为推送)​

如果您是首次接入华为推送,您无需删除配置。

如果您配置过 2.x 版本及更早版本的华为推送,请参见如下示例,删除从 "HMS 配置开始" 到 "HMS配置结束" 注释间的全部配置。

xml
///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 版本。请参考如下步骤:

  1. 如果没有自定义点击跳转的 intent,那么需要在您的会话列表界面所在的 activity 在 manifest的配置中加 android:exported="true" 这个flag

  2. 如果配置了自定义跳转的 intent,需要在相应要跳入的 activity 在 manifest 的配置中加 android:exported="true" 这个 flag