怀着谦卑和感恩的心情写下本文,希望对大家能有所帮助,没有什么技术含量,只是记录下自己踩过的坑,有问题请指教。
写作的原因有二:
1. 华为推送sdk的文档写得不好并且分散是不争的事实,值得吐槽的是这不是大厂作风,同样是push sdk,这点需要向小米和魅族学习。我也是东拼西凑看了好多个地方的文档,包括sdk中的指导书以及开发者联盟,然后自己和同事不断地尝试以及踩坑才最终较为完美的接入了华为HMS。我自己身在华为开发者群中,看到群主MM每天由于文档不完善这个大坑各种给大家解答,十分无奈,希望下次再有人在群里问一些常见问题的时候,群主只需将这篇文章贴出来即可。
2. 无论如何还是要感激华为免费(至少目前)为我们在华为手机上提供了类似APNs在iOS的推送服务。感激我在接入各家推送服务过程中社区给予我的帮助,这篇文章算是一种回馈。
废话到此,进入正题。
一、背景
公司的push系统采用的是N+1的方式,即N家厂商通道+1家第三方推送的方式。华为、小米和魅族手机使用它们的系统通道,其他手机使用一家第三方推送。所以对于华为推送,我们只在华为手机上使用。
二、目的
期望在我们的用户中,使用华为推送的手机不论app是否存活都能收到通知栏消息,并且不需要引导用户开启自启动权限就能捕获点击通知栏的事件进行自定义处理。 这也是接入华为推送服务的意义所在。
三、选型
1. 我接入的HMS版本为2.4.0.300,选择HMS而不是push sdk的原因是老版的push sdk官方已经不再维护,以及hms的体积只有200K出头。
2. 只使用通知栏消息,而不使用透传。在华为手机上使用华为的透传消息与第三方推送一样需要app存活,因此使用透传消息没有意义。所以劝打算使用透传消息的朋友打消这个念头。华为推送的通知栏消息在EMUI上就如同APNs在iOS的效果,因为通知直接由系统弹出,所以不论app是否存活消息都可达。然而通过官方的说明以及经过我和同事的一系列测试发现通知栏消息并不是所有的华为手机都能到达,需要满足一定的条件:1. emuiApiLevel > 9;2. 华为移动服务版本>=2.4.1.300。不满足这个条件的华为手机我们仍然使用第三方推送。
3. 服务端调用接口发送通知栏消息,参数设置为app自定义打开方式。
四、客户端接入参照开发指导书即可
五、服务端接入
前面提到,我们采用通知栏消息以及自定义打开方式,直接上代码:
- OAuth2Client oauth2Client = new OAuth2Client();
- oauth2Client.initKeyStoreStream(HuaweiPushService.class.getResource("/mykeystorebj.jks").openStream(), "123456"); // jks文件直接使用sdk里的即可,密码固定为123456
- AccessToken accessToken = oauth2Client.getAccessToken("client_credentials", "appId", "appSecret");
- System.out.println("access token: " + accessToken.getAccess_token() + " expires in " + accessToken.getExpires_in());
- NSPClient client = new NSPClient(accessToken.getAccess_token());
- client.initHttpConnections(30, 50);
- client.initKeyStoreStream(HuaweiPushService.class.getResource("/mykeystorebj.jks").openStream(), "123456");
- client.setTimeout(10000, 15000);
- Map<String, Object> params = new HashMap<>();
- String[] tokens = {"token"};
- params.put("cacheMode", 1);
- params.put("msgType", -1);
- params.put("deviceTokenList", tokens);
- params.put("android", "{"notification_title":"title","intent":"intent:#Intent;launchFlags=0x10000000;component=com.xxx.xxx/.MainActivity;i.age=18;S.name=zhang;end","notification_content":"content","doings":2}"); // intent由代码生成,具体请参考Q&A第3条
- params.put("expire_time", new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date(System.currentTimeMillis() + 3600 * 1000)));
- PushRet rsp = client.call("openpush.message.psBatchSend", params, PushRet.class);
- System.out.println("通知栏消息接口响应:" + rsp);
六、客户端处理自定义事件
由于app杀死以后点击push不会回调onEvent(因为广播被系统限制了),所以自定义动作的处理我们统一用intent来实现。参数传递依赖android结构体中的intent参数。intent中处理消息的组件只能是activity,不能是service或receiver。于是这时处理自定义事件的方式变为在指定activity的onCreate方法中调用getIntent()来获取服务端要传的参数进行处理。有的朋友说,我kill掉app后点击通知还能回调onEvent,那是因为你给app开了自启动权限。
七、其他Q&A
1. Q: 如何切换测试环境和正式环境?
A: 每次修改华为后台的sha256的指纹后执行如下步骤:1. 删除app;2. 清空华为移动服务的数据;3. 重装新指纹对应的app。不生效的话重复重新保存指纹,重复上述步骤。
2. Q: 如何生成intent参数?
A: 代码如下
A: 代码如下
- Intent intent = new Intent();
- intent.setClass(MainActivity.this,MainActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra("name", “zhangsan");
- intent.putExtra("age", 18);
- String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);
3. Q: 客户端连接时返回6003?
A: 后台配置的指纹与app对不上
A: 后台配置的指纹与app对不上
4. Q:客户端连接是返回907135702?
A: 没有在后台配置指纹
A: 没有在后台配置指纹
5. Q: 配置了指纹还是返回907135702?
A: 参照2的步骤
6. Q: 客户端返回错误码2
A: 华为移动服务版本太低,升级一下即可
A: 华为移动服务版本太低,升级一下即可
7. Q: app能否感知消息到达?
A: 不行。通知栏消息直接由系统弹出。
8. Q: 如何判断获取emuiApiLevel?
A: 代码如下:
- int emuiApiLevel = 0;
- try {
- Class cls = Class.forName("android.os.SystemProperties");
- Method method = cls.getDeclaredMethod("get", new Class[]{String.class});
- emuiApiLevel = Integer.parseInt((String) method.invoke(cls, new Object[]{"ro.build.hw_emui_api_level"}));
- } catch (Exception e) {
- e.printStackTrace();
- }
判断emuiApiLevel>9即可。
9. Q: 如何判断华为移动服务版本>=2.4.1.300?
A: 代码如下:
- PackageInfo pi = null;
- PackageManager pm = context.getPackageManager();
- int hwid = 0;
- try {
- pi = pm.getPackageInfo("com.huawei.hwid", 0);
- if (pi != null) {
- result = pi.versionCode;
- }
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
判断hwid>=20401300即可。
10. Q: 华为通知栏消息的声音、样式以及app在前台是否展示这些点是否可以自定义?
A: 通通不行,华为通知栏消息的样式只能是系统默认。









































苏公安网备 32011402010933号