PushLibrary,一個集合所有主流廠商的推送框架

不如跳舞發表於2019-02-13

年後第一發,一個集合所有主流廠商的推送框架

前言

由於專案需要,開發了一個整合了所有主流廠商的推送框架。本框架集合了小米,華為,OPPO,VIVO,極光等五家推送。其中我們可以在初始化時選擇是否支援這四家廠商推送。先貼下專案路徑:PushLibrary

目前的推送邏輯是,如果初始化時都支援,會根據使用者手機型號來自動判斷使用哪家的推送。如果使用者手機不屬於當前四大廠商,則使用極光推送。考慮到四大廠商推送也可能不支援早期版本的手機,會有在初始化出錯之後選擇極光推送的容錯處理。(後續可能會繼續加入個推,友盟推送等平臺推送,但我們日常開發中只需要新增一個就行了)

目前我們在使用各大推送平臺時,在使用者點選跳轉這個選項上,都是設定的自定義行為。由伺服器傳入額外資訊後APP根據資訊自行處理,例如跳轉到不同介面,顯示不同資訊。如果APP不做任何處理,點選通知不會產生任何效果,也不會自動開啟APP。

鄙人不才,可能很多需求沒考慮清楚。大家如果發現BUG或者有更好的解決方案,歡迎提issue。覺得有用或者出於鼓勵,也可以star一下,在此拜謝。

demo預覽

小米推送 vivo推送 極光推送
PushLibrary,一個集合所有主流廠商的推送框架
   
PushLibrary,一個集合所有主流廠商的推送框架
   
PushLibrary,一個集合所有主流廠商的推送框架
   

華為手機無法錄屏,所以只有截圖
PushLibrary,一個集合所有主流廠商的推送框架

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.xmlapplication標籤下新增廠商推送的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.xmlapplication標籤下注冊靜態廣播。

        <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也不用做處理。
PushLibrary,一個集合所有主流廠商的推送框架

華為推送,講道理,有點坑。整合起來最複雜不說,遇到的問題還賊多。華為推送在點選通知這塊還是選擇自定義由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) 轉發登出成功訊息

感謝

在做這個框架時,參考了OnePushPush,在此感謝各位同行大佬。

相關文章