1. 極光推送集成背景
? ? ? 最近在研究推送和長(zhǎng)連接,研究了幾家這方面的平臺(tái)之后瘫寝,最后綜合考慮選擇了極光推送。長(zhǎng)連接背砭妫活一直是一個(gè)大問(wèn)題焕阿,尤其的android方面,最近谷歌公司的幾次更新首启,android應(yīng)用蹦郝牛活是越來(lái)越難做,android方面的推送的到達(dá)率更是慘不忍睹毅桃。國(guó)內(nèi)android大環(huán)境大都以云端和客戶端保持長(zhǎng)連接的方式實(shí)現(xiàn)的褒纲。本文主要是說(shuō)一下極光推送普通集成和極光推送廠商通道的集成。
2. 推送普通集成方案
創(chuàng)建項(xiàng)目(見(jiàn)極光文檔:https://docs.jiguang.cn//jpush/guideline/intro/)
①添加依賴
Project 根目錄的主 gradle 中配置了 jcenter 支持
implementation 'cn.jiguang.sdk:jpush:3.5.4'
implementation 'cn.jiguang.sdk:jcore:2.2.4'
②配置代碼
配置極光的key钥飞,app 的gradle文件中配置極光的key
ndk {
? ? ? ? ? ? abiFilters "armeabi", "armeabi-v7a", "x86", "arm64-v8a", "x86_64",'mips', 'mips64'
? ? ? ? }
? ? ? ? manifestPlaceholders = [
? ? ? ? ? ? ? ? JPUSH_PKGNAME : applicationId,
? ? ? ? ? ? ? ? JPUSH_APPKEY : "JPUSH KEY", //JPush 上注冊(cè)的包名對(duì)應(yīng)的 Appkey.
? ? ? ? ? ? ? ? JPUSH_CHANNEL : "developer-default", //暫時(shí)填寫(xiě)默認(rèn)值即可.
? ? ? ? ]
權(quán)限配置
?<permission
? ? ? ? android:name="com.nade.nadejpush.permission.JPUSH_MESSAGE"
? ? ? ? android:protectionLevel="signature" />
? ? <!-- Required -->
? ? <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
? ? <uses-permission android:name="android.permission.INTERNET" />
? ? <uses-permission android:name="android.permission.READ_PHONE_STATE" />
? ? <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
? ? <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
? ? <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
? ? <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
? ? <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
? ? <!-- Optional. Required for location feature -->
? ? <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
? ? <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 用于開(kāi)啟 debug 版本的應(yīng)用在 6.0 系統(tǒng)上的層疊窗口權(quán)限 -->
? ? <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
? ? <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
? ? <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
? ? <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
? ? <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
? ? <uses-permission android:name="android.permission.GET_TASKS" />
? ? <uses-permission android:name="android.permission.VIBRATE" />
服務(wù)和廣播配置?
<!-- Since JCore2.0.0 Required SDK核心功能-->
? ? ? ? <!-- 可配置android:process參數(shù)將Service放在其他進(jìn)程中莺掠;android:enabled屬性不能是false -->
? ? ? ? <!-- 這個(gè)是自定義Service,要繼承極光JCommonService读宙,可以在更多手機(jī)平臺(tái)上使得推送通道保持的更穩(wěn)定 -->
? ? ? ? <service android:name=".service.JPushService"
? ? ? ? ? ? android:enabled="true"
? ? ? ? ? ? android:exported="false"
? ? ? ? ? ? android:process=":pushcore">
? ? ? ? ? ? <intent-filter>
? ? ? ? ? ? ? ? <action android:name="cn.jiguang.user.service.action" />
? ? ? ? ? ? </intent-filter>
? ? ? ? </service>
? ? ? ? <service
? ? ? ? ? ? android:name="cn.jpush.android.service.PushService"
? ? ? ? ? ? android:enabled="true"
? ? ? ? ? ? android:exported="false" >
? ? ? ? ? ? <intent-filter>
? ? ? ? ? ? ? ? <action android:name="cn.jpush.android.intent.REGISTER" />
? ? ? ? ? ? ? ? <action android:name="cn.jpush.android.intent.REPORT" />
? ? ? ? ? ? ? ? <action android:name="cn.jpush.android.intent.PushService" />
? ? ? ? ? ? ? ? <action android:name="cn.jpush.android.intent.PUSH_TIME" />
? ? ? ? ? ? </intent-filter>
? ? ? ? </service>
? ? ? ? <service
? ? ? ? ? ? android:name="cn.jpush.android.service.DaemonService"
? ? ? ? ? ? android:enabled="true"
? ? ? ? ? ? android:exported="true">
? ? ? ? ? ? <intent-filter >
? ? ? ? ? ? ? ? <action android:name="cn.jpush.android.intent.DaemonService" />
? ? ? ? ? ? ? ? <category android:name="com.nade.nadejpush"/>
? ? ? ? ? ? </intent-filter>
? ? ? ? </service>
? ? ? ? <!-- Required since 3.0.7 -->
? ? ? ? <!-- 新的 tag/alias 接口結(jié)果返回需要開(kāi)發(fā)者配置一個(gè)自定的廣播 -->
? ? ? ? <!-- 3.3.0開(kāi)始所有事件將通過(guò)該類回調(diào) -->
? ? ? ? <!-- 該廣播需要繼承 JPush 提供的 JPushMessageReceiver 類, 并如下新增一個(gè) Intent-Filter -->
? ? ? ? <receiver
? ? ? ? ? ? android:name=".receiver.JPushReceiver"
? ? ? ? ? ? android:enabled="true"
? ? ? ? ? ? android:exported="false" >
? ? ? ? ? ? <intent-filter>
? ? ? ? ? ? ? ? <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
? ? ? ? ? ? ? ? <category android:name="com.nade.nadejpush" />
? ? ? ? ? ? </intent-filter>
? ? ? ? </receiver>
? ? ? ? <receiver
? ? ? ? ? ? android:name="cn.jpush.android.service.PushReceiver"
? ? ? ? ? ? android:enabled="true" >
? ? ? ? ? ? <intent-filter android:priority="1000">
? ? ? ? ? ? ? ? <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />
? ? ? ? ? ? ? ? <category android:name="com.nade.nadejpush"/>
? ? ? ? ? ? </intent-filter>
? ? ? ? ? ? <intent-filter>
? ? ? ? ? ? ? ? <action android:name="android.intent.action.USER_PRESENT" />
? ? ? ? ? ? ? ? <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
? ? ? ? ? ? </intent-filter>
? ? ? ? ? ? <!-- Optional -->
? ? ? ? ? ? <intent-filter>
? ? ? ? ? ? ? ? <action android:name="android.intent.action.PACKAGE_ADDED" />
? ? ? ? ? ? ? ? <action android:name="android.intent.action.PACKAGE_REMOVED" />
? ? ? ? ? ? ? ? <data android:scheme="package" />
? ? ? ? ? ? </intent-filter>
? ? ? ? </receiver>
這里需要自定義一個(gè)消息接收器 JPushReceiver
/**
?* 消息處理彻秆,配合服務(wù)端實(shí)現(xiàn)具體的邏輯
?*/
public class JPushReceiver extends JPushMessageReceiver {
? ? @Override
? ? public void onMessage(Context context, CustomMessage customMessage) {
? ? ? ? super.onMessage(context, customMessage);
? ? ? ? //消息到達(dá) 可指定類型,指定操作
? ? ? ? NotificationBar.showNotifiBar(context,"我是消息","我是消息內(nèi)容");
? ? ? ? Log.d("jpush", "onMessage: "+customMessage.message+"/"+customMessage.extra);
? ? }
? ? @Override
? ? public void onNotifyMessageArrived(Context context, NotificationMessage notificationMessage) {
? ? ? ? super.onNotifyMessageArrived(context, notificationMessage);
? ? ? ? // 通知到達(dá)
? ? ? ? Log.d("jpush", "onNotifyMessageArrived: "+notificationMessage.notificationExtras);
? ? }
? ? @Override
? ? public void onNotifyMessageOpened(Context context, NotificationMessage notificationMessage) {
? ? ? ? super.onNotifyMessageOpened(context, notificationMessage);
? ? ? ? // 點(diǎn)擊通知欄消息 可指定類型结闸,指定操作
? ? ? ? Log.d("jpush", "onNotifyMessageOpened: "+notificationMessage.notificationExtras);
? ? }
? ? @Override
? ? public void onRegister(Context context, String s) {
? ? ? ? super.onRegister(context, s);
? ? ? ? // 保存極光id
? ? ? ? Log.d("jpush", "onRegister: id="+s);
? ? }
? ? @Override
? ? public void onConnected(Context context, boolean b) {
? ? ? ? super.onConnected(context, b);
? ? ? ? Log.d("jpush", "onConnected: "+b);
? ? ? ? if (b) {
? ? ? ? ? ? // 鏈接監(jiān)聽(tīng) 保存極光id
? ? ? ? ? ? String registrationID = JPushInterface.getRegistrationID(context.getApplicationContext());
? ? ? ? ? ? Log.d("jpush", "onConnected: 連接成功獲取id="+registrationID);
? ? ? ? }
? ? }
}
③ 初始化
這里關(guān)于初始化方案這里分享兩種:
i.? 極光方案唇兑,在Application的onCreate中初始化,也就是在應(yīng)用啟動(dòng)時(shí)初始化極光桦锄,優(yōu)點(diǎn)快速準(zhǔn)確扎附;但會(huì)影響app啟動(dòng)速度。
ii.? 在啟動(dòng)頁(yè)初始化结耀,優(yōu)點(diǎn)app啟動(dòng)速度快帕棉。我個(gè)人覺(jué)得第二方案更好一點(diǎn)针肥,在優(yōu)化app啟動(dòng)時(shí),會(huì)有一些幫助。
RegistrationID的獲取香伴,也有兩個(gè)方案
i. 在初始化以后慰枕,獲取極光id 極光id是異步返回的,此處不一定獲取成功即纲。
?String registrationID = JPushInterface.getRegistrationID(getApplicationContext());
ii. JPushReceiver中獲取具帮,這里獲取更為安全,能確保你一定可以拿到id低斋,建議采用該種方案
?@Override
? ? public void onRegister(Context context, String s) {
? ? ? ? super.onRegister(context, s);
? ? ? ? // 保存極光id
? ? ? ? Log.d("jpush", "onRegister: 注冊(cè)成功后返回極光id="+s);
? ? }
? ? @Override
? ? public void onConnected(Context context, boolean b) {
? ? ? ? super.onConnected(context, b);
? ? ? ? Log.d("jpush", "onConnected: "+b);
? ? ? ? if (b) {
? ? ? ? ? ? // 鏈接監(jiān)聽(tīng) 保存極光id
? ? ? ? ? ? String registrationID = JPushInterface.getRegistrationID(context.getApplicationContext());
? ? ? ? ? ? Log.d("jpush", "onConnected: 連接成功獲取id="+registrationID);
? ? ? ? }
? ? }
到此處蜂厅,極光推送的基本集成就完成了;屆時(shí)可以在極光的管理中心膊畴,去測(cè)試推送了掘猿。
在普通集成的基礎(chǔ)上,我們開(kāi)始集成廠商通道唇跨;
3. 廠商通道的集成
? ? ?廠商通道稠通,直白點(diǎn)說(shuō)就是系統(tǒng)級(jí)推送,和 ios一樣买猖;推送至手機(jī)系統(tǒng)平臺(tái)改橘,由系統(tǒng)平臺(tái)作為系統(tǒng)通知展示。到達(dá)率得到了很大的保證玉控;目前極光支持 小米 華為 魅族 oppo vivo FCM這幾個(gè)平臺(tái)的廠商通道飞主;原理見(jiàn)下圖:
?①申請(qǐng)平臺(tái)項(xiàng)目(小米,華為創(chuàng)建項(xiàng)目高诺,審核通過(guò)后申請(qǐng)項(xiàng)目的推送服務(wù))
以小米為例
https://dev.mi.com/console/appservice/push.html
先在小米開(kāi)放平臺(tái)創(chuàng)建項(xiàng)目 填寫(xiě)各種資料碌识,審核通過(guò)后,就開(kāi)始申請(qǐng)小米推送服務(wù)虱而。審核通過(guò)后丸冕,去極光后臺(tái)配置id 和即可;配置好以后 ,開(kāi)始進(jìn)行代碼配置薛窥,Project 根目錄的主 gradle 中配置了華為支持
allprojects {
? ? repositories {
? ? ? ? google()
? ? ? ? maven { url "https://jitpack.io" }
? ? ? ? maven {url'http://developer.huawei.com/repo/'}
? ? }
}
在app的gradle添加廠商通道sdk依賴胖烛,這個(gè)使用的極光的
?implementation 'cn.jiguang.sdk.plugin:huawei:3.3.4'
? ? implementation 'cn.jiguang.sdk.plugin:xiaomi:3.3.4'
? ? implementation 'cn.jiguang.sdk.plugin:meizu:3.3.4'
? ? implementation 'cn.jiguang.sdk.plugin:oppo:3.3.4'
? ? implementation 'cn.jiguang.sdk.plugin:vivo:3.3.4'
在app的gradle 配置廠商平臺(tái)申請(qǐng)好的 id 和 key
?備注:這里使用的是各平臺(tái)項(xiàng)目的推送服務(wù)id, 各平臺(tái)項(xiàng)目的推送服務(wù)id,各平臺(tái)項(xiàng)目的推送服務(wù)id!W缑浴佩番!?
manifestPlaceholders = [
? ? ? ? ? ? ? ? JPUSH_PKGNAME : applicationId,
? ? ? ? ? ? ? ? JPUSH_APPKEY ?: "JPUSHKEY", //JPush上注冊(cè)的包名對(duì)應(yīng)的appkey.
? ? ? ? ? ? ? ? JPUSH_CHANNEL : "developer-default", //暫時(shí)填寫(xiě)默認(rèn)值即可.
? ? ? ? ? ? ? ? HUAWEI_APPID ?: "100574375",//華為平臺(tái)注冊(cè)的appid
? ? ? ? ? ? ? ? XIAOMI_APPKEY : "MI-KEY",//小米平臺(tái)注冊(cè)的appkey
? ? ? ? ? ? ? ? XIAOMI_APPID ?: "MI-IS",//小米平臺(tái)注冊(cè)的appid
? ? ? ? ? ? ? ? MEIZU_APPKEY ?: "MZ-KEY",//魅族平臺(tái)注冊(cè)的appkey
? ? ? ? ? ? ? ? MEIZU_APPID ? : "MZ-ID",//魅族平臺(tái)注冊(cè)的appid
? ? ? ? ? ? ? ? OPPO_APPKEY ? : "OP-KEY", // OPPO平臺(tái)注冊(cè)的appkey
? ? ? ? ? ? ? ? OPPO_APPID ? ?: "OP-ID", // OPPO平臺(tái)注冊(cè)的appid
? ? ? ? ? ? ? ? OPPO_APPSECRET: "OP-SECRET"
? ? ? ? ? ? ? ? // vivo
? ? ? ? ? ? ? ? VIVO_APPKEY : "KEY",
? ? ? ? ? ? ? ? VIVO_APPID : "ID"
? ? ? ? ]
到此處就完成了。關(guān)于廠商通道的測(cè)試方法罢杉,去各大平臺(tái)的推送服務(wù)里的項(xiàng)目中趟畏,進(jìn)行手動(dòng)推送測(cè)試。以小米為例滩租,小米開(kāi)放平臺(tái) --- 應(yīng)用服務(wù) -- 消息推送 -- 全部應(yīng)用 --- 你的應(yīng)用 -- 創(chuàng)建推送 即可開(kāi)始測(cè)試
測(cè)試方法:
①保持長(zhǎng)鏈接時(shí)赋秀,手動(dòng)推送利朵,是否收到推送消息
②斷開(kāi)長(zhǎng)鏈接時(shí),手動(dòng)推送猎莲,是否收到推送消息
③斷開(kāi)長(zhǎng)鏈接時(shí)绍弟,手動(dòng)推送,打開(kāi)應(yīng)用后是否收到推送消息