第三方推送集成


Google 推送集成

必备条件

  • GCM 使用针对于国外用户;
  • GCM 要求设备安装有 Google Play 服务和 Google Play 商店。

设置环信 Android 推送证书

第 1 步:登录Google 开发平台,Create a project…,创建你的应用名称,应用 ID(ID系统会随机为你分配一个唯一的值,也可以手动填写)。

创建应用

第 2 步:创建成功得到一个对应的 project number。

获得project number

第 3 步:点击左侧 Credentials —create service key,得到 API key。

获得API key

在环信管理后台配置证书

登录环信管理后台,选择你的应用—选择推送证书—新增证书,证书的名称要求填写从 Google 后台创建项目生成的 project number,证书秘钥为创建 server key 生成的 API key。

在环信管理后台配置证书

Android 客户端代码配置

在 AndroidManifest.xml 配置。

注意:把 Demo 的包名 com.hyphenate.chatuidemo 替换成你自己项目的。

<manifest>
	...
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <permission 
        android:name="com.hyphenate.chatuidemo.permission.C2D_MESSAGE"
        android:protectionLevel="signature"
        />
    <uses-permission android:name="com.hyphenate.chatuidemo.permission.C2D_MESSAGE" />
	
	<application>
		...
		<receiver
            android:name="com.hyphenate.chat.EMGCMBroadcastReceiver"
            android:exported="true"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="com.hyphenate.chatuidemo" />
            </intent-filter>
        </receiver>

        <service android:name="com.hyphenate.chat.EMGCMListenerService"
            android:exported="false" >
        </service>
        
        <receiver 
            android:name="com.hyphenate.chatuidemo.receiver.GCMPushBroadCast"
            android:exported="false">
            <intent-filter >
                <action android:name="com.hyphenate.sdk.push"/>
                <category android:name="com.hyphenate.chatuidemo"/>
            </intent-filter>
        </receiver>
		...
	</application>
</mainfest>

代码设置

  • project number(Google 开发平台创建项目生成的)在初始化 SDK 前设置到 options 里options.setGCMNumber(projectNumber);
  • 使用 GCM 时需要在退出登录时解绑设备 token,调用EMClient.getInstance().logout(true)或者EMClient.getInstance().logout(true,callback)方法,如果是被踢的情况下,则要求设置为 false。

华为HMS推送集成

SDK3.4.0.1华为推送重大更新

为了方便用户自己升级华为推送相关sdk,环信 SDK 在3.4.0.1之后的版本中将华为推送相关从 IM SDK 中移除,同时提供对应的上传推送token接口供开发者调用,以后的版本就需要开发者自己去集成华为推送相关功能,然后调用下边的方法将 token 发送到环信服务器:

// 上传 token 方法
EMClient.getInstance().sendHMSPushTokenToServer("华为appId", "注册华为的 token");

这是华为官方集成文档,开发者可以自己根据华为官方文档进行集成华为推送 华为消息推送服务集成官方文档

环信 IM 的 Demo也已经集成了华为最新推送 SDK,开发者也可以参考 demo 进行集成

Demo 中将华为的 HMSAgent 做成了一个 module 进行引用(这里没有对华为 HMSAgent 进行任何封装和修改),开发者可以直接进行使用,也可以直接下载华为官方最新的HMSAgent自己进行集成

Demo在集成华为推送时将调用华为推送的几个方法都放在了HMSPushHelper类中,开发者可以进行参考使用


SDK3.4.0及之前的集成

环信 SDK 在3.3.4版本开始支持华为 HMS 推送服务,开发者从3.3.4之前升级并且之前集成了华为推送,然后按照下面的说明重新集成 HMS 推送服务;

PS:现在华为官方已经不支持老版本推送,因此这里边不提供老版本集成说明,使用3.3.4之前的版本 sdk的开发者进款升级环信 sdk 到最新版

PS:集成时需要删除之前的华为jar包和推送代码,并下载新版HMS SDK引用到自己的项目中,其中BasePush两个库是必须的,其他的可以参考华为官方介绍自己决定是否添加

创建华为应用

首先就是去华为开发者后台创建应用,并开启 push 服务,并上传对应的证书指纹,具体可以看下华为官方介绍: 华为HMS消息推送服务集成

上传推送证书

注册完整后,需要在环信开发者后台上传推送证书,选择你的应用—>推送证书—>Huawei—>新增证书,然后输入你在华为开发者后台创建的应用的APPIDAPP SECRET以及程序的包名

客户端配置 HMS

然后SDK 这里对 HMS 注册华为推送 token 进行了封装,集成时还是比较简单的,只需要在 AndroidManifest.xml 配置文件配置相关广播接收器和服务等: 记得设置自己的在华为开发者后台创建的应用的APP ID

PS:在自己实现广播接收器的时候必须继承自环信封装的那个广播接收器com.hyphenate.chat.EMHWPushReceiver,否则收不到环信的离线推送

<!--华为 HMS Config-->
        <!--华为开发者后台创建的应用的 APP ID-->
        <meta-data
            android:name="com.huawei.hms.client.appid"
            android:value="华为应用 APP ID" />
        <!--华为推送广播接收器,可以直接使用环信 sdk 封装好的,也可以继承自环信重写,如果继承自环信,实现 onToken 方法时必须要调用 super 方法-->
        <receiver android:name="com.hyphenate.chat.EMHWPushReceiver">
            <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>
        <!-- huawei push end -->

配置完这些之后,在满足条件的华为设备上就可以使用华为推送接收离线推送通知了; 这里的满足条件是指:华为设备必须安装2.4.+以上的华为移动服务,以及开启当前 app 的自启动权限

故障排查

当开发者做完这些之后如果在华为设备上还是收不到推送,可以看下控制台的输出,或者环信 sdcard 上保存的日志,是否有一下日志输出:

// 当设备的华为移动服务版本比较低的时候,无法启用华为推送,会有以下输出
D/ONE SDK: [EMPushHelper] huawei mobile services is not available. please upgrade
// 当注册 token 时,华为开发者后台证书不对应,或者没有开通 Push 服务,当所有的都确认没问题后,如果还是有这样的问题,这个需要联系华为技术支持查看下是否生效
D/ONE SDK: hms service connection suspended. error: 6xxx 或 9xxxxxxxx

后边的 error 为华为官方错误码,更多错误码请参考华为官方错误表:表3-1 HMS 通用错误码及处理方式


推送的配置选项

用户可以在消息扩展中增加特定的字段来实现消息的推送配置。

发送静默消息(不推送)

(Android 发消息)

EMMessage message = EMMessage.createSendMessage(EMMessage.Type.TXT);
EMTextMessageBody txtBody = new EMTextMessageBody("test");
message.setTo("6006");
// 设置自定义扩展字段
message.setAttribute("em_ignore_notification", true);
// 设置消息回调
message.setMessageStatusCallback(new EMCallBack() {...});
// 发送消息
EMClient.getInstance().chatManager().sendMessage(message);

强制推送

(Android 发消息)

EMMessage message = EMMessage.createSendMessage(EMMessage.Type.TXT);
EMTextMessageBody txtBody = new EMTextMessageBody("test");
message.setTo("6006");
// 设置自定义扩展字段
message.setAttribute("em_force_notification", true);
// 设置消息回调
message.setMessageStatusCallback(new EMCallBack() {...});
// 发送消息
EMClient.getInstance().chatManager().sendMessage(message);

自定义推送提示

(Android 发消息)

// 这里只是一 TXT 消息为例,IMAGE FILE 等类型的消息设置方法相同
EMMessage message = EMMessage.createSendMessage(EMMessage.Type.TXT);
EMTextMessageBody txtBody = new EMTextMessageBody("消息内容");
message.setTo("6006");
// 设置自定义推送提示
JSONObject extObject = new JSONObject();
try {
    extObject.put("em_push_name", "离线推送标题");
    extObject.put("em_push_content", "离线推送内容部分");
} catch (JSONException e) {
    e.printStackTrace();
}
// 将推送扩展设置到消息中
message.setAttribute("em_apns_ext", extObject);
// 设置消息回调
message.setMessageStatusCallback(new EMCallBack() {...});
// 发送消息
EMClient.getInstance().chatManager().sendMessage(message);

另外,GCM 推送可以在 “em_apns_ext” 中传入 “collapseKey”、“timeToLive”来控制推送的相关属性,详见 GCM 文档