年後第一發,一個集合所有主流廠商的推送框架
前言
由於專案需要,開發了一個整合了所有主流廠商的推送框架。本框架集合了小米,華為,OPPO,VIVO,極光等五家推送。其中我們可以在初始化時選擇是否支援這四家廠商推送。先貼下專案路徑:PushLibrary
目前的推送邏輯是,如果初始化時都支援,會根據使用者手機型號來自動判斷使用哪家的推送。如果使用者手機不屬於當前四大廠商,則使用極光推送。考慮到四大廠商推送也可能不支援早期版本的手機,會有在初始化出錯之後選擇極光推送的容錯處理。(後續可能會繼續加入個推,友盟推送等平臺推送,但我們日常開發中只需要新增一個就行了)
目前我們在使用各大推送平臺時,在使用者點選跳轉這個選項上,都是設定的自定義行為。由伺服器傳入額外資訊後APP根據資訊自行處理,例如跳轉到不同介面,顯示不同資訊。如果APP不做任何處理,點選通知不會產生任何效果,也不會自動開啟APP。
鄙人不才,可能很多需求沒考慮清楚。大家如果發現BUG或者有更好的解決方案,歡迎提issue。覺得有用或者出於鼓勵,也可以star一下,在此拜謝。
demo預覽
小米推送 | vivo推送 | 極光推送 |
---|---|---|
|
|
|
華為手機無法錄屏,所以只有截圖
OPPO推送無法註冊個人賬戶,暫時沒有預覽
快速整合
1.新增依賴
在專案的build.gradle
中,需要在allprojects
最後新增jitpack
allprojects {
repositories {
...
maven { url `https://jitpack.io` }
}
}
複製程式碼
在APP的build.gradle
中新增如下依賴,版本號以最新為準
implementation `com.github.YoloHuang:PushLibrary:v1.0`
複製程式碼
2.在AndroidManifest.xml
的application
標籤下新增廠商推送的ID和key等相關資源(如果只支援部分廠商,只需要新增支援的廠商資訊就行)
<!-- vivo 推送的ID 和 key -->
<meta-data
android:name="com.vivo.push.api_key"
android:value="b4bcea82-9dbf-45aa-82d8-5555bc65257e"/>
<meta-data
android:name="com.vivo.push.app_id"
android:value="10937"/>
<!-- oppo 推送暫不支援個人開發者,所以無法在demo中演示 -->
<meta-data
android:name="OPPO_APP_KEY"
android:value="" />
<meta-data
android:name="OPPO_APP_SECRET"
android:value="" />
<!-- 華為推送 ID-->
<meta-data
android:name="com.huawei.hms.client.appid"
android:value="appid=100612743" />
<!--//小米推送的AppKey ,APPID ****請務必在數值中間新增一個空格,否則會發生數值變化**** -->
<meta-data
android:name="XMPUSH_APPKEY"
android:value="5851794 217581" />
<meta-data
android:name="XMPUSH_APPID"
android:value="288230376 1517942581" />
<!--//小米推送的AppKey ,APPID ****請務必在數值中間新增一個空格,否則會發生數值變化**** -->
<!-- JPUSH_CHANNEL 是為了方便開發者統計APK分發渠道。-->
<meta-data
android:name="JPUSH_CHANNEL"
android:value="default" />
<!-- Required. AppKey copied from Portal -->
<meta-data
android:name="JPUSH_APPKEY"
android:value="4bc48df35351d4ccf480561f" />
複製程式碼
3.初始化pushlibrary
初始化僅需要在application的onCreate中增加如下程式碼。在這其中,需要注意:設定debug需要在init之前,這樣可以確保log列印完整。設定debug模式僅僅是針對log是否列印。debug預設為false,如果不需要列印log不設定即可。
override fun onCreate() {
super.onCreate()
PushTargetManager.getInstance().setDebug(true)
PushTargetManager.getInstance().init(this)
}
複製程式碼
4.登入,設定別名,登出等介面,其中登入需要在activity中執行(是由於華為推送登入需要傳入activity物件)。框架中,將登入和接受通知、登出和不接受通知放在一起處理,後面會拆分開來,滿足不同需求。
/**
* 登入
*/
PushTargetManager.getInstance().loginIn(this)
/**
* 設定別名
*/
PushTargetManager.getInstance().setAlias(alias)
/**
* 登出
*/
PushTargetManager.getInstance().loginOut()
複製程式碼
5.在AndroidManifest.xml
的application
標籤下注冊靜態廣播。
<receiver android:name="com.yolo.pushlibrary.TestPushReceiver">
<intent-filter>
<action android:name="com.kidosc.pushlibrary.ACTION_RECEIVE_NOTIFICATION"/>
<action android:name="com.kidosc.pushlibrary.ACTION_RECEIVE_NOTIFICATION_CLICK"/>
<action android:name="com.kidosc.pushlibrary.ACTION_RECEIVE_MESSAGE"/>
<action android:name="com.kidosc.pushlibrary.ACTION_RECEIVE_TOKEN_SET"/>
<action android:name="com.kidosc.pushlibrary.ACTION_RECEIVE_INIT_RESULT"/>
<action android:name="com.kidosc.pushlibrary.ACTION_RECEIVE_LOGIN_OUT"/>
<action android:name="com.kidosc.pushlibrary.ACTION_RECEIVE_SET_ALIAS"/>
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
複製程式碼
新建一個receiver繼承框架中的BasePushReceiver,重寫onReceiveNotificationClick等方法,推送的相關處理都是在這裡處理。
class TestPushReceiver : BasePushReceiver() {
companion object {
val ACTION_BROADCAST:String = "com.yolo.pushlibrary.ACTION_PUSH"
val PUSH_LOG = "push_log"
}
override fun onReceiveNotification(context: Context, info: ReceiverInfo) {
sendBroadCast(context,info)
}
override fun onReceiveNotificationClick(context: Context, info: ReceiverInfo) {
sendBroadCast(context,info)
}
override fun onReceiveMessage(context: Context, info: ReceiverInfo) {
sendBroadCast(context,info)
}
override fun onTokenSet(context: Context, info: ReceiverInfo) {
sendBroadCast(context,info)
}
override fun onInitResult(context: Context, info: ReceiverInfo) {
sendBroadCast(context,info)
}
override fun onLoginOut(context: Context, info: ReceiverInfo) {
sendBroadCast(context,info)
}
override fun onSetAlias(context: Context, info: ReceiverInfo) {
sendBroadCast(context,info)
}
fun sendBroadCast(context: Context,info: ReceiverInfo){
val intent= Intent(ACTION_BROADCAST)
intent.putExtra(PUSH_LOG,info)
intent.`package` = context.packageName
context.sendBroadcast(intent)
}
}
複製程式碼
這一步中,可能會存在Android8.0無法接收動態註冊廣播問題。但是我在8.0測試機上沒發現,後續如果出現此問題,會想辦法解決。
以上,就完成了整個框架的快速整合。
關於整合各家推送中遇到的問題
極光推送,小米推送,OPPO推送
極光是一個成熟的推送平臺,整個整合流程行雲流水,文件也十分完整,基本沒什麼問題。小米推送也是如此。OPPO推送由於整合完後無法註冊個人賬號測試,所以效果未知。各位大佬如果可以弄到測試賬號在下感激不盡。
vivo推送,華為推送
vivo推送中遇到的主要問題是,在伺服器端,按照vivo介面文件,我們在clientCustomMap中放入我們所需要額外資訊。同時設定skipType為3自定義。這樣我們可以直接根據通知中的額外資訊讓APP自行處理,而不需要在伺服器端設定。但是在skipContent這個引數上有一些疑問,不能為空,我們又不知道該傳入什麼。最後找到他們的官方FAE QQ交流,得知這個引數隨便填一下就行,APP也不用做處理。
華為推送,講道理,有點坑。整合起來最複雜不說,遇到的問題還賊多。華為推送在點選通知這塊還是選擇自定義由APP處理。但是我們需要在AndroidManifest.xml
中新增intent-filter過濾器,並且在伺服器端使用同種過濾器。而這點,在文件中藏的很深。華為推送服務端文件中關於這個問題的描述
<activity
android:name=".rom.huawei.HuaweiLoadActivity"
android:theme="@style/LoadTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="com.kidosc.pushlibrary"
android:path="/notification"
android:scheme="pushlibrary" />
</intent-filter>
</activity>
複製程式碼
還遇到的一個問題就是,簽名之後註冊華為推送失敗。這個是我自己這邊沒有進行混淆處理導致的。當時我的混淆處理加在pushlibrary中,卻一直不生效。後面將處理加在APP中,問題解決。目前推送框架已經解決了這個問題。
後續計劃
寫了個框架就相當於開了個坑,開坑不填那肯定是不行的。後續的計劃有:
1.增加標籤功能
2.增加友盟,個推平臺
3.優化程式碼,減小包的大小
4.將各個推送分開做庫,再使用統一庫做統一處理。這樣可以滿足不同需求。
相關API介紹
pushlibrary詳細api
方法名稱 | 描述及解釋 |
---|---|
init(Application application ) | 初始化OnePush,建議在Application中onCreate()方法 |
init(Application application,boolean enableHWPush,boolean enableOppoPush,boolean enableVivoPush,boolean enableXIAOMIPush ) | 初始化OnePush,建議在Application中onCreate()方法,可以設定是否支援該廠商推送 |
loginIn(Activity activity) | 註冊訊息推送,需要在activity中呼叫 |
loginOut() | 取消註冊訊息推送 |
setAlias(String alias) | 繫結別名 |
setDebug(boolean) | 設定是否為debug模式 |
BasePushReceiver詳細api
方法名稱 | 描述及解釋 |
---|---|
onReceiveNotification(Context context ,ReceiverInfo info) | 轉發通知 |
onReceiveMessage(Context context ,ReceiverInfo info) | 轉發透傳訊息 |
onTokenSet(Context context ,ReceiverInfo info) | 轉發華為token |
onInitResult(Context context ,ReceiverInfo info) | 轉發初始化成功訊息,info中包含推送註冊平臺資訊 |
onSetAlias(Context context ,ReceiverInfo info) | 轉發設定別名成功的訊息,info中包含別名 |
onLoginOut(Context context ,ReceiverInfo info) | 轉發登出成功訊息 |