1. 程式人生 > >Android 整合華為推送

Android 整合華為推送

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失效

如果你有任何疑問,先順著這個思路看下去,不知不覺避免了好幾個坑

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、應用殺死狀態下這個方法無論如何都不會觸發