融云即时通讯SDK集成 -- 华为推送的点击跳转处理
1.背景:
最近公司新上的app要加上即时通讯的功能, 自己快速实现一个当然是不可能的了(项目deadline也顶不住哇).就从各家成熟的SDK厂商选来选去的, 各有各的好也各有各的不足.最后点兵点将,选了融云家的SDK(老板说了算hhhh).
他家的官网和文档地址:
官网:https://www.rongcloud.cn/
文档:https://docs.rongcloud.cn/v4
这个任务当然还是落在我的头上. 基础的IM聊天, 群组聊天等功能集成在另一篇博客中已经讲过, 这里就先不说了. 之前的一篇文章已经讲过, 这篇文章重点讲下华为推送过来的通知栏点击事件, 这小小的一件事, 可耗费了不少的精力.
2. 融云家SDK接入厂商推送指南
这个他家讲的挺清楚了, 都近似手把手的教了, 那我也就不在这浪费键盘寿命了(偷个懒hhhhh).给他家官方文档往这儿一贴好了: https://docs.rongcloud.cn/v4/views/im/ui/guide/private/notify/push/mi.html. 大家注意一下他家华为厂商推送的文档分2.x和4.x哈, 对应的是他家旧版/新版SDK中接入的厂商的新/旧版本推送包.我这里之前是踩过坑的, 推荐大家还是用他家的4.x的sdk包集成, 里边集成的是华为新版本的推送包. 因为华为已经在逐渐弃用旧版本的推送包了, 所以不想以后麻烦再迭代的话, 还是直接上新版本比较好, 因为现在已经有接入旧版本包的app在某些低版本华为Rom上收不到推送了, 还是谨慎一点比较好.
3. 华为推送通知点击跳转自定义
这里我们所指的跳转是, 点击通知栏到达的华为推送通知后, 调起我们的app, 跳到相应的Activity的. 因为我们做的是即时通讯App, 所以点击别人发来的消息推送通知后, 当然是跳到和该用户聊天的会话页面, 但就是这样一个小业务, 实现起来还真有点麻烦. 所以这里也算是给大家踩踩坑啦.
首先是点击跳转的逻辑, 通过和融云技术支持联系以及查看他们sdk的代码, 得知他们的推送都是走了一个叫PushMessageReceiver的类, 开发者可以注册并继承该类, 重写onNotificationMessageClicked()方法, 显而易见这就是对通知消息的监听. 可这也是第一个坑, 华为因为平台的限制, 推送通知的点击事件根本不走这里. 准确的说是华为和Oppo都因为各自平台的限制, 不走这里. 所以当我兴致勃勃重写了这个方法准备一次通过的时候, 点击后直接走到了会话列表界面, 而非会话界面.
这是因为华为平台点击跳转是需要配一个intent, 在融云的后台, 如图所示:
这里的intent即为通知栏点击跳转后的隐式启动相应activity的那个intent.
获取某Activity相应intent的代码, 可把intent给打到log中:
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("wonderfullpush://com.wonderfull.android.push/notification?action=your parameter"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
String intnetUri = intent.toUri(Intent.URI_INTENT_SCHEME);
Log.d("hwpush", "intnetUri=" + intnetUri);
生成的intent大概是这样的格式:
intent://com.wonderfull.android.push/notification?action=$action#Intent;scheme=wonderfullpush;action=android.intent.action.VIEW;launchFlags=0x10000000;end
不过这块还有坑, 还不能直接把装会话界面的activity的intent直接写在这里, 因为这个会话界面去的究竟是哪个对话者的界面, 相应userId的参数是传不到的. 在这里我尝试获取过intent里边的数据, 是空的.
和融云的技术支持团队确认后, 找到了解决方案. 只有intent走到入口类, 才能拿的到通知里携带的数据, 我app的闪屏页, 也就是SplashActivity, 在融云后台把自定义点击跳转intent配成SplashActivity的. 然后在这里把intent的数据拿到, 再一次调用融云的接口跳转到相应的会话界面就OK了.
等拿到这个intent的后, 又是来了一点点小麻烦. 根据融云的文档, 我在入口Activity(闪屏页, SplashActivity)这里接收到了intent, 从intent里边取相应的数据:
这个intent中给的数据包含了转义符:
{"rc":"{\"conversationType\":\"1\",\"targetId\":\"userid8\",\"sourceType\":\"0\",\"fromUserId\":\"userid8\",\"objectName\":\"RC:TxtMsg\",\"id\":\"BLCG-G8TC-U7E6-KV7P\",\"tId\":\"doctorid3\"}"}
String jsonStr = "{\"rc\":\"{\\\"conversationType\\\":\\\"1\\\",\\\"targetId\\\":\\\"userid8\\\",\\\"sourceType\\\":\\\"0\\\",\\\"fromUserId\\\":\\\"userid8\\\",\\\"objectName\\\":\\\"RC:TxtMsg\\\",\\\"id\\\":\\\"BLCG-G8TC-U7E6-KV7P\\\",\\\"tId\\\":\\\"doctorid3\\\"}\"}";
String fixStr1 = jsonStr.replace("\\", "");
String fixStr2 = fixStr1.replace("\"rc\":\"", "\"rc\":" );
String result = fixStr2.replace("\"}\"", "\"}");
Log.d(TAG, "result jsonStr: "+ result);
JSONObject jsonObject;
try {
jsonObject = new JSONObject(result);
String options = jsonObject.getString("rc");
JsonObject object = (JsonObject) new JsonParser().parse(options);
String targetId = object.getAsJsonObject().get("targetId").getAsString();
Log.d(TAG, "analyse json targetId: " + targetId);
} catch (JSONException e) {
e.printStackTrace();
}
我选择了自行处理字符串, 拿到了相应的targetId, 从我的闪屏页跳转到相应的会话界面去. 这样需求就搞定了.