第三方推送集成


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推送集成

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

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 通用错误码及处理方式


华为老版本推送集成

注意:华为EMUI4.0 需要把app 自动启动权限打开才能收到推送。

需求

为了在华为设备上当app被kill后还能继续收到消息

设置华为推送证书

进入[http://developer.huawei.com/cn/consumer/devunion/openPlatform/html/memberCenter.html#appManage#|华为开发者后台]],创建一个应用,完成后配置push权益。创建完成后,会自动生成的APP ID及APP SECRET,进入环信管理后台,选择你的应用—>选择推送证书—>Huawei—>新增证书。

证书名称为刚从华为后台拿到的 APP ID,证书密钥为 APP SECRET,点击上传即可。

客户端配置

华为推送所需要的jar包已经放到easeui的libs目录下:HwPush_SDK_V2705_nomap.jar,因为demo用到了百度地图,和华为push的地图模块冲突(两者都是用的百度地图),这里的push jar包移除了map模块,需要的开发者可以去华为后台自行下载

在 AndroidManifest.xml 中配置权限及相应 service 声明等。

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

<manifest>
     ...     
	<application>
	...
<receiver android:name="com.hyphenate.chat.EMHuaweiPushReceiver" >
            <intent-filter>
                <!--必须,用于接收token-->
                <action android:name="com.huawei.android.push.intent.REGISTRATION" />
                <!--必须,用于接收消息-->
                <action android:name="com.huawei.android.push.intent.RECEIVE" />
            </intent-filter>
            <meta-data android:name="CS_cloud_ablitity" android:value="successRateAnalytics"/>
        </receiver>

     	<!--PushSDK:PushSDK接收外部请求事件入口-->
        <receiver
            android:name="com.huawei.android.pushagent.PushEventReceiver"
            android:process=":pushservice" >
            <intent-filter>
                <action android:name="com.huawei.android.push.intent.REFRESH_PUSH_CHANNEL" />
                <action android:name="com.huawei.intent.action.PUSH" />
                <action android:name="com.huawei.intent.action.PUSH_ON" />
                <action android:name="com.huawei.android.push.PLUGIN" />
            </intent-filter>
        </receiver>
         <!-- PushSDK:Push服务 -->
        <service
            android:name="com.huawei.android.pushagent.PushService"
            android:process=":pushservice" >
        </service>
	...
	</application>
</mainfest>

代码设置

在初始化 SDK 前设置到 options 里options.setHuaweiPushAppId(appId)

Logout 时调用EMClient.getInstance().logout(true,callback)

推送的配置选项

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

发送静默消息(不推送)

(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 文档