在上一章节,我们了解了推送的基本概念,在本章节,我们开始使用百度推送、小米推送、华为推送
录入时版本号:
再此之前,我们假设你已经注册了对应平台的对应账户,并且创建了对应的应用,获取到了对应AppID,Appkey,ApppSecretKey
百度推送引入说明
小米推送引入说明
华为推送引入说明
[魅族推送引入说明]
dependencies {
compile 'com.meizu.flyme.internet:push-internal-publish:3.2.*'
}
一般需要注册:
<meta-data android:name="api_key" android:value="vbhptIZZOetZTtPaEKM1a4LK" />
<meta-data
android:name="api_key"
android:value="MUBmEOuW29Kajfy7tVzDG2D7" />
<receiver android:name="com.baidu.android.pushservice.PushServiceReceiver"
android:process=":bdservice_v1" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="com.baidu.android.pushservice.action.notification.SHOW" />
<action android:name="com.baidu.android.pushservice.action.media.CLICK" />
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
intent-filter>
receiver>
<receiver android:name="com.baidu.android.pushservice.RegistrationReceiver"
android:process=":bdservice_v1" >
<intent-filter>
<action android:name="com.baidu.android.pushservice.action.METHOD" />
<action android:name="com.baidu.android.pushservice.action.BIND_SYNC" />
intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
intent-filter>
receiver>
<service android:name="com.baidu.android.pushservice.PushService" android:exported="true"
android:process=":bdservice_v1" >
<intent-filter >
<action android:name="com.baidu.android.pushservice.action.PUSH_SERVICE" />
intent-filter>
service>
<service android:name="com.baidu.android.pushservice.CommandService"
android:exported="true" />
<provider
android:name="com.baidu.android.pushservice.PushInfoProvider"
android:authorities="test.com.yu.bdpush"
android:writePermission="baidu.push.permission.WRITE_PUSHINFOPROVIDER.test.com.yu"
android:protectionLevel = "signature"
android:exported="true" />
<service
android:name="com.xiaomi.push.service.XMJobService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":pushservice" />-
<service android:name="com.xiaomi.push.service.XMPushService" android:enabled="true"
android:process=":pushservice"/>
<service android:name="com.xiaomi.mipush.sdk.PushMessageHandler" android:enabled="true"
android:exported="true"/>
<service android:enabled="true" android:name="com.xiaomi.mipush.sdk.MessageHandleService"/>
<receiver
android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<category android:name="android.intent.category.DEFAULT" />
intent-filter>
receiver>
<receiver android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver"
android:exported="true" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<category android:name="android.intent.category.DEFAULT" />
intent-filter>
receiver>
<receiver android:name="com.xiaomi.push.service.receivers.PingReceiver"
android:exported="false"
android:process=":pushservice" >
<intent-filter>
<action android:name="com.xiaomi.push.PING_TIMER" />
intent-filter>
receiver>
<service
android:name="com.huawei.android.pushagent.PushService"
android:process=":pushservice" >
service>
<receiver
android:name="com.huawei.android.pushagent.PushEventReceiver"
android:process=":pushservice" >
<intent-filter>
<action android:name="com.huawei.android.push.intent.REFRESH_PUSH_CHANNEL" />
<action android:name="com.huawei.intent.action.PUSH" />
<action android:name="com.huawei.intent.action.PUSH_ON" />
<action android:name="com.huawei.android.push.PLUGIN" />
intent-filter>
<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>
<receiver
android:name="com.huawei.android.pushagent.PushBootReceiver"
android:process=":pushservice" >
<intent-filter>
<action android:name="com.huawei.android.push.intent.REGISTER" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
intent-filter>
<meta-data
android:name="CS_cloud_version"
android:value="\u0032\u0037\u0030\u0035" />
receiver>
<receiver android:name="com.baidu.push.example.MyPushMessageReceiver">
<intent-filter>
<action android:name="com.baidu.android.pushservice.action.MESSAGE" />
<action android:name="com.baidu.android.pushservice.action.RECEIVE" />
<action android:name="com.baidu.android.pushservice.action.notification.CLICK" />
intent-filter>
receiver>
<receiver
android:name="test.com.yu.DemoMessageReceiver"
android:exported="true" >
<intent-filter>
<action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE" />
intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED" />
intent-filter>
<intent-filter>
<action android:name="com.xiaomi.mipush.ERROR" />
intent-filter>
receiver>
<receiver android:name="com.huawei.pushtest.receiver.MyReceiver" >
<intent-filter>
<action android:name="com.huawei.android.push.intent.REGISTRATION" />
<action android:name="com.huawei.android.push.intent.RECEIVE" />
<action android:name="com.huawei.android.push.intent.CLICK" />
<action android:name="com.huawei.intent.action.PUSH_STATE" />
<action android:name="com.huawei.android.push.plugin.RESPONSE" />
intent-filter>
<meta-data android:name="CS_cloud_ablitity" android:value="@string/hwpush_ability_value"/>
receiver>
<receiver android:name="包名.MyPushMsgReceiver">
<intent-filter>
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
<action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
<action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK"/>
<action android:name="com.meizu.c2dm.intent.REGISTRATION" />
<action android:name="com.meizu.c2dm.intent.RECEIVE" />
<category android:name="包名">category>
intent-filter>
receiver>
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.BROADCAST_PACKAGE_CHANGED" />
<uses-permission android:name="android.permission.BROADCAST_PACKAGE_REPLACED" />
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/>
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="baidu.push.permission. WRITE_PUSHINFOPROVIDER.test.com.yu " />
<permission
android:name="baidu.push.permission. WRITE_PUSHINFOPROVIDER.test.com.yu"
android:protectionLevel="normal">
permission>
<permission
android:name="test.com.yu.permission.MIPUSH_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="test.com.yu.permission.MIPUSH_RECEIVE" />
<uses-permission android:name="com.huawei.pushagent.permission.RICHMEDIA_PROVIDER"/>
<uses-permission android:name="com.meizu.flyme.push.permission.RECEIVE">uses-permission>
<permission android:name="包名.push.permission.MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="包名.push.permission.MESSAGE">uses-permission>
<uses-permission android:name="com.meizu.c2dm.permission.RECEIVE" />
<permission android:name="你的包名.permission.C2D_MESSAGE"
android:protectionLevel="signature">permission>
<uses-permission android:name="你的包名.permission.C2D_MESSAGE"/>
<activity
android:name="com.baidu.android.pushservice.richmedia.MediaViewActivity"
android:configChanges="orientation|keyboardHidden"
android:label="MediaViewActivity" >
activity>
<activity
android:name="com.baidu.android.pushservice.richmedia.MediaListActivity"
android:configChanges="orientation|keyboardHidden"
android:label="MediaListActivity"
android:launchMode="singleTask" >
activity>
<activity
android:name="com.huawei.android.pushselfshow.richpush.RichPushActivity"
android:process=":pushservice"
android:theme="@style/hwpush_NoActionBar"
android:configChanges="orientation|screenSize|locale|layoutDirection"
android:screenOrientation="portrait">
<meta-data android:name="hwc-theme"
android:value="androidhwext:style/Theme.Emui"/>
<intent-filter>
<action android:name="com.huawei.android.push.intent.RICHPUSH" />
<category android:name="android.intent.category.DEFAULT" />
intent-filter>
activity>
<activity
android:name="com.huawei.android.pushselfshow.permission.RequestPermissionsActivity"
android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize|locale|layoutDirection"
android:exported="false">
activity>
PushManager.startWork(getApplicationContext(),PushConstants.LOGIN_TYPE_API_KEY,"api_key")
MiPushClient.registerPush(this, APP_ID, APP_KEY);
// 获取客户端AccessToken,获取之前请先确定该应用(包名)已经在开发者联盟上创建成功,并申请、审核通过Push权益
PushManager.requestToken(PustDemoActivity.this);
该部分详见下一章节内容
该部分详见下一章节内容
如果需要混淆app,请在混淆文件(一般默认为Android工程下proguard-project.txt或者proguard.cfg)中添加以下说明(pushservice-VERSION.jar为集成的jar包名字,VERSION为版本名称),防止SDK内容被二次混淆,无法收到消息。
-libraryjars libs/pushservice-VERSION.jar
-dontwarn com.baidu.**
-keep class com.baidu.**{*; }
如果你的应用使用了混淆,你需要keep自定义的BroadcastReceiver。
自定义的BroadcastReceiver继承PushMessageReceiver,使用下面的代码是不行的。
-keep public class * extends android.content.BroadcastReceiver
你需要使用下面的代码keep自定义的BroadcastReceiver。
#这里com.xiaomi.mipushdemo.DemoMessageRreceiver改成app中定义的完整类名
-keep class com.xiaomi.mipush.sdk.DemoMessageReceiver {*;}
开发者编译APK时请不要混淆本SDK,避免功能异常。 在配置文件中加入:
-keep class com.huawei.android.pushagent.**{*;}
-keep class com.huawei.android. pushselfshow.**{*;}
-keep class com.huawei.android. microkernel.**{*;}
-keep class com.baidu.mapapi.**{*;}
仅供参考。
混淆 Meizu插件以前是将proguard文件独立发布,因此proguard文件需要独立配置,现在我们已经将proguard打包进了aar中,具体详见consumerProguardFiles,因此就不再需要单独配置proguard远程依赖了
PUSH服务 与 华为移动服务(HMS)
使用HMS推送定义了EMUI的样式导致TimePicker初始化失败
官方DEMO有这句话
<application>
<meta-data android:name="hwc-theme"
android:value="androidhwext:style/Theme.Emui.NoActionBar" />
application>
使用了华为HMS SDK中的推送功能,然后插件布局文件中的TimePicker初始化时,会报如下错误:
android.view.InflateException: Binary XML file line #47: Error inflating class huawei.android.widget.TimePicker
很奇怪,TimePicker在布局文件中使用标签,当布局文件被inflate后,在android.widget.TimePicker前面加了一个huawei.。如果使用
android.view.InflateException: Binary XML file line #20: Error inflating class
at android.view.LayoutInflater.createView(LayoutInflater.java:620)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:669)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:694)
at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at android.app.TimePickerDialog.(TimePickerDialog.java:103)
at android.app.TimePickerDialog.(TimePickerDialog.java:74)
at android.view.View.performClick(View.java:4447)
at android.view.View$PerformClick.run(View.java:18457)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5119)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.view.LayoutInflater.createView(LayoutInflater.java:594)
... 20 more
Caused by: java.lang.NullPointerException
at android.view.ViewGroup.addView(ViewGroup.java:3353)
at com.huawei.android.hwcontrol.TimePickerFactory.updateAmPmStart(TimePickerFactory.java:92)
at android.widget.TimePicker.(TimePicker.java:265)
at android.widget.TimePicker.(TimePicker.java:139)
... 23 more
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.view.LayoutInflater.createView(LayoutInflater.java:594)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:669)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:694)
at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at android.app.TimePickerDialog.(TimePickerDialog.java:103)
at android.app.TimePickerDialog.(TimePickerDialog.java:74)
at android.view.View.performClick(View.java:4447)
at android.view.View$PerformClick.run(View.java:18457)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5119)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.view.ViewGroup.addView(ViewGroup.java:3353)
at com.huawei.android.hwcontrol.TimePickerFactory.updateAmPmStart(TimePickerFactory.java:92)
at android.widget.TimePicker.(TimePicker.java:265)
at android.widget.TimePicker.(TimePicker.java:139)
... 23 more
华为改了系统的源码,因为google官方的android系统源中有这样一个逻辑,发现布局文件中的View没有包名,会自动加上android.widget.前缀。已经在怀疑是在AndroidManifest.xml文件中配置了什么导致了问题,所以一行一行的排查。果然,在去掉下面这行后,就正常了。
这个meta-data定义是放在applicaton标签中,所以会针对整个App。把这行干掉之后,问题解决。
如果在推送中已经填写了Debug Key的SHA256证书指纹,再改成Release Key的指纹时,发现手机一直获取不到token,解决办法是把手机中相关华为的服务的应用缓存清除掉,特别是华为移动服务。如果还是不行,把华为商城应用升级到最新版本
如果一直能正常获取到token,突然又不能,解决办法是重启手机再试。
如果注册成功,发现收到消息,首先排查服务器端调用华为SDK是否OK,如果服务器端调用OK,没有出现报错之类的问题,然后就是等,可能是10分钟后或者20分钟后,甚至是第二天,你就 基本 能收到消息了
自己集成SDK测试时,出现了几次消息没收到的情况,也就是推送丢失了。但使用华为联盟后台推送比使用SDK推送,消息的到达率和准时性要好