手把手教你集成阿里雲推送(app殺死仍可推送)

做手機控車項目,需求是車在遭受非法侵入的時候要及時報警,之前是用短信的方式,一開始量少還可以,隨着用戶越來越多,短信的開銷越來越大,決定做成推送方式,這就要求客戶一定能夠收到推送,無論後臺進程是否被殺死.

首先登陸阿里雲官方平臺,創建應用 阿里雲創建應用

然後就是下載各種包配置應用,有maven庫快速集成方式,但我不知道爲什麼下載不下來,所以還是選擇了手動配置,以下是用到的包

配置appkey和appsecret(創建應用時候生成的)

    <application android:name="*****">
        <meta-data android:name="com.alibaba.app.appkey" android:value="*****"/> <!-- 請填寫你自己的- appKey -->
        <meta-data android:name="com.alibaba.app.appsecret" android:value="****"/> <!-- 請填寫你自己的appSecret -->
    </application>

清單文件裏增加權限和註冊service和receiver

手動創建消息接收Receiver,繼承自com.alibaba.sdk.android.push.MessageReceiver,並在對應回調中添加業務處理邏輯

    public class MyMessageReceiver extends MessageReceiver {
        // 消息接收部分的LOG_TAG
        public static final String REC_TAG = "receiver";
        @Override
        public void onNotification(Context context, String title, String summary, Map<String, String> extraMap) {
            // TODO 處理推送通知
            Log.e("MyMessageReceiver", "Receive notification, title: " + title + ", summary: " + summary + ", extraMap: " + extraMap);
        }
        @Override
        public void onMessage(Context context, CPushMessage cPushMessage) {
                Log.e("MyMessageReceiver", "onMessage, messageId: " + cPushMessage.getMessageId() + ", title: " + cPushMessage.getTitle() + ", content:" + cPushMessage.getContent());
        }
        @Override
        public void onNotificationOpened(Context context, String title, String summary, String extraMap) {
            Log.e("MyMessageReceiver", "onNotificationOpened, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
        }
        @Override
        protected void onNotificationClickedWithNoAction(Context context, String title, String summary, String extraMap) {
            Log.e("MyMessageReceiver", "onNotificationClickedWithNoAction, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
        }
        @Override
        protected void onNotificationReceivedInApp(Context context, String title, String summary, Map<String, String> extraMap, int openType, String openActivity, String openUrl) {
            Log.e("MyMessageReceiver", "onNotificationReceivedInApp, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap + ", openType:" + openType + ", openActivity:" + openActivity + ", openUrl:" + openUrl);
        }
        @Override
        protected void onNotificationRemoved(Context context, String messageId) {
            Log.e("MyMessageReceiver", "onNotificationRemoved");
        }
    }

並在清單文件中配置該receiver

    <!-- 消息接收監聽器 (用戶可自主擴展) -->
    <receiver
        android:name=".MyMessageReceiver"
        android:exported="false"> <!-- 爲保證receiver安全,建議設置不可導出,如需對其他應用開放可通過android:permission進行限制 -->
        <intent-filter>
            <action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.alibaba.sdk.android.push.RECEIVE" />
        </intent-filter>
    </receiver>

然後官方文檔裏有這樣一句提示

如果是從V2.3.7及以下版本升級到V3.0.0及以上版本的用戶,需將<action android:name="org.agoo.android.intent.action.RECEIVE" />改爲<action android:name="com.alibaba.sdk.android.push.RECEIVE" />,否則會接收不到推送。

雖然我不是這樣的用戶,但還是做了修改

然後再application裏初始化推送通道(此處考慮了8.0以上限制推送的情況:即定義了一個通知渠道的id)

/**
     * 初始化雲推送通道
     * @param applicationContext
     */
    private void initCloudChannel(Context applicationContext) {


        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
            // 通知渠道的id
            String id = "1";
            // 用戶可以看到的通知渠道的名字.
            CharSequence name = "notification channel";
            // 用戶可以看到的通知渠道的描述
            String description = "notification description";
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel mChannel = new NotificationChannel(id, name, importance);


//            // 設置渠道描述
//            mChannel.setDescription("測試通知組");
//            // 是否繞過請勿打擾模式
            mChannel.canBypassDnd();
//            // 設置繞過請勿打擾模式
            mChannel.setBypassDnd(true);
//            // 桌面Launcher的消息角標
            mChannel.canShowBadge();
//            // 設置顯示桌面Launcher的消息角標
            mChannel.setShowBadge(true);
//            // 設置通知出現時聲音,默認通知是有聲音的
//            mChannel.setSound(null, null);
//            // 設置通知出現時的閃燈(如果 android 設備支持的話)
//            mChannel.enableLights(true);
//            mChannel.setLightColor(Color.RED);
//            // 設置通知出現時的震動(如果 android 設備支持的話)
//            mChannel.enableVibration(true);


            // 配置通知渠道的屬性
            mChannel.setDescription(description);
            // 設置通知出現時的閃燈(如果 android 設備支持的話)
            mChannel.enableLights(true);
            mChannel.setLightColor(Color.RED);
            // 設置通知出現時的震動(如果 android 設備支持的話)
            mChannel.enableVibration(true);
            mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
            //最後在notificationmanager中創建該通知渠道
            if (mNotificationManager != null) {
                mNotificationManager.createNotificationChannel(mChannel);
            }
        }

//        AdvancedCustomPushNotification notification = new AdvancedCustomPushNotification(R.layout.notitfication_layout, R.id.m_icon, R.id.m_title, R.id.m_text);
//        notification.setServerOptionFirst(true);
//        notification.setBuildWhenAppInForeground(true);
//        notification.setRemindType(BasicCustomPushNotification.REMIND_TYPE_VIBRATE_AND_SOUND);
//        boolean res = CustomNotificationBuilder.getInstance().setCustomNotification(2, notification);

        PushServiceFactory.init(applicationContext);
        pushService = PushServiceFactory.getCloudPushService();
        pushService.register(applicationContext, new CommonCallback() {
            @Override
            public void onSuccess(String response) {
                Log.d("MyMessageReceiver", "init cloudchannel success"+response+ pushService.getDeviceId());

            }
            @Override
            public void onFailed(String errorCode, String errorMessage) {
                Log.d("MyMessageReceiver", "init cloudchannel failed -- errorcode:" + errorCode + " -- errorMessage:" + errorMessage);
            }
        });

    }

至此,就可以在控制檯測試阿里雲推送了

接下來纔是重點

以上操作只能保證APP開啓或者進程在後臺運行的情況下才能收到推送(有時候後臺運行也收不到),在後臺進程被殺死的情況下,是不能收到推送的,好在阿里雲提供的有移動推送輔助通道,這個東西,個人理解就是阿里雲與各個手機廠商的合作,需要去各個手機廠商的開發平臺去申請,申請成功就相當於借用廠商通道向廠商自己製造的手機發送通知,這樣就不再受進程限制

那就要一個一個來:輔助通道配置

一:華爲

首先在華爲開發者聯盟註冊APP,得到APPID和APPsecret,並開啓push功能 開啓push服務

下載輔助通道擴展包 阿里雲maven庫地址,可搜索並下載擴展包 這裏其實可以直接連接maven庫,很不幸,我還是不能從maven中取包,所以只能手動集成

另外阿里雲官方文檔裏添加的輔助推送擴展包依賴是3.0.10版本,但maven裏最新的只有3.0.9版本

這裏很矛盾,暫且不問(至於他說的OPPO,vivo需使用3.0.10版本,鑑於本人在寫這篇文章時只做了華爲,所以先擱置,車到山前必有路,做到了再說)

項目裏添加華爲推送sdk依賴:

    dependencies {
        ......
        compile 'com.aliyun.ams:huawei-push:2.6.3.305'
        compile 'com.aliyun.ams:huawei-push-base:2.6.3.305'
    }

同時在AndroidManifest文件中添加如下配置:

    <meta-data
                android:name="com.huawei.hms.client.appid"
                android:value="華爲開放平臺申請的ID信息(appid)" />

在application.onCreate()方法中初始化廠商通道. 注意:輔助通道註冊務必在Application中執行且放在推送SDK初始化代碼之後,否則可能導致輔助通道註冊失敗

    // 註冊方法會自動判斷是否支持小米系統推送,如不支持會跳過註冊。
    MiPushRegister.register(applicationContext, "小米AppID", "小米AppKey");
    // 註冊方法會自動判斷是否支持華爲系統推送,如不支持會跳過註冊。
    HuaWeiRegister.register(application);
    //GCM/FCM輔助通道註冊
    GcmRegister.register(this, sendId, applicationId); //sendId/applicationId爲步驟獲得的參數
    // OPPO通道註冊
    OppoRegister.register(applicationContext, appKey, appSecret); // appKey/appSecret在OPPO開發者平臺獲取
    // 魅族通道註冊
    MeizuRegister.register(applicationContext, "appId", "appkey"); // appId/appkey在魅族開發者平臺獲取
    // VIVO通道註冊
    VivoRegister.register(applicationContext);

可打印日誌查看通道初始化是否成功

 如不成功,檢查是否在華爲控制檯配置SHA256指紋證書,目前華爲需要配置 生成並配置指紋證書

這裏我一開始初始化失敗了,配置指紋證書之後就成功了

通過輔助通道(廠商通道)送達的通知,要定義一個activity去接收數據:官方文檔如下:

  • 服務端指定輔助彈窗通道推送時,一定要指定通知點擊後要打開的Activity,該Activity需繼承自抽象類AndroidPopupActivityMiPushSystemNotificationActivity已廢棄,小米、華爲、OPPO等廠商通道彈窗統一繼承AndroidPopupActivity),否則無法獲取到通知的相關信息,並且會影響通知到達率的統計;
  • AndroidPopupActivity中提供抽象方法onSysNoticeOpened(),實現該方法後可獲取到輔助彈窗通知的標題內容額外參數,在通知點擊時觸發,原本的通知回調onNotification()onNotificationOpened()不適用於輔助彈窗;
  • 指定打開的託管彈窗Activity在AndroidManifest.xml中註冊時需要聲明屬性:android:exported=true

    import com.alibaba.sdk.android.push.AndroidPopupActivity;
    public class PopupPushActivity extends AndroidPopupActivity {
        static final String TAG = "PopupPushActivity";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
        /**
         * 實現通知打開回調方法,獲取通知相關信息
         * @param title     標題
         * @param summary   內容
         * @param extMap    額外參數
         */
        @Override
        protected void onSysNoticeOpened(String title, String summary, Map<String, String> extMap) {
            Log.d("OnMiPushSysNoticeOpened, title: " + title + ", content: " + summary + ", extMap: " + extMap);
        }
    }

 服務端在推送時,需自己配置好appkey和appsecret,還要置頂輔助彈框對應的activity

在控制檯的表現就是

 

至此,華爲手機上的app無論後臺進程存在與否,都能收到推送

其他手機廠商也差不多都是這樣的流程,等我做完了,哪個有特別需要注意的地方,再來更新

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章