Android 集成华为推送

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28978893/article/details/80684448

Android的推送业务现状还是比较混乱,手机厂商各有一套推送机制和SDK需要你去集成,今天先谈一谈华为的推送服务集成吧

集成背景:React Native项目,已经集成了一套JPush,但是目前相当一部分Android机型极光推送在应用杀掉之后是不能唤醒的,Android和Apple平分秋色,客户有需求,就着手集成吧,集成路线 华为 =》小米 => 其他厂商

我先把集成正确的思路和流程梳理一下,遇到的坑最后再说

1、先晒一下SDK文档这里写链接内容

首先肯定是connect到华为的服务

HuaweiApiClient client = new HuaweiApiClient.Builder(this)
  .addApi(HuaweiPush.PUSH_API)
  .addConnectionCallbacks(this)
  .addOnConnectionFailedListener(this)
  .build();
MixPushMoudle.pushManager = new HuaweiPushManager(client, ${appId}, ${appSecret});
client.connect();

最重要的是获取到当前设备(用户)的deviceToken,其他平台也叫ClientId,其实是用户的唯一标志,好的一点是deviceToken会在connect之后主动帮我们获取,我们可以通过重写PushReceiver的onToken获取

@Override
public void onToken(Context context, String token, Bundle extras) {
   Log.i(TAG, "HUAWEI获取到deviceToken:" + token);
   //延时1秒后再发送事件,防止RN客户端还未初始化完成时在注册前就发送了事件
   final String stoken = token;
}

另外我们也可以采用一种主动的获取deviceToken的方式

public void requestDeviceToken(Context context) {
    PendingResult<TokenResult> tokenResult = HuaweiPush.HuaweiPushApi.getToken(client);
    tokenResult.setResultCallback(new ResultCallback<TokenResult>() {
        @Override
        public void onResult(TokenResult tokenResult) {
            if (tokenResult.getTokenRes().getRetCode() == 0) {
                Log.i(TAG, "HUAWEI获取deviceToken成功");
            } else {
                Log.i(TAG, "HUAWEI获取deviceToken成功");
            }
        }
    });
}

当然这种方式在回调中只会获取 状态,具体的值还需要在onToken中获取

2、在你的服务端推送集成服务没有建立好的时候你借助华为推送后台进行推送测试,基本的参数我就不介绍了,这里我只讲三点

这里写图片描述

a、点击通知的类型有三种,随便选,本案例只讲“打开应用”选项;
b、后续行为我们选择“自定义动作”,不管你是哪种需求,只要你想唤醒已经杀掉的应用,选它就对了;
c、效果测试是你在配置完通知内容之后的测试,你可以拿着这些参数多次在测试机上查看推送效果,直到你界面的cookie失效

扫描二维码关注公众号,回复: 3592347 查看本文章

如果你有任何疑问,先顺着这个思路看下去,不知不觉避免了好几个坑

3、推送参数配置完成之后我们可以在真机上测试了,我的设备是Honor 6X,标准的测试机配置,推送正常到达之后会在通知栏显示,我们之所以能针对推送内容在应用内外部做出一些操作,是因为在点击操作栏信息的时候触发了事件监听,获取到了我们在后台配置的参数,那究竟如何获取呢?

a、信息是如果拼接起来的放进推送里面的,自定义行为的intentUri又包含了哪些信息,分别是什么含义?

private void getMixPushIntentUri() {

    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("scheme://com.healscitech.bluesprucehealth/mixpush_extras"));
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra("action", "webPage");
    intent.putExtra("webPage", "{\"url\":\"https://hm.healscitech.com/questionWeatherListControl\"}");
    String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);
    Log.e("MainActivity", "action是:" + intentUri);
    //MixPush 后台自定义操作  intent://com.healscitech.bluesprucehealth/mixpush_extras#Intent;scheme=scheme;launchFlags=0x10000000;S.action=webPage;S.webPage=%7B%22url%22%3A%22https%3A%2F%2Fhm.healscitech.com%2FquestionWeatherListControl%22%7D;end
}

仔细分析的话,这个intentUri包含了两部分信息
uri
这个参数和我们想要跳转的Activity有直接关联,是这个Activity的Intent-filter的部分参数拼接起来的
这里写图片描述
上图之后是不是一目了然
bundle
这个Bundle里面存放一切我们想传递给客户端的信息

b、这些信息的获取也很简单,Inetnt到我们想要处理的Activity之后我们通过getIntent获取就是了

public void checkMixPushEvent() {
    Intent intent = getIntent();
    Bundle bundle = intent.getExtras();
    // 如果App是开启状态,则不会走OnCreate,会触发onEvent
    if (bundle != null) {
        Log.e(Tag, "MixPush接收到推送消息栏点击事件");
        final String content = convertBundleToJson(bundle);
        // 重新初始化 Intent, 避免重复触发
        intent = new Intent();
    }
}

获取到信息之后你想怎么处理都OK,那如果你想拿这部分信息和JS进行交互,在这里给你提供一个转化的方法

private String convertBundleToJson(Bundle bundle) {

    JSONObject jsonObject = new JSONObject();

    for (String key : bundle.keySet()) {
        Object obj = bundle.get(key);
        try {
            jsonObject.put(key, wrap(bundle.get(key)));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    return jsonObject.toString();
}

c、最重要的一点是通过Intent获取推送信息的方法在目标Activity
的哪个声明周期调用最为合适呢,我们来分析一下应用在运行中、杀死状态下Activity七个生命周期的调用情况

杀死状态下,Activity从OnCreate开始
运行中,Activity从OnPause,所以我们就把调用放在了onResume这个阶段

顺利避开了所有的坑

那我们走别的路会遇到哪些坑呢?

onEvent方法不触发

原因

1、后续行为你选择了“直接打开应用”,然后自定义内容里面没有至少一对{ key, value}

2、应用杀死状态下这个方法无论如何都不会触发

猜你喜欢

转载自blog.csdn.net/qq_28978893/article/details/80684448