由于项目需要,开发了一个整合了所有主流厂商的推送框架。本框架集合了小米,华为,OPPO,VIVO,极光等五家推送。其中我们可以在初始化时选择是否支持这四家厂商推送。先贴下项目路径:PushLibrary
目前的推送逻辑是,如果初始化时都支持,会根据用户手机型号来自动判断使用哪家的推送。如果用户手机不属于当前四大厂商,则使用极光推送。考虑到四大厂商推送也可能不支持早期版本的手机,会有在初始化出错之后选择极光推送的容错处理。(后续可能会继续加入个推,友盟推送等平台推送,但我们日常开发中只需要添加一个就行了)
目前我们在使用各大推送平台时,在用户点击跳转这个选项上,都是设置的自定义行为。由服务器传入额外信息后APP根据信息自行处理,例如跳转到不同界面,显示不同信息。如果APP不做任何处理,点击通知不会产生任何效果,也不会自动打开APP。
鄙人不才,可能很多需求没考虑清楚。大家如果发现BUG或者有更好的解决方案,欢迎提issue。觉得有用或者出于鼓励,也可以star一下,在此拜谢。
小米推送 | vivo推送 | 极光推送 |
---|---|---|
![]() |
![]() |
![]() |
OPPO推送无法注册个人账户,暂时没有预览
在项目的build.gradle
中,需要在allprojects
最后添加jitpack
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
在APP的build.gradle
中添加如下依赖,版本号以最新为准
implementation 'com.github.YoloHuang:PushLibrary:v1.0'
<!-- 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" />
初始化仅需要在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()
<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推送由于集成完后无法注册个人账号测试,所以效果未知。各位大佬如果可以弄到测试账号在下感激不尽。
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.将各个推送分开做库,再使用统一库做统一处理。这样可以满足不同需求。
方法名称 | 描述及解释 |
---|---|
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模式 |
方法名称 | 描述及解释 |
---|---|
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) | 转发登出成功消息 |