PushLibrary

Introduction: 一个集合所有主流厂商的推送框架
More: Author   ReportBugs   
Tags:

前言

由于项目需要,开发了一个整合了所有主流厂商的推送框架。本框架集合了小米,华为,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.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 也不用做处理。

华为推送,讲道理,有点坑。集成起来最复杂不说,遇到的问题还贼多。华为推送在点击通知这块还是选择自定义由 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,在此感谢各位同行大佬。

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools