跳到主要内容

Android 混合推送指南

混合推送概述​

自 Android 8.0 之后,系统权限控制越来越严,第三方推送通道的生命周期受到较大限制;同时,国内主流厂商也开始推出自己独立的推送服务,而厂商间千差万别的繁杂接口徒增了开发和代码维护的难度。为此,我们推出混合推送方案。我们逐一对接国内主流厂商,将它们不同的接口隐藏起来,让开发者通过统一的 API 完成推送任务。这保障了主流 Android 系统上的推送到达率,也大幅降低了开发复杂度。

在混合推送方案里,消息下发时使用的通道不再是我们自己维持的 WebSocket 长连接,而是借用厂商和 OS 层的系统通道进行通信。 一条推送消息下发的步骤如下:

  1. 开发者调用云服务 Push API 请求对全部或特定设备进行推送;
  2. 云推送服务端将请求转发给厂商的推送接口;
  3. 厂商通过手机端的系统通道下发推送消息,同时手机端系统消息接收器将推送消息展示到通知栏;
  4. 终端用户点击消息之后唤起目标应用或者页面。

整个流程与苹果的 APNs 推送类似,SDK 在客户端基本不会得到调用(具体依赖于厂商的实现方案),消息的下发和展示都依赖厂商客户端的行为。所以如果部分厂商在某些推送中夹带了其他非开发者提交的消息,或者在服务启用的时候,有额外营销性质的弹窗,这都是厂商自己的行为,与我们完全无关,还请大家了解。另外,如果开发者碰到厂商 SDK 的问题,我们也无法深入调查,还请大家自行到厂商的论坛或技术支持渠道咨询解决。

Android 混合推送功能仅对商用版应用开放,如果希望使用该功能,请进入 应用 > 推送 > 设置 > 混合推送,打开混合推送的开关。

注意,混合推送可以随时按需开关。当该选项关闭后,下一次 Android 推送会与普通推送一样自动选择自有通道送达客户端,除了会再次遇到上面提到的自有通道在部分 ROM 上会受到限制的问题之外,不会有别的影响。而当该选项再次开启后,Android 推送又会去选择厂商推送渠道。

开启了混合推送之后,Installation 表中每一个设备对应的记录,会增加 registrationId 字段,用于记录厂商分配的注册 id(类似于 APNs 的 device token),同时还会增加一个 vendor 字段(如果没有这一字段,则说明客户端集成有问题),其值为

vendor厂商
HMS华为 HMS 推送
mi小米推送
mz魅族推送
oppoOPPO 推送
vivovivo 推送
honor荣耀推送

注意,混合推送对接的是厂商各自的推送服务,需要单独配置,不支持混用。 通常情况下,需要提交不同的版本(分别对接厂商的推送服务)到相应厂商的应用商店。 如果希望使用统一版本,那么需要自行判断手机型号,在手机上开启对应的推送。

推送提醒的红点或角标展示​

很多开发者都希望可以在应用桌面开启角标或者小红点,以达到更好的提醒效果。国内厂商对此功能的开放程度不一,详见下表:

厂商是否支持角标/红点是否需要配置适配说明
华为支持角标是请参考下文华为角标适配说明
小米支持角标否遵从系统默认逻辑,感应通知栏通知数目,按 1 自动增减
OPPO支持红点否圆点展示需由用户在通知设置中手动开启,遵从系统默认逻辑,有通知则展示,无则不展示;数值展示只对指定应用开启,例如 QQ、微信,需向官方进行权限申请,暂无明确适配说明。
vivo支持角标是参考下文vivo 手机角标适配说明
魅族支持红点否遵从系统默认逻辑,仅支持红点展示,有通知则展示,无则不展示
荣耀支持角标否客户端无需配置,服务端推送时通过 badge 参数进行设置,详情可参考:荣耀服务端推送.

通知栏消息与透传消息​

很多开发者会关心通知栏消息和透传消息是否支持,因为应用状态不同,可能接收到消息的途径不一样,产品层面希望的处理方式也有差异。不同厂商对透传消息的支持不一样,详见下表:

厂商是否支持透传消息
华为是
小米是
OPPO否
vivo否(老版本有透传接口,新版本已不建议使用)
魅族否
荣耀是

注意,如果指定了 silent 为真,但厂商不支持透传,那么这条消息会被丢弃,推送记录中会记录相应的报错信息。

即时通讯的离线推送​

在即时通讯服务中,在 iOS 平台上如果用户下线,是可以启动离线消息推送机制的,对于 Android 用户来说,如果只是使用云推送自有通道,那么是不存在离线推送的,因为聊天和推送共享同一条 WebSocket 长链接,在即时通讯服务中用户下线了的话,那么推送也必然是不可达的。但是如果启用了混合推送,因为推送消息走的是厂商通道,这一点和 iOS 基本一致,所以这时候 Android 用户就存在离线推送的通知路径了。 也就是说,如果开启了混合推送,那么即时通讯里面的离线推送和静音机制,对使用了混合推送的 Android 用户也是有效的。

受限说明​

推送消息长度限制:

  • 消息中的应用包名最大支持 128 字节,消息内容最大支持 4KB 字节。

最低 Android 版本要求:

  • 华为推送需要用户手机上安装 HMS Core(APK)6.11.0.300 及以上版本,最低 Android 版本为 4.4(minSdkVersion 19)。
  • 小米推送服务 SDK 支持的最低安卓版本为 4.4(minSdkVersion:19)。
  • vivo 推送服务支持的最低 Android 版本为 6.0(minSdkVersion:23)。
  • OPPO 推送只支持 Android 4.4 或以上版本的手机系统(minSdkVersion:19)。
  • 魅族(flyme)推送只支持 Android 4.2 或以上版本的手机系统(minSdkVersion:17)。
  • 荣耀 推送支持国内Magic UI 4.0及以上,海外Magic UI 4.2及以上(minSdkVersion 19)。

影响送达率的因素说明:

  • 终端设备是否在线。如果设备离线,推送服务会缓存消息,待设备上线后,再将消息推送给设备。
  • 终端设备上集成推送服务 SDK 的应用是否被卸载。
  • 终端设备的网络状况是否稳定。
  • 终端设备的安全控制策略。
  • 透传消息的送达受 Android 系统和应用是否驻留在后台影响。

下面我们逐一看看如何对接华为、小米、魅族等厂商的推送服务。

推荐的接入方式​

混合推送本质上还是依赖于各厂商的 SDK 和服务端能力,我们的客户端 SDK 只是对厂商 SDK 的包装,而实际的推送请求也是通过 LeanCloud 中转之后发送到厂商后台。因为是一对多的关系,我们的客户端 SDK 更新速度可能跟不上厂商的迭代速度,因此建议大家直接对接厂商 SDK,然后在客户端把厂商分配的「注册 id」与厂商标识(见上一章 vendor 的说明)保存到设备信息(Installation)中,这样之后一样可以通过我们的推送 API 来给所有设备正确发送推送信息。

客户端接入方法​

不同厂商获取「注册 id」的流程和接口会有不同,可以参考厂商平台的开发指南,这里我们说一下集成厂商 SDK 获取到「注册 id」之后如何按照规范来保存设备信息。

华为推送(HMS)​

开发者从 HmsMessageService 继承自己的实现类,然后在 onNewToken(String token) 回调函数中调用如下代码进行保存:

  public static void updateInstallation(String hwToken) {
if (StringUtil.isEmpty(hwToken)) {
return;
}
LCInstallation installation = LCInstallation.getCurrentInstallation();
if (!VENDOR.equals(installation.getString(LCInstallation.VENDOR))) {
installation.put(LCInstallation.VENDOR, "HMS");
}
if (!hwToken.equals(installation.getString(LCInstallation.REGISTRATION_ID))) {
installation.put(LCInstallation.REGISTRATION_ID, hwToken);
}
installation.saveInBackground().subscribe(ObserverBuilder.buildSingleObserver(new SaveCallback() {
@Override
public void done(LCException e) {
if (null != e) {
LOGGER.e("update installation error!", e);
} else {
LOGGER.d("Huawei push registration successful!");
}
}
}));
}

示例代码可以参考LCHMSMessageService。

小米推送​

开发者从 PushMessageReceiver 继承自己的实现类,然后在 onReceiveRegisterResult 回调函数中调用如上例代码进行保存(记得将 vendor 换成 mi)。示例代码可以参考LCMiPushMessageReceiver。

OPPO 推送​

开发者从 ICallBackResultService 继承自己的实现类,然后在 onRegister 回调函数中调用如上例代码进行保存(记得将 vendor 换成 oppo)。示例代码可以参考LCOPPOPushAdapter。

vivo 推送​

开发者从 OpenClientPushMessageReceiver 继承自己的实现类,然后在 onReceiveRegId 回调函数中调用如上例代码进行保存(记得将 vendor 换成 vivo)。示例代码可以参考LCVIVOPushMessageReceiver。

魅族推送​

开发者从 MzPushMessageReceiver 继承自己的实现类,然后在 onRegisterStatus 回调函数中调用如上例代码进行保存(记得将 vendor 换成 mz)。示例代码可以参考LCFlymePushMessageReceiver。

荣耀推送​

开发者从 HonorMessageService 继承自己的实现类,然后在 onNewToken 回调函数中调用如上例代码进行保存(记得将 vendor 换成 honor)。示例代码可以参考LCHonorMessageService。

发送混合推送的服务端 API​

可以参考这里的说明来发送推送请求:推送 REST API 使用指南。

如果开发者要集成我们封装的混合推送 SDK,可以继续往下阅读,如果自行接入厂商 SDK,则可以忽略下文。

混合推送 library 的构成​

我们提供了一个 all-in-one 的混合推送模块,统一支持华为(HMS)、小米、OPPO、vivo、魅族、荣耀推送,开发者依赖如下:

cn.leancloud:mixpush-android:8.2.28@aar

从 6.5.1 版本开始,我们额外提供了单一厂商的推送 library,以支持不希望全部集成的产品之需求,新 library 与厂商的对应关系如下:

  • 华为(HMS) cn.leancloud:mixpush-hms:8.2.28
  • 小米 cn.leancloud:mixpush-xiaomi:8.2.28
  • 魅族 cn.leancloud:mixpush-meizu:8.2.28
  • OPPO cn.leancloud:mixpush-oppo:8.2.28
  • vivo cn.leancloud:mixpush-vivo:8.2.28
  • 荣耀 cn.leancloud:mixpush-honor:8.2.28

两组 library 的使用方法基本相同,开发者可以根据自己的需要选取合适的 library。有一点需要注意的是,在 6.5.1 及后续版本的 library 中,由于小米、OPPO、vivo 、荣耀并没有将他们的 SDK 包发布到公开源供开发者引用,所以如果是使用这几个厂商的推送,需要开发者将厂商的 SDK 包手动加入工程中。

混合推送 SDK 的获取方法​

我们已经把所有的 library 推送到了 maven 中央仓库,开发者可以直接在 build.gradle 中进行引用(maven 依赖方式)。

但是对于华为和荣耀推送(从 8.2.16 版本开始支持),因为厂商是将他们的基础 sdk 发布到私有仓库,所以我们在使用 mixpush-android(all in one 版本) 或者 mixpush-hms(华为推送)/mixpush-honor(荣耀推送)时,需要在项目级 build.gradle 文件的 allprojects/repositories 和 buildscript/repositories 中增加仓库地址(分别对应不同的推送目标):

maven {url 'http://developer.huawei.com/repo/'}
maven {url 'https://developer.hihonor.com/repo/'}

开发者可以参考我们的 all-in-one demo 来进行集中配置。

华为推送-HMS 版本​

环境配置​

  1. 注册华为账号:在 华为开发者联盟 注册华为开发者账号。
  2. 开发前准备:接入华为 PUSH 之前,需要创建应用并配置应用签名,具体可参考华为官方文档:开发准备。
  3. 打开推送服务开关:登录华为开发者联盟,按照开发准备一文中的提示开通推送服务。
  4. 将华为 App 信息保存到 开发者中心 控制台:将上面创建的华为 App 信息(主要有 AppId 和 AppSecret),通过 开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 推送通知 > 设置 > 混合推送 与应用关联。

接入 SDK​

获取 HMS SDK​

当前版本 SDK 依赖华为 PushKit V5 版本,开发者可以参考华为官方文档完成 HMS SDK 的接入。 其主要步骤有:

  • 在 AndroidStudio 开发环境中添加当前应用的 AppGallery Connect 配置文件,如下图所示:

    image

  • 配置 HMS SDK 的 maven 仓库地址。

    • 在项目级 build.gradle 文件的 allprojects/repositories 和 buildscript/repositories 中增加仓库地址:

      maven {url 'http://developer.huawei.com/repo/'}
  • 在项目级 build.gradle 的 buildscript/dependencies 里面增加配置:

    dependencies {
    classpath 'com.android.tools.build:gradle:4.1.1'
    classpath 'com.huawei.agconnect:agcp:1.6.0.300'
    }
  • 添加编译依赖。

    • 在应用级的 build.gradle 头部增加如下配置:

      apply plugin: 'com.huawei.agconnect'

      如下图所示:

      applyImage

    • 在应用级的 build.gradle 中增加如下编译依赖:

      dependencies {
      //其他已存在的依赖不要删除
      implementation 'com.huawei.hms:push:6.11.0.300'
      }
  • 在 android 中配置签名

    将生成签名证书指纹步骤中生成的签名文件拷贝到工程的 app 目录下,在 build.gradle 文件中配置签名:

    android {
    signingConfigs {
    config {
    keyAlias 'pushdemo'
    keyPassword '123456789'
    storeFile file('demo.keystore')
    storePassword '123456789'
    }
    }

    buildTypes {
    debug {
    signingConfig signingConfigs.config
    }
    release {
    signingConfig signingConfigs.config
    minifyEnabled false
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    }
    }

做完这些修改后,Android Studio 右上方出现 Sync Now 链接。点击 Sync Now 等待同步完成。

修改应用 manifest 配置​

首先导入 mixpush-hms 包,修改 build.gradle 文件,在 dependencies 中添加依赖:

dependencies {
//混合推送需要的包
implementation 'cn.leancloud:mixpush-hms:8.2.28'
//即时通信与推送需要的包
implementation 'cn.leancloud:realtime-android:8.2.28'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

implementation 'com.huawei.hms:push:6.11.0.300'
}

如果希望一次性接入所有厂商推送,可以将 mixpush-hms 替换为 mixpush-android。

然后配置相关 AndroidManifest,添加 Permission(开发者要将其中的 <包名> 替换为自己的应用的 package):

<!-- HMS-SDK引导升级HMS功能,访问OTA服务器需要网络权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 检测网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

集成最新的 HMS Core Push SDK 版本后要在 AndroidManifest.xml 文件的 application 节点下参照以下步骤注册 Service,用于接收华为推送的消息与令牌。

<service
android:name="cn.leancloud.LCHMSMessageService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>

具体使用​

  1. 在 application 的 onCreate 方法中调用 LeanCloud.initialize 完成初始化之后,进行混合推送 library 的初始化:

    • 使用 mixpush-android 的开发者,调用 cn.leancloud.LCMixPushManager.registerHMSPush(context, profile) 完成 HMS 推送的初始化。
    • 使用 mixpush-hms 的开发者,调用 cn.leancloud.hms.LCMixPushManager.registerHMSPush(context, profile) 完成 HMS 推送的初始化。

    这里参数 profile 的用法可以参考推送 REST API 使用指南的《Android 混合推送多配置区分》一节。

  2. 务必在应用启动的首个 activity 的 onCreate 方法中调用 LCMixPushManager.connectHMS(activity) ,确保 HMS SDK 连接成功。如果开发者不通过 AppGallery Connect 配置文件来集成,我们也提供了 LCMixPushManager.connectHMS(activity, huaweiAppId) 来显式指定华为应用 id 完成连接。

云端只有在满足以下全部条件的情况下才会使用华为推送:

- EMUI 系统
- 在华为后台正确配置应用签名
- manifest 正确填写

检测华为推送是否集成成功,可以检查 Installation 表中该设备对应的记录是否增加一个 vendor 字段,vendor 字段值为 HMS 表示设备成功注册为华为 HMS 推送。

提升透传消息到达率​

透传消息是由客户端应用负责处理的消息。终端设备收到透传消息后不直接展示,而是将数据传递给应用,由应用自主解析内容,并触发相关动作(如跳转网页、应用内页面等等)。透传消息的常用场景包括好友邀请、VoIP 呼叫、语音播报等。 按照华为官方说明,透传消息的到达率受 Android 系统和应用是否驻留在后台影响,推送服务不保证透传消息的高到达率,并且会让应用层处理变得复杂,所以还是推荐大家使用普通的通知栏消息。

当使用华为推送发透传消息时,如果目标设备上应用进程被杀,会出现推送消息无法接收的情况。这个是华为 ROM 对透传消息广播的限制导致的,需要引导用户在华为「权限设置」中对应用开启自启动权限来避免。

应用在前台时自己处理通知栏消息​

华为手机可以支持这一需求,但需要在调用 REST API 发送消息时,指定 message.android.notification.foreground_show 值为 false,同时客户端 Manifest 中声明 HmsMessageService 子类,并声明 queries 节点(针对 Android 11 以上系统)。

REST API 请求示例:

{
"hms": {
"message": {
"notification": {
"title": "message title",
"body": "message body"
},
"android": {
"notification": {
"foreground_show": false,
"click_action": {
"type": 1,
"action": "com.huawei.codelabpush.intent.action.test"
}
}
}
}
}
}

manifest 配置示例:

<manifest ...>
...
<application ...>
<service android:name="cn.leancloud.LCHMSMessageService" android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
...
<queries>
<intent>
<action android:name="com.huawei.hms.core.aidlservice" />
</intent>
</queries>
...
</manifest>

使用特定 activity 响应推送消息​

华为推送消息,在用户点击了通知栏信息之后,默认是打开应用,用户也可以指定特定的 activity 来响应推送启动事件。

打开应用自定义页面有两种方式,一种是通过服务端 API 指定 intent 参数,另一种是指定 action 参数,我们混合推送 SDK 选择使用 intent 参数(具体可参考华为文档服务端发送 push 消息),开发者也可以在发送请求时自行指定 action 参数(按照华为的 REST API 规范指定即可)。

对于目标 activity,开发者需要在 manifest 文件的 application 中增加 intent-filter 的定义,例如:

<!-- (可选)开发者自定义的打开推送消息的目的 activity。-->
<activity android:name="<please use your own activity name>">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="lcpushscheme" android:host="cn.leancloud.push" android:path="/notify_detail"/>
</intent-filter>
</activity>

在目标 activity 的 onCreate 函数中可以从 intent extra data 中通过 content key 可以获得推送内容(JSON 格式,包含 push 消息中所有自定义属性)。 可以参考我们的示例:PushTargetActivity)。

一般情况下,这里 intent-filter 的内容都不需要修改。 如果同一开发者有多个应用都使用了我们的 HMS 混合推送,或者终端用户安装了多个使用我们的 HMS 混合推送的应用,那么在同一个终端上,推送消息在通知栏被点击之后,因为多个应用都响应同样的 intent-filter,所以会出现要选择应用来打开的情况。 这可以通过在 intent-filter 中配置不一样的 android:host 解决。

在云服务控制台,增加华为 HMS 推送配置的时候,开发者可以指定自己的 Android Intent Hostname(不指定就使用默认值 cn.leancloud.push),然后在这里的 intent-filter 中填上同样的值,客户端就可以区分不同应用的通知栏消息了。

云端在调用 HMS 推送接口的时候,会把开发者自定义的属性,使用固定的 intentUri pattern 来封装成 intent 数据,其中 intentUri 的固定格式为:

intent://HOST/notify_detail#Intent;scheme=lcpushscheme;S.content=XXXX;launchFlags=0x10000000;end

其中 HOST 就是上面配置的 Android Intent Hostname,默认值为 cn.leancloud.push;XXX 就是开发者自定义参数的 JSON 字符串做了 URL Encode 之后的值,只有这部分内容是开发者可以指定的。

云端发送这种推送的例子如下:

curl -X POST \
-H "X-LC-Id: {your app id}" \
-H "X-LC-Key: {your app key}" \
-H "Content-Type: application/json" \
-d '{
"where": {"channels" : "public"}
"data": {"alert" : "消息内容",
"title": "显示在通知栏的标题",
"k1" : "v1",
"k2" : "v2"}
}' \
https://{{host}}/1.1/push

云端最终发送给 HMS Server 的请求中 payload 字段为(其中 {"k1" : "v1","k2" : "v2"} 这个 JSON 串经过了 URLEncode 处理):

{
"hms": {
"msg": {
"type": 3,
"body": {
"title": "显示在通知栏的标题",
"content": "消息内容"
},
"action": {
"type": 1,
"param": {
"intent": "intent://cn.leancloud.push/notify_detail?S.content=%7B%22k1%22%3A%22v1%22%2C%22k2%22%3A%22v2%22%7D#Intent;scheme=lcpushscheme;launchFlags=0x10000000;end"
}
}
}
}
}

到目前为止,我们只支持一种 intentUri 格式,所以所有的推送请求都会被同一个 activity 响应。如果开发者需要最终显示不同的页面,可以由这个接收 activity 进行一次转发。

华为推送自定义 Receiver​

如果你想推送消息,但不显示在 Android 系统的通知栏中,而是执行应用程序预定义的逻辑,可以自定义 Receiver。 华为混合推送自定义 Receiver 需要继承 LCHMSMessageService,在收到透传消息的回调方法 onMessageReceived 获取推送消息数据。 你的 Receiver 可以按照如下方式实现:

public class MyHuaweiReceiver extends LCHMSMessageService {
@Override
public boolean onMessageReceived(RemoteMessage remoteMessage) {
try {
String message = remoteMessage.getData();
String content = "--- 收到推送消息:--- " + new String(message, "UTF-8");
System.out.println("TAG:" + content);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

AndroidManifest.xml 中把 LCHMSMessageService 替换为你自定义的 MyHuaweiReceiver。

<service
android:name=".MyHuaweiReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>

修改 HMS 推送注册函数。特别注意一点,使用自定义 Receiver 的时候,需要调用 LCMixPushManager.registerHMSPush(context, profile, receiverClazz) 或者 LCMixPushManager.registerHMSPush(context, receiverClazz) 来完成 HMS 推送的初始化,否则会导致 LCMixPushManager.registerHMSPush 调用失败。

推送的内容示例如下:

{
"alert": "消息内容",
"title": "显示在通知栏的标题",
"custom-key": "由用户添加的自定义属性,custom-key 仅是举例,可随意替换",
"silent": true //silent 属性,是透传消息与通知栏消息的标志
}

华为角标适配说明​

使用限制​

华为手机角标展示支持 EMUI 8.0 及以上手机。 受限于华为手机角标能力的开放程度,在不同的推送场景下角标功能有所不同,详见下表。

推送形式角标能力实现方式
通知栏消息支持角标自动加 1、直接设置或不变,支持通知点击的自动减 1,不支持通知清除的自动减 1通过管理台或 Push API 关键字设置
透传消息开发者自行处理设置、加减逻辑调用 HMS SDK 开放接口

配置说明​

应用内角标设置权限申请​

为能实现角标修改的正确效果,请首先为应用添加华为手机上的角标读写权限,具体实现为在应用 AndroidManifest.xml 文件的 manifest 标签下添加以下权限配置:

<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/>
华为手机终端设置角标自增减​

华为手机支持角标自动增减 1(负数为减,正数为增),需要在客户端通过代码实现,示例如下:

Bundle extra = new Bundle();
extra.putString("package", "xxxxxx");
extra.putString("class", "yyyyyyy");
extra.putInt("badgenumber", i);
context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, extra);

推送消息智能分类​

华为推送服务会将推送消息自动分为服务与通讯、资讯营销两类,不同类别的提醒方式有所差异,因此也会影响混合推送内容中一些属性的效果。 例如,服务与通讯分类默认使用系统铃声,资讯营销分类默认无铃声,这一设定只能由用户在手机的通知中心自行修改,sound 属性中指定的自定义铃声无效。 如果想要使用自定义铃声,需要创建 Channel,在创建时设置相应的铃声,这样指定 Channel 的推送就可以使用专门的铃声了。 不过,某些情况下,华为推送服务仍会将自定义 Channel 的推送归类为服务与通讯或资讯营销。

请参考华为的开发者文档了解服务与通讯、资讯营销两个分类的具体差异。

参考 demo​

我们提供了一个 最新的华为推送 demo,可供你在接入过程中参考。

华为推送测试​

华为推送在每日单设备推送数量上有一些限制,详细信息可以见华为官方文档;一般来说,资讯营销类消息的每日单设备的推送数量为 2 条。

所以在单设备测试华为推送时,需要添加一个参数用来标识此次推送是测试推送,测试推送不受每日单设备推送数量上限要求,详细信息可见华为官方文档的 target_user_type 参数;当设置 target_user_type 参数为 1 时,即表明此次推送为测试推送。

华为测试推送也存在一些限制,如下:

  • 每个应用每日可发送该测试消息 500 条
  • 单次推送不能超过 10 台设备

可以在推送的 data 中加入 target_user_type 参数,样例如下:

{
"alert" : "Hello",
"hms" : {
"target_user_type" : 1
}
}

注意:请不要在正式推送中使用 target_user_type 参数。

小米推送​

环境配置​

  1. 注册小米账号:在 小米开放平台 上注册小米开发者账号并完成实名认证(详细流程)。
  2. 创建小米推送服务应用(详细流程)。
  3. 设置小米的 AppId 及 AppSecret:在 小米开放平台 > 管理控制台 > 消息推送 > 相关应用 可以查到具体的小米推送服务应用的 AppId 及 AppSecret。将此 AppId 及 AppSecret 通过 开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 推送通知 > 设置 > 混合推送 与云服务应用关联。

接入 SDK​

我们混合推送基于小米 5.9.9 版本 SDK 进行开发。开发者需要首先导入 mixpush-android 包:修改 build.gradle 文件,在 dependencies 中添加依赖:

dependencies {
//混合推送需要的包
implementation fileTree(dir: 'libs', include: ['*.aar']) // 需将 MiPush_SDK_Client_5_9_9-C_3rd.aar 放入应用的 libs 目录下
implementation 'cn.leancloud:mixpush-android:8.2.28'
//即时通信与推送需要的包
implementation 'cn.leancloud:realtime-android:8.2.28'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
}

如果只希望接入小米推送,可以将 mixpush-android 替换为 mixpush-xiaomi。 如果是通过 aar 包导入,则需要手动下载 aar 包 小米 Push SDK。

然后配置相关 AndroidManifest。添加 Permission:

<!-- 小米 SDK 需要的权限。 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<permission android:name="<包名>.permission.MIPUSH_RECEIVE" android:protectionLevel="signature" />
<uses-permission android:name="<包名>.permission.MIPUSH_RECEIVE" />

添加 service 与 receiver。开发者要将其中的 <包名> 替换为自己的应用对应的 package:

<service
android:name="com.xiaomi.push.service.XMPushService"
android:enabled="true"
android:process=":pushservice"/>

<service
android:name="com.xiaomi.push.service.XMJobService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":pushservice" />

<service
android:name="com.xiaomi.mipush.sdk.PushMessageHandler"
android:enabled="true"
android:exported="true"/>

<service
android:name="com.xiaomi.mipush.sdk.MessageHandleService"
android:enabled="true"/>

<receiver
android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>

<receiver
android:name="com.xiaomi.push.service.receivers.PingReceiver"
android:exported="false"
android:process=":pushservice">
<intent-filter>
<action android:name="com.xiaomi.push.PING_TIMER"/>
</intent-filter>
</receiver>

<receiver
android:name="cn.leancloud.LCMiPushMessageReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE"/>
</intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED"/>
</intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.ERROR"/>
</intent-filter>
</receiver>

具体使用​

在 LeanCloud.initialize 之后调用以下函数进行混合推送 library 的初始化:

  • 使用 mixpush-android 的开发者,调用 cn.leancloud.LCMixPushManager.registerXiaomiPush(context, miAppId, miAppKey, profile) 。
  • 使用 mixpush-xiaomi 的开发者,调用 cn.leancloud.mi.LCMixPushManager.registerXiaomiPush(context, miAppId, miAppKey, profile) 。

这里:

  • 参数 miAppKey 需要的是 AppKey,而在控制台的混合推送配置中 Profile 的第二个参数是 AppSecret,请注意区分,并分别正确填写。
  • 参数 profile 的用法可以参考 推送 REST API 使用指南的《Android 混合推送多配置区分》一节。

云端只有在满足以下全部条件的情况下才会使用小米推送:

  • MIUI 系统
  • manifest 正确填写
  • appId、appKey、appSecret 有效

小米推送通知栏消息的点击事件​

当小米通知栏消息被点击后,如果已经设置了自定义 Receiver,则 SDK 会发送一个 action 为 com.avos.avoscloud.mi_notification_action 的 broadcast。如有需要,开发者可以通过订阅此消息获取点击事件,否则 SDK 会默认打开启动推送服务时设置的 Activity。

其它​

如果遇到报错「应用在黑名单中,禁止发送消息」,则原因可能是没在小米应用商店上架 APP。详细信息可以参见小米推送服务在 2022 年更新的小米推送技术服务协议。

魅族推送​

环境配置​

  1. 注册魅族账号:在 Flyme开放平台 上注册魅族开发者账号并完成开发者认证(详细流程)。
  2. 创建魅族推送服务应用(详细流程)。
  3. 设置魅族的 AppId 及 AppSecret:在 魅族推送平台 > 应用列表 > 打开应用 > 配置管理 可以查到具体的魅族推送服务应用的 AppId 及 AppSecret。将此 AppId 及 AppSecret 通过 开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 推送通知 > 设置 > 混合推送,与云服务应用关联。

接入 SDK​

首先导入 mixpush-android 包。修改 build.gradle 文件,在 dependencies 中添加依赖:

dependencies {
//魅族推送需要的包
implementation 'com.meizu.flyme.internet:push-internal:4.3.0'
//混合推送需要的包
implementation 'cn.leancloud:mixpush-android:8.2.28'
//即时通信与推送需要的包
implementation 'cn.leancloud:realtime-android:8.2.28'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
}

如果只希望接入魅族推送,可以将 mixpush-android 替换为 mixpush-meizu。

如果是通过 jar 包导入,则需要手动下载 jar 包 魅族 Push SDK。

然后配置相关 AndroidManifest。添加 Permission:

  <!-- 兼容flyme5.0以下版本,魅族内部集成pushSDK必填,不然无法收到消息-->
<uses-permission android:name="com.meizu.flyme.push.permission.RECEIVE"></uses-permission>
<permission android:name="<包名>.push.permission.MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="<包名>.push.permission.MESSAGE"></uses-permission>

<!-- 兼容flyme3.0配置权限-->
<uses-permission android:name="com.meizu.c2dm.permission.RECEIVE" />
<permission android:name="<包名>.permission.C2D_MESSAGE"
android:protectionLevel="signature"></permission>
<uses-permission android:name="<包名>.permission.C2D_MESSAGE"/>

添加 service 与 receiver。开发者要将其中的 <包名> 替换为自己的应用对应的 package:

<receiver android:name="cn.leancloud.LCFlymePushMessageReceiver">
<intent-filter>
<!-- 接收push消息 -->
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
<!-- 接收register消息 -->
<action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
<!-- 接收unregister消息-->
<action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK"/>
<!-- 兼容低版本Flyme3推送服务配置 -->
<action android:name="com.meizu.c2dm.intent.REGISTRATION" />
<action android:name="com.meizu.c2dm.intent.RECEIVE" />
<category android:name="<包名>"></category>
</intent-filter>
</receiver>

具体使用​

在 LeanCloud.initialize 之后调用以下函数进行混合推送 library 的初始化:

  • 使用 mixpush-android 的开发者,调用 cn.leancloud.LCMixPushManager.registerFlymePush(context, flymeId, flymeKey, profile) 。
  • 使用 mixpush-meizu 的开发者,调用 cn.leancloud.flyme.LCMixPushManager.registerFlymePush(context, flymeId, flymeKey, profile) 。

这里参数 profile 的用法可以参考推送 REST API 使用指南的《Android 混合推送多配置区分》一节。

注意,云端只有在以下三个条件都满足的情况下,才会使用魅族推送。

  • Flyme 系统
  • manifest 正确填写
  • flymeId、flymeKey 有效

魅族推送通知栏消息的点击事件​

当魅族通知栏消息被点击后,如果已经设置了自定义 Receiver,则 SDK 会发送一个 action 为 com.avos.avoscloud.flyme_notification_action 的 broadcast。如有需要,开发者可以通过订阅此消息获取点击事件,否则 SDK 会默认打开启动推送服务时对应设置的 Activity。

魅族推送测试​

测试魅族推送时,需提前将设备加入到魅族推送后台的「常用设备」列表中。登录魅族开发者账号,进入推送服务后台管理,然后进入「配置管理」页面,最后进入「常用设备」页面,添加常用设备。

vivo 推送​

vivo 混合推送 demo:可参照 这里。

环境配置​

要使用 vivo 官方推送服务,需要在 vivo 开发者平台注册一个账号,并创建好应用。 这里假设大家已经完成上述操作,创建好了应用,并获取了 appId、appKey、appSecret(请保存好这几个值,下一步接入的时候会用到。)

接入 SDK​

当前版本的 SDK 是基于 vivo 官方文档 push SDK 接入文档 封装而来,使用的 vivo push SDK 基线版本是 3.0.0.7。我们会结合 demo(源码)来解释整个接入流程。

首先将 demo 工程 app/libs 目录下的所有 jar 包(如有)拷贝到目标工程的 libs 目录下,然后修改 build.gradle 文件,在 dependencies 中添加依赖:

dependencies {
//混合推送需要的包
implementation files("libs/vivo_pushsdk-v3.0.0.7_488.aar") // 将 vivo_pushsdk-v3.0.0.7_488.aar 置于应用 libs 目录下
implementation 'cn.leancloud:mixpush-vivo:8.2.28'
//即时通信与推送需要的包
implementation 'cn.leancloud:realtime-android:8.2.28'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
}

接下来配置 AndroidManifest,添加权限声明:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

最后在 AndroidManifest 中添加必须的 service 与 receiver(开发者要将其中的 com.vivo.push.app_id 和 com.vivo.push.app_key 替换为自己的应用的信息):

<!--vivo Push需要配置的service、activity-->
<service
android:name="com.vivo.push.sdk.service.CommandClientService"
android:permission="com.push.permission.UPSTAGESERVICE"
android:exported="true" />
<activity
android:name="com.vivo.push.sdk.LinkProxyClientActivity"
android:exported="false"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <!-- push应用定义消息receiver声明 -->

<receiver android:name=".MyPushMessageReceiver">
<intent-filter>
<!-- 接收push消息 -->
<action android:name="com.vivo.pushclient.action.RECEIVE" />
</intent-filter>
</receiver>

<meta-data
android:name="com.vivo.push.api_key"
android:value="YOUR-APP-KEY" />
<meta-data
android:name="com.vivo.push.app_id"
android:value="YOUR-APP-ID" />

<!--vivo Push SDK的版本信息-->
<meta-data
android:name="sdk_version_vivo"
android:value="488"/>

接下来我们看看代码上要怎么做。

初始化​

与其他推送的初始化方法一样,我们在 Application#onCreate 方法中进行 vivo 推送的初始化:

import cn.leancloud.LeanCloud;
import cn.leancloud.LCMixPushManager; // 使用 mixpush-android 的场合
//import cn.leancloud.vivo.LCMixPushManager; // 使用 mixpush-vivo 的场合

public class MyApp extends Application {
// 请替换成你自己的 appId 和 appKey
private static final String LC_APP_ID = "xxx";
private static final String LC_APP_KEY = "xxx";

@Override
public void onCreate() {
super.onCreate();

//开启调试日志
LeanCloud.setLogLevel(LCLogger.Level.DEBUG);

// LeanCloud SDK 初始化
LeanCloud.initialize(this, "{{appid}}", "{{appkey}}", "https://please-replace-with-your-customized.domain.com");

// vivo 推送初始化
// 使用 mixpush-android 的场合,引用 cn.leancloud.LCMixPushManager
// 使用 mixpush-vivo 的场合,引用 cn.leancloud.vivo.LCMixPushManager
// 注意这里第二个参数,表示用户是否同意了应用的隐私声明。true:用户同意了隐私声明,默认同意;false:未同意隐私声明。
LCMixPushManager.registerVIVOPush(this, true);

LCMixPushManager.turnOnVIVOPush(new LCCallback<Boolean>() {
@Override
protected void internalDone0(Boolean aBoolean, LCException e) {
if (null != e) {
System.out.println("failed to turn on vivo push. cause:");
e.printStackTrace();
} else {
System.out.println("succeed to turn on vivo push.");
}
}
});
}
}

开发者也可以在 onCreate 方法中调用 LCMixPushManager 的其他方法,以使用 vivo 推送的全部客户端功能:

public class LCMixPushManager {
// 判断当前设备是否支持 vivo 推送
public static boolean isSupportVIVOPush(Context context);

// 关闭 vivo 推送
public static void turnOffVIVOPush(final LCCallback<Boolean> callback);

public static void bindVIVOAlias(Context context, String alias, final LCCallback<Boolean> callback);

public static void unbindVIVOAlias(Context context, String alias, final LCCallback<Boolean> callback);

public static String getVIVOAlias(Context context);

public static void setVIVOTopic(Context context, String topic, final LCCallback<Boolean> callback);

public static void delVIVOTopic(Context context, String topic, final LCCallback<Boolean> callback);

public static List<String> getVIVOTopics(Context context);
}

添加 vivo 推送配置​

在开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 推送通知 > 设置 页面开启混合推送服务,并且在「vivo 推送配置」一节设置好准备阶段申请好的 vivo appId、vivo appKey、vivo Secret,就可以了。

响应通知栏消息的点击事件​

与其他厂商的混合推送机制一样,vivo 混合推送也是通过系统通道来下发消息,开发者调用 push API 发送消息时,其流程为:

  • 用户服务器向云推送服务器发送推送请求;
  • 云推送服务器向 vivo 服务器 转发请求;
  • vivo 服务器通过系统长链接下发推送通知到手机端;
  • 手机端操作系统将消息展示在通知栏;
  • 用户点击通知栏消息。

新版的 vivo 推送已经不再通过 SDK 来响应通知栏的点击回调,而是在消息中直接指定了响应的 Activity 与附带数据,这要求我们在发送推送请求的时候就按照 vivo 的规则组织好参数,同时客户端 AndroidManifest 里需要声明好响应 Activity 支持的 filter,例如:

<activity
android:name=".CustomActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="cn.leancloud.push"
android:path="/detail"
android:scheme="mixpushscheme" />
</intent-filter>
</activity>

具体的客户端和 REST API 请求示例,可以参看我们的 demo。

vivo 手机角标适配说明​

使用限制​

vivo 的通知栏消息,并不支持角标显示,而透传消息(官方已建议不再继续使用),则可以由开发者自己处理设置逻辑。 vivo 桌面图标角标默认是关闭的,开发者接入完成后还需要终端用户手动开启,开启完成后收到新消息时,在已安装的应用桌面图标右上角显示「数字角标」。终端用户开启角标设置的路径是:「设置 > 通知与状态栏 > 应用通知管理 > 应用名称 > 桌面图标角标」。

视 OS 版本差异,「桌面图标角标」名称可能为「应用图标标记」或「桌面角标」。

配置说明​

  • 添加权限

    为能实现角标修改的正确效果,请首先为应用添加 vivo 手机上的角标读写权限,具体实现为在应用 AndroidManifest.xml 文件的 manifest 标签下添加以下权限配置:

    <uses-permission android:name="com.vivo.notification.permission.BADGE_ICON" />
  • 应用在需要显示桌面角标的场景,通过广播将信息发送给 vivoLauncher:

    广播参数:

    • action:launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM

    • packageName:应用包名

    • className:主类名

    • notificationNum:未读消息数目

      简单示例:

      Intent intent = new Intent();
      int missedCalls = 10;
      intent.setAction("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
      intent.putExtra("packageName", "com.android.xxxx");
      intent.putExtra("className", "com.android.xxxx.Mainxxxx");
      intent.putExtra("notificationNum", missedCalls);
      intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
      sendBroadcast(intent);

      注意: 在 8.0 系统上,还需要给 Intent 加上下面的 flag:Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND

OPPO 推送​

混合推送 OPPO 模块基于 oppo Push SDK v3.4.0 版本,支持 Android 4.4 或以上版本的手机系统,服务支持信息如下:

  • 支持平台:ColorOS 3.1 及以上的系统的 OPPO 机型,一加 5/5t 及以上机型,realme 所有机型。
  • 通知消息类型:只支持通知栏消息的推送。消息下发到 OS 系统模块并由系统通知模块展示,在用户点击通知前,不启动应用。具体限制可参考 OPPO 官方文档。

在接入时,开发者可以参考我们的 demo。

环境配置​

在开始接入之前,有两项准备工作:

这里假设大家已经完成上述操作,创建好了应用,并获取了 appKey、appSecret、masterSecret,请保存好这三个值,下一步接入的时候会用到:

  • SDK 初始化需要使用 appKey 和 appSecret 。
  • 服务端设置需要使用 appKey和 masterSecret。

接入 SDK​

下载 SDk​

  • 将之前下载的 SDK(com.heytap.msp_3.4.0.aar)复制到工程 libs/ 目录下,然后修改 build.gradle 文件,在 dependencies 中添加依赖:
dependencies {
//混合推送需要的包
implementation fileTree(dir: 'libs', include: ['*.aar'])
implementation 'cn.leancloud:mixpush-oppo:8.2.28'
//即时通信与推送需要的包
implementation 'cn.leancloud:realtime-android:8.2.28'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'commons-codec:commons-codec:1.6'
}

配置 AndroidManifest.xml​

注意:OPPO 推送服务SDK 3.4.0 版本支持的最低安卓版本为 Android 4.4 系统(minSdkVersion="19")。

  • 增加权限列表(如果应用无透传权限,则不用配置)

    <!-- 基础模块(必须加入以下声明)START -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <!-- 基础模块 END -->

    <uses-permission android:name="com.coloros.mcs.permission.RECIEVE_MCS_MESSAGE"/>
    <uses-permission android:name="com.heytap.mcs.permission.RECIEVE_MCS_MESSAGE"/>
  • 推送服务组件注册(如果应用无透传权限,则不用配置)

    <service
    android:name="com.heytap.msp.push.service.CompatibleDataMessageCallbackService"
    android:permission="com.coloros.mcs.permission.SEND_MCS_MESSAGE">
    <intent-filter>
    <action android:name="com.coloros.mcs.action.RECEIVE_MCS_MESSAGE"/>
    </intent-filter>
    </service> <!-- 兼容 Q 以下版本 -->
    <service
    android:name="com.heytap.msp.push.service.DataMessageCallbackService"
    android:permission="com.heytap.mcs.permission.SEND_PUSH_MESSAGE">
    <intent-filter>
    <action android:name="com.heytap.mcs.action.RECEIVE_MCS_MESSAGE"/>
    <action android:name="com.heytap.msp.push.RECEIVE_MCS_MESSAGE"/>
    </intent-filter>
    </service>. <!-- 兼容 Q 版本 -->

接下来我们看看代码上要怎么做。

初始化​

与其他推送的初始化方法一样,我们在 Application#onCreate 方法中进行 OPPO 推送的初始化:

import cn.leancloud.LeanCloud;
import cn.leancloud.LCOPPOPushAdapter;
import cn.leancloud.oppo.LCMixPushManager; // 使用 mixpush-oppo 的场合
//import cn.leancloud.LCMixPushManager; // 使用 mixpush-android 的场合

// Customized Application.
public class MyApp extends Application {
// 请替换成你自己的 appId 和 appKey
private static final String LC_APP_ID = "xxx";
private static final String LC_APP_KEY = "xxx";
private String OPPO_APPKEY = "your OPPO app id";
private String OPPO_APPSECRET = "your OPPO app secret";

@Override
public void onCreate() {
super.onCreate();

//开启调试日志
LeanCloud.setLogLevel(LCLogger.Level.DEBUG);

// LeanCloud SDK 初始化
LeanCloud.initialize(this, "{{appid}}", "{{appkey}}", "https://please-replace-with-your-customized.domain.com");

// OPPO 推送初始化
// 使用 mixpush-android 的场合,引用 cn.leancloud.LCMixPushManager
// 使用 mixpush-oppo 的场合,引用 cn.leancloud.oppo.LCMixPushManager
LCMixPushManager.registerOppoPush(this, OPPO_APPKEY, OPPO_APPSECRET, new LCOPPOPushAdapter());
}
}

开发者也可以在 onCreate 方法中调用 LCMixPushManager 的其他方法,以使用 OPPO 推送的全部客户端功能,具体可以参看 LCMixPushManager 的接口文档,或参考官方文档-详细 API 说明 来了解具体信息。

添加 OPPO 推送配置​

在开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 推送通知 > 设置页面开启混合推送服务,并且在「OPPO 推送配置」一节设置好准备阶段申请好的「OPPO app key」和「OPPO master secret」,就可以了。

响应通知栏消息的点击事件​

与其他厂商的混合推送机制一样,OPPO 混合推送也是通过系统通道来下发消息,开发者调用 push API 发送消息时,其流程为:

  • 用户服务器向云推送服务器发送推送请求;

  • 云推送服务器 向 OPPO 服务器 转发请求;

  • OPPO 服务器 通过系统长链接下发推送通知到手机端;

  • 手机端操作系统将消息展示在通知栏;

  • 用户点击通知栏消息。此时 OS 会根据 push 参数执行不同的动作(默认值为 0):

    1. 启动应用;
    2. 打开应用内页(activity 的 intent action);
    3. 打开网页;
    4. 打开应用内页(activity);
    5. Intent scheme URL

客户端响应用户点击的过程不需要 SDK 参与,全部都是由系统通过消息里面附带的信息来自行处理。混合推送现在可支持所有动作方式,具体可参考我们的 demo。

荣耀推送​

环境配置​

  1. 注册荣耀账号:在 荣耀开发者平台 注册荣耀开发者账号。
  2. 开发前准备:接入荣耀 PUSH 之前,需要申请开通推送服务,开通流程可以参考 推送服务开通流程 ,其中配置 SHA256 证书指纹 可以参考 指纹证书生成。
  3. 配置消息回执,设置步骤可参考 消息回执,回调地址请设置为:https://callback.tds1.tapapis.cn/push/v1/callback/honor。
  4. 将荣耀 App 信息保存到 开发者中心 控制台:将上面创建的荣耀 App 信息(主要有 APP ID、APP Secret、Client ID、Client Secret),通过 开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 推送通知 > 设置 > 混合推送 与应用关联。

接入 SDK​

获取荣耀推送 SDK​

开发者可以参考荣耀推送官方文档,完成荣耀推送 SDK 的接入。其主要步骤有:

  • 配置荣耀 SDK 的 maven 仓库地址。在项目级 build.gradle 文件的 allprojects/repositories 和 buildscript/repositories 中增加仓库地址:

    maven { url 'https://developer.hihonor.com/repo/' }
  • 打开应用级的 build.gradle 文件,在 dependencies 中添加如下编译依赖。

    dependencies {
    implementation 'com.hihonor.mcs:push:7.0.41.301'
    }
  • 在 android 中配置签名。将生成签名证书指纹步骤中生成的签名文件拷贝到工程的 app 目录下,在 build.gradle 文件中配置签名:

    android {
    signingConfigs {
    config {
    keyAlias 'pushdemo'
    keyPassword '123456789'
    storeFile file('demo.keystore')
    storePassword '123456789'
    }
    }

    buildTypes {
    debug {
    signingConfig signingConfigs.config
    }
    release {
    signingConfig signingConfigs.config
    minifyEnabled false
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    }
    }

做完这些修改后,Android Studio 右上方出现 Sync Now 链接。点击 Sync Now 等待同步完成。

修改应用 manifest 配置​

首先导入 mixpush-honor 包,修改 build.gradle 文件,在 dependencies 中添加依赖:

dependencies {
//混合推送需要的包
implementation 'cn.leancloud:mixpush-honor:8.2.28'
//即时通信与推送需要的包
implementation 'cn.leancloud:realtime-android:8.2.28'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

implementation 'com.hihonor.mcs:push:7.0.41.301'
}

如果希望一次性接入所有厂商推送,可以将 mixpush-honor 替换为 mixpush-android。

然后配置相关 AndroidManifest,添加 Permission(开发者要将其中的 <包名> 替换为自己的应用的包名):

<!-- 需要网络权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 检测网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

集成最新的荣耀 Push SDK 版本后要在 AndroidManifest.xml 文件的 application 节点下参照以下步骤注册 service,用于接收荣耀推送的消息与令牌。

<application
<service
android:name="cn.leancloud.LCHonorMessageService"
android:exported="false">
<intent-filter>
<action android:name="com.hihonor.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>

配置 AppId 信息:需要同样在 AndroidManifest.xml 文件下,添加 meta-data 标签,并在 com.hihonor.push.app_id 下添加 AppId(AppId 在注册完成后获取)。

<manifest>
<application>
<meta-data
android:name="com.hihonor.push.app_id"
android:value="您的 AppId" />
</application>
</manifest>

初始化​

与其他推送的初始化方法一样,在 Application#onCreate 方法中进行荣耀推送的初始化:

import cn.leancloud.LeanCloud;
import cn.leancloud.honor.LCMixPushManager; // 使用 mixpush-honor 的场合
import cn.leancloud.LCMixPushManager; // 使用 mixpush-android 的场合

// Customized Application.
public class MyApp extends Application {
// 请替换成你自己的 appId 和 appKey
private static final String LC_APP_ID = "xxx";
private static final String LC_APP_KEY = "xxx";


@Override
public void onCreate() {
super.onCreate();

//开启调试日志
LeanCloud.setLogLevel(LCLogger.Level.DEBUG);

// LeanCloud SDK 初始化
LeanCloud.initialize(this, "{{appid}}", "{{appkey}}", "https://please-replace-with-your-customized.domain.com");

// 荣耀推送初始化
// 使用 mixpush-android 的场合,引用 cn.leancloud.LCMixPushManager
// 使用 mixpush-honor 的场合,引用 cn.leancloud.honor.LCMixPushManager
LCMixPushManager.registerHonorPush(this);
}
}

点击通知打开自定义页面​

您可以自定义处理点击通知栏消息通知的动作,包括:打开应用首页、打开特定 URL 和打开自定义页面。

打开应用自定义页面有两种方式,一种是通过服务端 API 指定 intent 参数,另一种是指定 action 参数,混合推送 SDK 选择使用 intent 参数(具体可参考荣耀文档 服务端发送 push 消息 ),开发者也可以在发送请求时自行指定 action 参数(按照荣耀的 REST API 规范指定即可)。

对于目标 activity,开发者需要在 manifest 文件的 application 中增加 intent-filter 的定义,例如:

<!-- (可选)开发者自定义的打开推送消息的目的 activity。-->
<activity
android:name="您的自定义 Activity 路径"
android:exported="false">

<!-- intent 参数配置示例 -->

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="lcpushscheme"
android:host="cn.leancloud.push"
android:path="/notify_detail"/>
</intent-filter>

<!-- action 参数配置示例 -->

<intent-filter>
<action android:name="com.tds.android.demo.activity.second.action" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

荣耀推送测试​

荣耀推送在每日单设备推送数量上有一些限制(和华为推送类似)。

所以在单设备测试荣耀推送时,需要添加一个参数用来标识此次推送是测试推送,测试推送不受每日单设备推送数量上限要求,详细信息可见荣耀官方文档的 targetUserType 参数;当设置 targetUserType 参数为 1 时,即表明此次推送为测试推送。

荣耀测试推送也存在一些限制,如下:

  • 每个应用每日可发送该测试消息 1000 条
  • 单次推送不能超过 10 台设备

可以在推送的 data 中加入 targetUserType 参数,样例如下:

{
"alert" : "Hello",
"honor" : {
"targetUserType" : 1
}
}

注意:请不要在正式推送中使用 targetUserType 参数。

取消混合推送注册​

对于已经注册了混合推送的用户,如果想取消混合推送的注册而改走云服务自有的 WebSocket 的话,可以调用如下函数:

LCMixPushManager.unRegisterMixPush();

此函数为异步函数,如果取消成功会有 Registration canceled successfully 的日志输出,万一取消注册失败的话会有类似 unRegisterMixPush error 的日志输出。

错误排查建议​

  • 只要注册时有条件不符合,SDK 会在日志中输出导致注册失败的原因,例如 register error, mainifest is incomplete 代表 manifest 未正确填写。如果注册成功,_Installation 表中的相关记录应该具有 vendor 这个字段并且不为空值。

  • 如果注册一直失败的话,请提交工单或去论坛发帖,提供相关日志、具体机型以及系统版本号,我们会跟进协助来排查。

  • 查看魅族机型的设置,并打开「信任此应用」、「开机自启动」、「自启动管理」和「权限管理」等相关选项。