极光厂商通道集成指南
- 小米集成指南
1、使用JCenter自动化集成步骤
- 确认AndroidStudio的Project根目录的主gradle中配置了jcenter支持。(新建project默认配置就支持)
buildscript { repositories { jcenter() } } allprojects { repositories { jcenter() } }
- 在应用module的gradle中dependencies节点添加如下代码:
dependencies{ compile 'cn.jiguang.sdk.plugin:xiaomi:3.2.0'//此版本插件仅支持JPushSDK3.2.0及以上版本 }
- 在应⽤module的gradle中defaultConfig节点添加如下代码(不要遗漏前缀MI-):
manifestPlaceholders=[ JPUSH_PKGNAME:"您应用的包名" XIAOMI_APPKEY:"MI-您的应用对应的小米的APPKEY",//小米平台注册的appkey XIAOMI_APPID:"MI-您的应用对应的小米的APPID",//小米平台注册的appid ]
2、配置AndroidManifest.xml集成步骤
注意:(JCenter自动化集成与配置AndroidManifest.xml集成二者选择一种即可,如果您完成以上步骤,您可以跳过本段)
- 导入极光的插件包以及小米推送sdk的jar
- 将极光提供的libs包中的jpush-android-plugin-xiaomi-v3.x.x.jar(插件包)及MiPush_SDK_Client_x_x_x.jar(小米推送包)导入到工程libs/目录下。
- 配置小米推送sdk所需要的权限
配置小米必须的组件<permission android:name="您应用的包名.permission.MIPUSH_RECEIVE" android:protectionLevel="signature"/> <uses-permission android:name="您应用的包名.permission.MIPUSH_RECEIVE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <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.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.GET_TASKS"/> <uses-permission android:name="android.permission.VIBRATE"/>
-
<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:name="com.xiaomi.mipush.sdk.MessageHandleService" android:enabled="true"/> <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>
注:请不要将极光的组件PushReceiver配置进程和主进程分离。(按照示例默认配置即可)否则会影响小米RegId的获取。
-
配置JPush接受的小米sdk的消息接受类
-
<receiver android:name="cn.jpush.android.service.PluginXiaomiPlatformsReceiver" 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>
将APPKEY与APPID替换为在小米后台注册对应该应用的AppKey/AppID(不要遗漏前缀MI-)
-
<meta-data android:name="XIAOMI_APPKEY" android:value="MI-您的应用对应的小米的appkey"/> <meta-data android:name="XIAOMI_APPID" android:value="MI-您的应用对应小米的appID"/>
3、小米SDK的编译混淆问题
如果使用了proguard,需要在配置文件中加入,可以防止一个误报的warning导致无法成功编译:
-
-dontwarncom.xiaomi.push.** -keepclasscom.xiaomi.push.**{*;}
4、集成结果判断
成功
能成功调用接口获取到小米rid,存在小米集成成功但rid为null的情况。(需要在主进程中获取)
-
MiPushClient.getRegId(getApplicationContext());
失败
缺少appkey或appid。打印:
-
xiaomisdkappkeyorappidwasempty,pleasecheckyourmanifestconfig
当配置都正常时,小米sdk注册失败时miui会打印E级别的日志,一般是appkey、appid非法。打印:
-
"xiaomipushregisterfailed-errorCode:" + message.getResultCode() + ",reason:" + message.getReason());
当配置都正常时,无法通过方法MiPushClient.getRegId获得regID,需要检查一下小米应用是否开启推送功能。打印:
-
[PluginXiaomiPlatformsReceiver]xiaomipushregisterfailed-errorCode:22022,reason:Invalidpackagename:com.xxxxxx.xxxxxx
-
5、小米厂商通道测试方法
- 在您的App中集成极光3.2.0及以上版本的SDK,并且按照「第三方通知通道集成指南」集成所需的厂商SDK;
- 联系极光技术支持确认已在极光的后台配置好了相关的应用信息。如果开通成功了再进行下一个步骤;
- 将集成好的App(测试版本)安装在测试机(需要小米手机)上,并且运行App;
- 保持App在前台运行,尝试对设备进行推送;
- 如果应用收到消息,将App退到后台,并且杀掉所有App进程;
- 再次进行推送,如果能够收到推送,则表明厂商通道集成成功。
1、使用JCenter自动化集成步骤
- 确认androidstudio的Project根目录的主gradle中配置了jcenter支持。(新建project默认配置就支持)。因为华为本身不支持jcenter集成方式,所以需要在androidstudio的Project根目录的主gradle中配置其提供的库引用地址。
-
buildscript{ repositories{ jcenter() } } allprojects{ repositories{ jcenter() maven{url'http://developer.huawei.com/repo/'} } }
在应用module的gradle中dependencies节点添加如下代码:
-
dependencies{ compile'cn.jiguang.sdk.plugin:huawei:3.2.0'//此版本插件仅支持JPushSDK3.2.0及以上版本 }
在应用module的gradle中defaultConfig节点添加如下代码:
-
manifestPlaceholders=[ JPUSH_PKGNAME:"您应用的包名" HUAWEI_APPID:"您的应用对应华为的appID",//华为平台注册的appid ]
2、配置AndroidManifest.xml集成步骤
注意:(JCenter自动化集成与配置AndroidManifest.xml集成二者选择一种即可,如果您完成以上步骤,您可以跳过本段)
- 导入极光的插件包以及华为HMS SDK的jar
-
将极光提供的libs包中的jpush-android-plugin-huawei-v3.x.x(华为插件包)及HMS_SDK_x.x.x.xxx.jar (华为推送包)导入到工程libs/目录下。
将third-push/huawei/assets里面的资源复制到工程/assets中对应的目录
注1:极光集成华为通道在JPush Android SDK 3.0.5添加,对应测试的华为HMSSDK版本为:HMS-SDK-2.4.0.300.aar。
注2:JPush Android SDK 3.0.9适配HMS SDK的升级,对应测试的华为HMSSDK版本为:HMSSdk-base-2.5.2.300.aar,HMSSdk-push-2.5.2.300.aar。
注3:JPush Android SDK 3.1.2适配HMS SDK的升级,对应测试的华为HMSSDK版本为:HMSSdk-base-2.5.2.302.aar,HMSSdk-push-2.5.2.302.aar。
注4:从HMS_SDK_2.6.0.301版本开始支持jar包+res资源集成,JPush Android SDK 3.1.6对应测试的华为HMS SDK 版本为:HMS_SDK_2.6.0.301.jar。
注5:Jpush Android SDK 3.2.0对应测试的华为HMS SDK 版本为:HMS_SDK_2.6.3.301.jar。
- 修改minSdkVersion的值
-
注:HMS arr会强制将minSdkVersion修改为14。如果当前app使用minSdkVersion的值小14,则需要使用tools避免被强制覆盖。
-
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" ··· > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21" tools:overrideLibrary="com.huawei.android.hms.base,com.huawei.android.hms.push"/>
配置HMSSDKPush必须的组件
-
<provider android:name="com.huawei.hms.update.provider.UpdateProvider" android:authorities="您应用的包名.hms.update.provider" android:exported="false" android:grantUriPermissions="true"> </provider> <!--receiver android:name="com.huawei.hms.support.api.push.PushEventReceiver"> <intent-filter> <接收通道发来的通知栏消息,兼容老版本Push,在新版的 3.2.0的SDK 需要注释此receiver> <action android:name="com.huawei.intent.action.PUSH"/> </intent-filter> </receiver-->
- 配置接收HMS消息的广播接收器
-
<receiver android:name="cn.jpush.android.service.PluginHuaweiPlatformsReceiver"> <intent-filter> <!--必须,用于接收token--> <action android:name="com.huawei.android.push.intent.REGISTRATION"/> <!--必须,用于接收消息--> <action android:name="com.huawei.android.push.intent.RECEIVE"/> <!--可选,用于点击通知栏或通知栏上的按钮后触发onEvent回调--> <action android:name="com.huawei.android.push.intent.CLICK"/> <!--可选,查看push通道是否连接,不查看则不需要--> <action android:name="com.huawei.intent.action.PUSH_STATE"/> </intent-filter> <meta-data android:name="CS_cloud_ablitity" android:value="successRateAnalytics"/> </receiver>
- 替换HMS的appid
-
在华为控制台上获取注册应用的appid,并填充在manifest如下所示的位置。(不要遗漏前缀appid=)
-
<meta-data android:name="com.huawei.hms.client.appid" android:value="appid=您的应用对应华为的appID"/>
- 在build.gradle中配置在华为后台添加的指纹证书对应的签名
-
注:HMS服务必须要求app签名才能注册成功。指纹证书是在终端采用keytool-list-v-keystorekeystorefileName获取偶对应的指纹证书。
-
signingConfigs{ release{ storeFilefile("release.keystore")//签名文件的path storePassword"123456" keyAlias"android.keystore" keyPassword"123456" } } buildTypes{ release{ minifyEnabledtrue proguardFiles'proguard-rules.pro' signingConfig signingConfigs.release } debug{ minifyEnabledfalse signingConfig signingConfigs.release } }
3、华为SDK的编译混淆问题
如果使用了proguard,需要在配置文件中加入,可以防止一个误报的warning导致无法成功编译
-
–keepclasscom.huawei.hms.**{*;}
4、缺少HMS agent的解决方法
1. 将同级目录下的HMSSdk-agent.aar 文件复制到工程的libs目录下
2. 在build.gradle文件中增加如下:
-
3. 在build.gradle文件中将HMSSdk-agent.aar加入dependenciesrepositories{ flatDir{ dirs 'libs' } }
-
dependencies { compile(name: 'HMSSdk-agent', ext: 'aar') }
4.增加混淆配置
-
-dontwarn com.huawei.** -keep public class * extends android.app.Activity -keep interface com.huawei.android.hms.agent.common.INoProguard {*;} -keep class * extends com.huawei.android.hms.agent.common.INoProguard {*;}
注:当前此方法仅仅适用于使用极光集成华为推送华为检测不通过的临时解决方案,当有接入华为的支付,sns等其它sdk时当前方法时不适用的,请知悉。
-
5、新增兼容华为HMSSDK接口
HMSconnect失败时,需要根据错误码来判断是否能通过用户行为来解决该错误,所以增加新的接口来适配此种行为。接口所在类名为:cn.jpush.android.api.JPluginPlatformInterface,以下所有接口需要在Activity中调用,并且Activity如果调用相关接口就必须全部调用.漏掉一个接口则会导致内存泄漏或功能异常。如果在Activity中没有调用相关接口,在HMSSDK初始化失败并且可以通过用户行为解决的错误则会没有入口解决。
注1:以上内容中“用户行为”指app使用者的操作行为,一般情况下就是点击HMS插件升级提示。
注2:本部分的内容主要适用于华为手机上的华为移动服务框架版本太低,导致华为通道初始化失败,此接口可以引导客户去升级华为移动服务框架,用以启用华为的厂商通道。如果您不需要对手机上的华为移动服务框架进行检查,可以跳过此部分,此时手机依旧走极光通道。
示例代码:
-
public class MainActivity extends Activity{ private JPluginPlatformInterface pHuaweiPushInterface; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initView(); pHuaweiPushInterface = new JPluginPlatformInterface(this.getApplicationContext()); } @Override public void onStart() { super.onStart(); pHuaweiPushInterface.onStart(this); } @Override public void onStop() { super.onStop(); pHuaweiPushInterface.onStop(this); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //JPush中调用HMS SDK解决错误的接口传入的requestCode为10001,开发者调用是请注意不要同样使用10001 if(requestCode == JPluginPlatformInterface.JPLUGIN_REQUEST_CODE) { pHuaweiPushInterface.onActivityResult(this, requestCode, resultCode, data); } } }
6、点击通知跳转到指定Activity
- 说明
-
华为push允许开发者在推送通知的时候传入自定义的intenturi字符串,当用户点击了该通知,系统会根据uri的值过滤出匹配的Activity,并打开Activity,达到跳转的目的。
注1:此功能从JPushAndroidSDK3.0.9开始支持。
注2:此功能需要服务器端与Android端联合修改与调试。
- 服务端使用方式
-
在pushapi的payload中的"notification"的"android"节点下添加以下字段:
关键字
类型
示例
说明
uri_activity
String
"cn.jpush.android.ui.OpenClickActivity"
该字段用于指定开发者想要打开的activity,值为activity节点的"android:name"属性值。
示例代码:
-
{ "platform": [ "android" ], "audience": "all", "notification": { "android": { "alert": "在线alert003", "title": "在线title003", "uri_activity": "com.example.jpushdemo.OpenClickActivity" } }, "message": { "msg_content": "自定义消息内容003" } }
极光提供服务端JAVASDK,下载地址https://github.com/jpush/jpush-api-java-client/tree/huawei,内含有example样例。可以拉取最新的代码自行打包,也可以直接使用libs文件夹下的jar。
示例代码如下:
注:setUriActivity()方法传递的参数在非华为机型上做无效处理。
-
public static PushPayload buildPushObject_huawei() { Notification notification = Notification.newBuilder() .addPlatformNotification(AndroidNotification.newBuilder() .setAlert(ALERT) .setBigPicPath("path to big picture") .setBigText("long text") .setBuilderId(1) .setCategory("CATEGORY_SOCIAL") .setStyle(1) .setTitle("Alert test") .setPriority(1) .setAlert(ALERT) .setUriActivity("com.example.jpushdemo.OpenClickActivity") .build()) .build(); return PushPayload.newBuilder() .setPlatform(Platform.android()) .setAudience(Audience.newBuilder() .addAudienceTarget(AudienceTarget.alias("123321")).build()) .setNotification(notification) .setMessage(Message.content(MSG_CONTENT)) .build(); }
- Android端配置步骤
-
1.AndroidManifest.xml中配置点击通知要打开的Activity
-
<activity android:name="您配置的activity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
注:android:exported属性必须设置为true,并增加示例中的intent-filter,否则会导致无法收到通知。
2.获取通知相关信息
目前启动配置的activity都是使用Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK方式启动,只需要在您配置的activity中的onCreate方法中进行处理,获取通知信息。通过getIntent().getData()获取到Intent数据。获取到的数据是JSON字符串,通过解析可以获得通知相关内容。
JSON示例如下:
-
{ "msg_id": "123456", "n_content": "thisiscontent", "n_extras": { "key1": "value1", "key2": "value2" }, "n_title": "thisistitle", "rom_type": 0 }
JSON内容字段说明:
字段
取值类型
描述
msg_id
String
通过此key获取到通知的msgid
n_title
String
通过此key获取到通知标题
n_content
String
通过此key获取到通知内容
n_extras
String
通过此key获取到通知附加字段
rom_type
byte
通过此key获取到下发通知的平台。得到值说明:byte类型的整数,0为极光,1为小米,2为华为,3为魅族,4为OPPO,8为FCM。
注:rom_type用于点击事件的上报,一般情况下开发者只需要取到该字段的值用于上报,不需要关心具体取值。
3.通知点击上报
解析通知内容后,需主动调用接口来进行通知点击上报,上报接口如下:
-
/** * context 上下文 * msgId 消息ID * whichPushSDK 收到推送的平台,即 rom_type 字段的取值。 **/ JPushInterface.reportNotificationOpened(Context context, String msgId, byte whichPushSDK);
注:点击上报必须传入正确的whichPushSDK参数,否则会造成统计数据错误。
4.富媒体调整
在AndroidManifest.xml中将PushActivity、PopWinActivity的android:exported="false"属性修改为true,否则会导致收不到富媒体推送。
5.Activity示例代码
-
package com.example.jpushdemo; import android.app.Activity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.widget.TextView; import org.json.JSONException; import org.json.JSONObject; import cn.jpush.android.api.JPushInterface; /** * Created by jiguang. */ public class OpenClickActivity extends Activity { private static final String TAG = "OpenClickActivity"; /**消息Id**/ private static final String KEY_MSGID = "msg_id"; /**该通知的下发通道**/ private static final String KEY_WHICH_PUSH_SDK = "rom_type"; /**通知标题**/ private static final String KEY_TITLE = "n_title"; /**通知内容**/ private static final String KEY_CONTENT = "n_content"; /**通知附加字段**/ private static final String KEY_EXTRAS = "n_extras"; private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mTextView = new TextView(this); setContentView(mTextView); handleOpenClick(); } /** * 处理点击事件,当前启动配置的Activity都是使用 * Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK * 方式启动,只需要在onCreat中调用此方法进行处理 */ private void handleOpenClick() { Log.d(TAG, "用户点击打开了通知"); if (getIntent().getData() == null) return; String data = getIntent().getData().toString(); Log.w(TAG, "msg content is " + String.valueOf(data)); if (TextUtils.isEmpty(data)) return; try { JSONObject jsonObject = new JSONObject(data); String msgId = jsonObject.optString(KEY_MSGID); byte whichPushSDK = (byte) jsonObject.optInt(KEY_WHICH_PUSH_SDK); String title = jsonObject.optString(KEY_TITLE); String content = jsonObject.optString(KEY_CONTENT); String extras = jsonObject.optString(KEY_EXTRAS); StringBuilder sb = new StringBuilder(); sb.append("msgId:"); sb.append(String.valueOf(msgId)); sb.append("\n"); sb.append("title:"); sb.append(String.valueOf(title)); sb.append("\n"); sb.append("content:"); sb.append(String.valueOf(content)); sb.append("\n"); sb.append("extras:"); sb.append(String.valueOf(extras)); sb.append("\n"); sb.append("platform:"); sb.append(getPushSDKName(whichPushSDK)); mTextView.setText(sb.toString()); //上报点击事件 JPushInterface.reportNotificationOpened(this, msgId, whichPushSDK); } catch (JSONException e) { Log.w(TAG, "parse notification error"); } } private String getPushSDKName(byte whichPushSDK) { String name; switch (whichPushSDK){ case 0: name = "jpush"; break; case 1: name = "xiaomi"; break; case 2: name = "huawei"; break; case 3: name = "meizu"; break; case 4: name = "oppo"; break; case 8: name = "fcm"; break; default: name = "jpush"; } return name; } }
7、集成结果判断
成功
打印结果如下:
-
I/JIGUANG-JPush(12717):[PluginHuaweiPlatformsReceiver]token:0862858030260325300000350600CN01,belongId:1
失败
·缺少华为推送UpdateProvider组件:
-
<provider android:name="com.huawei.hms.update.provider.UpdateProvider" android:authorities="您应用的包名.hms.update.provider" android:exported="false" android:grantUriPermissions="true"> </provider>
提示效果:华为移动服务不是最新,安装运行,提示“华为移动服务版本太旧,更新到最新版本才可用此功能,是否更新?”点击更新,下载安装时会报:解析包时出现错误。会因为华为推送服务app没有更新而不能使用华为推送(走极光通道)。
·manifest配置的华为appid不存在或者尚未在华为控制台上面的应用没有配置push功能。支持的Emui系统下会有如下打印:
-
当前APP打包时keystore的SHA256与华为开发者平台上填入的SHA256不一致时。支持的Emui系统下会有如下打印:D/JIGUANG-JPush:[PluginHuaweiApiClientCallBack]onConnectionFailed:null,connectionResult:907135702
-
D/JIGUANG-JPush:[PluginHuaweiApiClientCallBack]onConnectionFailed:com.example.jpushdemo.MainActivity@1fa9f59,connectionResult:6003
处理方法:检查是否在华为开发者联盟的平台上配置了正确(和打包或者调试的证书一致)的证书指纹。如果不一致请修改成一致,等待15分钟后清理手机端《华为移动服务》应用的缓存。
· 华为集成常见错误码
ErrorCode
原因
处理方式
1
设备上未安装华为移动服务
2
设备上安装的华为移动服务需要升级
3
设备上的华为移动服务已经不可用
说明华为移动服务被禁用了,请到设备系统设置中启用。
6
aidl绑定失败
8
发生内部错误
内部接口出现异常,请联系华为方支持人员。
9
设备上安装的华为移动服务不是真实的
设备上安装的华为移动服务应用有伪造嫌疑,请确认华为移动服务应用来源是否正确。
13
取消
华为移动服务版本过低时,弹出升级对话框,此时用户取消了升级。
14
超时
华为移动服务版本过低时,弹出升级引导,在下载升级包时超时了。
21
设备因太老而不支持
设备版本太低,HMS支持的android最低版本为Android4.0.3。
6002
应用的鉴权信息不存在
6003
证书指纹校验:证书指纹错误
1、检查是否在华为开发者联盟上配置了正确的证书指纹。登录开发者联盟,点击“会员中心”,在“我的产品”点击需要检查证书指纹应用的服务,在“产品服务列表”界面检查“SHA256证书指纹”配置的信息是否和获取的指纹证书一致,如果不一致请修改,修改后请清理华为移动服务缓存。
6004
接口鉴权:权限不存在,未在联盟上申请
请检查当前应用是否在华为开发者联盟创建并申请相关服务。如果检查都正确,请联系华为方支持人员。
6005
接口鉴权:未授权
请检查当前应用是否在华为开发者联盟创建并申请相关服务。如果检查都正确,请联系华为方支持人员。
6006
接口鉴权:授权过期
907135000
传入的参数错误
请检查相关的配置信息是否正确。比如:manifest文件中的appid;是否使用证书签名等。
907135001
内部错误,表示内部出现异常且无法恢复
内部接口出现异常,请联系华为方支持人员。
907135002
服务不存在,调用的接口不存在
请检查构建HuaweiApiClient时设置的API是否正确。
907135702
OpenGW没有配置指纹证书
1、请检查手机网络是否可以正常访问互联网。2、检查是否在华为开发者联盟上配置了正确的证书指纹。登录开发者联盟,点击“会员中心”,在“我的产品”点击需要检查证书指纹应用的服务,在“产品服务列表”界面检查“SHA256证书指纹”配置的信息是否和获取的指纹证书一致,如果不一致请修改。
907135703
OpenGW没有配置Permission
请检查当前应用是否在华为开发者联盟创建并申请相关服务。如果检查都正确,请联系华为方支持人员。
8、华为厂商通道测试方法
- 在您的App中集成极光3.2.0及以上版本的SDK,并且按照「第三方通知通道集成指南」集成所需的厂商SDK;
- 联系极光技术支持确认已在极光的后台配置好了相关的应用信息。如果开通成功了再进行下一个步骤;
- 将集成好的App(测试版本)安装在测试机(需要运行 EMUI版本 5.0及以上的手机)上,并且运行App;
- 保持App在前台运行,尝试对设备进行推送;
- 如果应用收到消息,将App退到后台,并且杀掉所有App进程;
- 再次进行推送,如果能够收到推送,则表明厂商通道集成成功。
-
-
魅族集成指南
-
1、使用JCenter自动化集成步骤
- 确认androidstudio的Project根目录的主gradle中配置了jcenter支持。(新建project默认配置就支持)
-
buildscript{ repositories{ jcenter() } } allprojects{ repositories{ jcenter() } }
在应用module的gradle中dependencies节点添加如下代码:
-
dependencies{ compile'cn.jiguang.sdk.plugin:meizu:3.2.0'//此版本插件仅支持JPushSDK3.2.0及以上版本 }
在应用module的gradle中defaultConfig节点添加如下代码(不要遗漏前缀MZ-):
-
manifestPlaceholders=[ JPUSH_PKGNAME:"您应用的包名" MEIZU_APPKEY:"MZ-您的应用对应的魅族appkey",//魅族平台注册的appkey MEIZU_APPID:"MZ-您的应用对应魅族的appid",//魅族平台注册的appid ]
2、配置AndroidManifest.xml集成步骤
注意:(JCenter自动化集成与配置AndroidManifest.xml集成二者选择一种即可,如果您完成以上步骤,您可以跳过本段)
- 导入极光的插件包的jar
-
将极光提供的libs包中的插件包(jpush-android-plugin-meizu-v3.x.x.jar)和魅族推送包(meizu-push-x.x.x.jar)添加到工程libs目录下。
注1:JPush Android SDK 3.2.0添加了魅族推送包,对应的魅族sdk版本为:meizu-push-3.8.1.jar
- 修改minSdkVersion的值
-
注:魅族推送会强制将minSdkVersion修改为11。如果当前app使用的minSdkVersion的值小于11,则需要使用tools避免被强制覆盖。
-
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" ... > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21" tools:overrideLibrary=" cn.jpush.android.thirdpush.meizu"/>
配置魅族推送sdk所需要的权限
-
<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"/>
配置JPush接受魅族sdk的消息接受类
-
<receiver android:name="cn.jpush.android.service.PluginMeizuPlatformsReceiver"> <intent-filter> <!--接收push消息--> <action android:name="com.meizu.flyme.push.intent.MESSAGE"/> <!--接收register消息--> <action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK"/> <!--接收unregister消息--> <action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK"/> <!--兼容低版本Flyme3推送服务配置--> <action android:name="com.meizu.c2dm.intent.REGISTRATION"/> <action android:name="com.meizu.c2dm.intent.RECEIVE"/> <category android:name="您应用的包名"></category> </intent-filter> </receiver>
将MEIZUAPPKEY与MEIZUAPPID替换为在魅族后台注册对应该应用的AppKey/AppID(不要遗漏前缀MZ-)
-
<meta-data android:name="MEIZU_APPKEY" android:value="MZ-您的应用对应的魅族的APPKEY"/> <meta-data android:name="MEIZU_APPID" android:value="MZ-您的应用对应的魅族的APPID"/>
通过MzPushSDK接收的通知,可设置其通知栏icon,⽅法如下:
在应用的工程目录res/drawable-xxxx/几个文件夹中添加对应不同分辨率的通知栏icon图标,文件名为mz_push_notification_small_icon。如果文件名错误,将无法正确显示该应用的状态栏图 标。魅族手机状态栏icon规范请参考魅族PushSDKDemo中的图片文件。
注:如果没有放入符合规范的icon⽂件,会默认使用应用图标作为通知icon。⽽应用图标不符合魅族的通知栏icon设计规范的话,则会导致通知栏图标无法正确显示。
- 功能说明
-
由于魅族官方的通知内容长度限制为100个字符以内(中英文都算一个),当通知内容(极光的“alert”字段的值)长度超过100时,魅族通道会推送失败。此时调用极光api推送通知时,请在payload 中的 "notification" 的 "android" 节点的"extras"节点添加以下字段:
Key
类型
示例
说明
mzpns_content_forshort
String
"short content"
通知内容(极光的“alert”字段)长度超过100个字时,请在此字段的值传入不超过100个字的通知内容。
json示例代码:
-
{ "platform":[ "android" ], "audience":"all", "notification":{ "android":{ "alert":"在国内 Android 生态中,推送通道都是由终端与云端之间的长链接来维持,严重依赖于应用进程的存活状态。如今一些手机……(省略若干字)……组件即可", "title":"概述", "extras":{ "mzpns_content_forshort":"在国内Android系统上推送严重依赖于应用进程的存活状态。" } } } }
5、集成结果判断
成功
JPush集成成功,魅族sdk打印日志:
-
E/AbstractMessageHandler(12917):currentHandlermessageBasicPushStatus{code='200',message=''}pushId='0XC71516b727f6c0377570f645c0c415c627857667072',Becomeinvalidafter604800seconds} 或者 E/AbstractMessageHandler(12917):currentHandlermessageBasicPushStatus{code='200',message='alreadyregisterPushId,dontregisterfrequently'}pushId='J04760350615d6364567a7a447f0d0f7b017f055d6759',Becomeinvalidafter603767seconds}
失败
·MEIZU_APPKEY、MEIZU_APPID非法,打印日志如下:
-
E/PushPlatformManager(10154):{"code":"1005","message":"参数错误,请参考API文档","value":"","redirect":""} 04-2814:55:14.627:D/AndroidNetworking(10154):executiondone:ANRequest{sequenceNumber='1,mMethod=1,mPriority=MEDIUM,mRequestType=0,mUrl=https://api-push.meizu.com/garcia/api/client/message/registerPush}
·MEIZU_APPKEY、MEIZU_APPID不是同一个魅族应用,打印日志如下:
-
04-2800:13:38.685:E/PushPlatformManager(32757):registerStatusBasicPushStatus{code='1006',message='签名认证失败'}pushId='null',Becomeinvalidafter0seconds} 04-2800:13:38.724:I/AbstractMessageHandler(32728):startRegisterStatusHandlermatch 04-2800:13:38.724:E/AbstractMessageHandler(32728):currentmessageTypeMESSAGE_TYPE_PUSH_REGISTER_STATUS
集成错误码
ErrorCode
错误原因
UNKNOWN_ERROR
-1
未知错误
SUCCESS
200
成功
SYSTEM_ERROR
1001
系统错误
SYSTEM_BUSY
1003
服务器忙
PARAMETER_ERROR
1005
参数错误,请参考API文档
INVALID_SIGN
1006
签名认证失败
INVALID_APPLICATION_ID
110000
appId不合法
INVALID_APPLICATION_KEY
110001
appKey不合法
UNSUBSCRIBE_PUSHID
110002
pushId未注册
INVALID_PUSHID
110003
pushId非法
PARAM_BLANK
110004
参数不能为空
APP_IN_BLACK_LIST
110009
应用被加入黑名单
APP_REQUEST_EXCEED_LIMIT
110010
应用请求频率过快
APP_PUSH_TIME_EXCEED_LIMIT
110051
超过该应用的次数限制
APP_REQUEST_PUSH_LIMIT
110019
超过该应用每天推送次数限制
INVALID_APPLICATION_PACKAGENAME
110031
packageName不合法
INVALID_TASK_ID
110032
非法的taskId
INVALID_APPLICATION_SECRET
110033
非法的appSecret
6、魅族厂商通道测试方法
- 在您的App中集成极光3.2.0及以上版本的SDK,并且按照「第三方通知通道集成指南」集成所需的厂商SDK;
- 联系极光技术支持确认已在极光的后台配置好了相关的应用信息。如果开通成功了再进行下一个步骤;
- 将集成好的App(测试版本)安装在测试机(需要运行 Flyme版本 5.1.11.1及以上的手机)上,并且运行App;
- 保持App在前台运行,尝试对设备进行推送;
- 如果应用收到消息,将App退到后台,并且杀掉所有App进程;
- 再次进行推送,如果能够收到推送,则表明厂商通道集成成功。
-
-
FCM集成指南
-
- 导入极光的 FCM插件包的jar
-
将极光提供的libs包中的插件包(jpush-android-plugin-fcm-v3.x.x.jar)添加到工程libs目录下。
- 在android studio 的 Project 根目录的主 gradle 中配置使用jcenter(新建的project默认已配置),具体如下:
-
1、手动配置集成步骤
-
在根级 build.gradle 中 dependencies 节点下添加规则,以纳入 Google 服务插件,可根据 Firebase 发布的版本更新选择最新版本:buildscript { repositories { jcenter() } ...... } allprojets { repositories { jcenter() } }
-
在应用 module 的 build.gradle 文件底部添加 apply plugin 代码行,以启用 gradle 插件:buildscript { dependencies { classpath 'com.google.gms:google-services:4.1.0' } } allprojets { repositories { maven { url "https://maven.google.com" } } }
-
在应用 module 的 gradle 中 dependencies 节点添加如下代码,可根据 Firebase 发布的版本更新选择最新版本:apply plugin: 'com.google.gms.google-services'
-
dependencies { compile 'com.google.firebase:firebase-messaging:17.3.4' }
注1: 添加 FCM SDK 的官方文档(https://firebase.google.com/docs/android/setup?authuser=0)
注2: 编译时如果遇到类似如下错误,拉取FCM依赖失败,请在 Android Studio->SDK Manager->SDK Tools 中将 Google Play Services 和Google Repository 更新到最新版本后再试。
-
Failed to resolve: com.google.firebase:firebase-core:x.x.x Error:(36, 13) Failed to resolve: com.google.firebase:firebase-messaging:x.x.x
FCM 推送会强制将 minSdkVersion 修改为 14。如果当前 app 使用的 minSdkVersion 的值小于14,则需要使用 tools 避免被强制覆盖。
-
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" ... > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21" tools:overrideLibrary=" com.google.android.gms.common.license, com.google.android.gms.tasks.license, com.google.firebase.firebase.common.license, com.google.firebase.firebase.iid.license, com.google.firebase.firebase.messaging.license, com.google.firebase.measurement.impl.license, com.google.firebase.measurement.license, com.google.firebase.firebase_core, com.google.firebase.measurement, com.google.firebase.firebase_common, com.google.firebase.messaging, com.google.firebase.iid, com.google.android.gms, com.google.android.gms.tasks, com.google.firebase.iid.internal, com.google.firebase.analytics.connector, com.google.android.gms.stats, com.google.android.gms.common, com.google.android.gms.measurement.api, com.google.android.gms.ads_identifier, com.google.android.gms.measurement_base, com.google.firebase.analytics.connector.impl, android.support.v4, android.support.compat, android.arch.lifecycle, android.support.mediacompat, android.support.coreutils, android.support.coreui, android.support.fragment, com.google.firebase.measurement_impl"/>
配置JPush接收的FCM SDK的消息服务类
-
<service android:name="cn.jpush.android.service.PluginFCMMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service> <service android:name="cn.jpush.android.service.PluginFCMInstanceIdService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/> </intent-filter> </service>
在 AndroidManifest.xml 中增加如下配置来设置 FCM 通知图标。
-
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/您要配置的通知图标" />
2、点击通知跳转 Activity
- 功能说明
-
FCM 允许开发者在推送通知的时候传入自定义的 intent action 字符串,当用户点击了该通知,系统会根据 action 的值过滤出匹配的Activity ,并打开 Activity,获取推送内容。
- Push API 推送说明
-
在 push api 的 payload 中的 "notification" 的 "android" 节点下添加以下字段:
关键字
类型
示例
说明
uri_action
string
"cn.jpush.android.ui.OpenClickActivity"
该字段用于指定开发者想要打开的 activity。值为该activity下您配置的特殊action name
请求json如下:
-
{ "platform": [ "android" ], "audience": "all", "notification": { "android": { "alert": "在线alert003", "title": "在线title003", "uri_action": "com.example.jpushdemo.OpenClickActivity" } }, "message": { "msg_content": "自定义消息内容003" } }
- APP 端配置
-
1. 在 AndroidManifest.xml 中配置点击通知要打开的 activity
-
<activity android:name="您配置的activity" android:exported="true"> <intent-filter> <action android:name="您配置的特殊action"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
2.获取通知相关信息
在您配置的 activity 中的onCreate方法中进行处理,获取通知信息。
通过 getIntent().getExtras().getString("JMessageExtra") 获取到数据。获取到的数据是 JSON 字符串,通过解析可以获得通知相关内容。
JSON 示例如下:
-
{ "msg_id": "123456", "n_content": "this is content", "n_extras": { "key1": "value1", "key2": "value2" }, "n_title": "this is title", "rom_type": 0 }
JSON 内容字段说明:
字段
取值类型
描述
msg_id
String
通过此key获取到通知的msgid
n_title
String
通过此key获取到通知标题
n_content
String
通过此key获取到通知内容
n_extras
String
通过此key获取到通知附加字段
rom_type
byte
通过此key获取到下发通知的平台。得到值说明:byte类型的整数,0为极光,1为小米,2为华为,3为魅族,4为OPPO,8为FCM。
注: rom_type 用于点击事件的上报,一般情况下开发者只需要取到该字段的值用于上报,不需要关心具体取值。
3.通知点击上报
解析通知内容后,需主动调用接口来进行通知点击上报,上报接口如下:
注: 点击上报必须传入正确的 whichPushSDK 参数,否则会造成统计数据错误。
-
/** * context 上下文 * msgId 消息ID * whichPushSDK 收到推送的平台,即 rom_type 字段的取值。 **/ JPushInterface.reportNotificationOpened(Context context, String msgId, byte whichPushSDK);
4.富媒体调整
为 PushActivity 增加 <action android:name="cn.jpush.android.ui.PushActivity" />。
为 PopWinActivity 增加 <action android:name="cn.jpush.android.ui.PopWinActivity" />。
-
<activity android:name="cn.jpush.android.ui.PushActivity" android:configChanges="orientation|keyboardHidden" android:theme="@android:style/Theme.NoTitleBar"> <intent-filter> <action android:name="cn.jpush.android.ui.PushActivity" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="您的应用的包名" /> </intent-filter> </activity> <activity android:name="cn.jpush.android.ui.PopWinActivity" android:configChanges="orientation|keyboardHidden" android:theme="@style/MyDialogStyle"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="您的应用的包名" /> <action android:name="cn.jpush.android.ui.PopWinActivity"/> </intent-filter> </activity>
5.Activity 示例代码
-
package com.example.jpushdemo; import android.app.Activity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.widget.TextView; import org.json.JSONException; import org.json.JSONObject; import cn.jpush.android.api.JPushInterface; /** * Created by jiguang on 17/7/5. */ public class OpenClickActivity extends Activity { private static final String TAG = "OpenClickActivity"; /**消息Id**/ private static final String KEY_MSGID = "msg_id"; /**该通知的下发通道**/ private static final String KEY_WHICH_PUSH_SDK = "rom_type"; /**通知标题**/ private static final String KEY_TITLE = "n_title"; /**通知内容**/ private static final String KEY_CONTENT = "n_content"; /**通知附加字段**/ private static final String KEY_EXTRAS = "n_extras"; private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mTextView = new TextView(this); setContentView(mTextView); handleOpenClick(); } /** * 处理点击事件,当前启动配置的Activity都是使用 * Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK * 方式启动,只需要在onCreat中调用此方法进行处理 */ private void handleOpenClick() { Log.d(TAG, "用户点击打开了通知"); String data = null; //获取FCM平台附带的jpush信息 if (getIntent().getData() != null) { data = getIntent().getData().toString(); } //获取FCM平台附带的jpush信息 if(TextUtils.isEmpty(data) && getIntent().getExtras() != null){ data = getIntent().getExtras().getString("JMessageExtra"); } Log.w(TAG, "msg content is " + String.valueOf(data)); if (TextUtils.isEmpty(data)) return; try { JSONObject jsonObject = new JSONObject(data); String msgId = jsonObject.optString(KEY_MSGID); byte whichPushSDK = (byte) jsonObject.optInt(KEY_WHICH_PUSH_SDK); String title = jsonObject.optString(KEY_TITLE); String content = jsonObject.optString(KEY_CONTENT); String extras = jsonObject.optString(KEY_EXTRAS); StringBuilder sb = new StringBuilder(); sb.append("msgId:"); sb.append(String.valueOf(msgId)); sb.append("\n"); sb.append("title:"); sb.append(String.valueOf(title)); sb.append("\n"); sb.append("content:"); sb.append(String.valueOf(content)); sb.append("\n"); sb.append("extras:"); sb.append(String.valueOf(extras)); sb.append("\n"); sb.append("platform:"); sb.append(getPushSDKName(whichPushSDK)); mTextView.setText(sb.toString()); //上报点击事件 JPushInterface.reportNotificationOpened(this, msgId, whichPushSDK); } catch (JSONException e) { Log.w(TAG, "parse notification error"); } } private String getPushSDKName(byte whichPushSDK) { String name; switch (whichPushSDK){ case 0: name = "jpush"; break; case 1: name = "xiaomi"; break; case 2: name = "huawei"; break; case 3: name = "meizu"; break; case 4: name = "oppo"; break; case 8: name = "fcm"; break; default: name = "jpush"; } return name; } }
3、FCM 测试方法
- 在您的App中集成极光3.2.0及以上版本的SDK,并且按照「第三方通知通道集成指南」集成所需的厂商SDK;
- 联系极光技术支持确认已在极光的后台配置好了相关的应用信息。如果开通成功了再进行下一个步骤;
- 将技术支持所给的debug版本的jcore替换掉项目中的版本,然后在极光初始化之前加上如下代码
-
JCoreInterface.testCountryCode("us"); JPushInterface.init(this);
- 将集成好的App(测试版本)安装在测试机(需要GooglePlay服务为系统服务且版本不低于11.0.4)上,然后翻墙,并且运行App;
- 保持App在前台运行,尝试对设备进行推送;
- 如果应用收到消息,将App退到后台(进入省电模式,或后台驻留),强行停止应用可能收不到;
- 再次进行推送,如果能够收到推送,则表明FCM通道集成成功。
-
- OPPO集成指南
-
1、使用JCenter自动化集成步骤
- 确认androidstudio的Project根目录的主gradle中配置了jcenter支持。(新建project默认配置就支持)。
-
buildscript{ repositories{ jcenter() } } allprojects{ repositories{ jcenter() } }
在应用module的gradle中dependencies节点添加如下代码:
-
dependencies{ compile'cn.jiguang.sdk.plugin:oppo:3.1.8'//此版本插件仅支持JPushSDK3.1.8及以上版本 }
在应用module的gradle中defaultConfig节点添加如下代码(不要遗漏前缀OP-):
-
manifestPlaceholders=[ JPUSH_PKGNAME:"您应用的包名" //设置manifest.xml中的变量 OPPO_APPKEY : "OP-您的应用对应OPPO的APPKEY", // OPPO平台注册的appkey OPPO_APPID : "OP-您的应用对应OPPO的APPID", // OPPO平台注册的appid OPPO_APPSECRET: "OP-您的应用对应OPPO的APPSECRET",//OPPO平台注册的appsecret ]
2、配置AndroidManifest.xml集成步骤
注意:(JCenter自动化集成与配置AndroidManifest.xml集成二者选择一种即可,如果您完成以上步骤,您可以跳过本段)
- 导入极光的插件包以及OPPO的SDK的jar
-
将极光提供的libs包中的jpush-android-plugin-oppo-v3.x.x.jar(OPPO插件包)及com.coloros.mcssdk.jar (OPPO推送包)导入到工程libs/目录下。
- 配置OPPO推送所需要的权限
-
<uses-permission android:name="com.coloros.mcs.permission.RECIEVE_MCS_MESSAGE"/>
配置OPPO 推送的必须的组件
-
<service android:name="cn.jpush.android.service.PluginOppoPushService"> <intent-filter> <action android:name="com.coloros.mcs.action.RECEIVE_MCS_MESSAGE" /> </intent-filter> </service>
配置OPPO 推送的相关参数(不要遗漏前缀OP-)
-
<meta-data android:name="OPPO_APPKEY" android:value="OP-您的应用对应的OPPO的APPKEY" /> <meta-data android:name="OPPO_APPID" android:value="OP-您的应用对应的OPPO的APPID" /> <meta-data android:name="OPPO_APPSECRET" android:value="OP-您的应用对应的OPPO的APPSECRET" />
3.OPPO SDK的编译混淆问题
如果使用了proguard,需要在配置文件中加入,可以防止一个误报的warning导致无法成功编译
-
-dontwarn com.coloros.mcsdk.** -keep class com.coloros.mcsdk.** { *; }
4、通知内容长度兼容
- 功能说明
- 由于 OPPO 官方的通知内容长度限制为200个字数以内(中英文都算一个),当通知内容(极光的“alert”字段的值)长度超过200字,OPPO通道会推送失败。此时调用极光api推送通知,请在payload 中的 "notification" 的 "android" 节点的"extras"节点添加以下字段:
Key
类型
示例
说明
oppns_content_forshort
String
"short content"
通知内容(极光的“alert”字段)长度超过200个字时,请在此字段的值传入不超过200个字的通知内容。
json示例代码:
-
{ "platform":[ "android" ], "audience":"all", "notification":{ "android":{ "alert":"在国内 Android 生态中,推送通道都是由终端与云端之间的长链接来维持,严重依赖于应用进程的存活状态。如今一些手机……(省略若干字)……组件即可", "title":"概述", "uri_ action":"com.example.jpushdemo.OpenClickActivity", "extras":{ "oppns_content_forshort":"在国内Android系统上推送严重依赖于应用进程的存活状态。" } } } }
5、点击通知跳转到指定Activity
- 说明
-
OPPO 允许开发者在推送通知的时候传入自定义的 intent action 字符串,当用户点击了该通知,系统会根据 action 的值过滤出匹配的 Activity,并打开 Activity,获取推送内容。若不配置,点击通知则直接打开应用主页。
- 服务端使用方式
-
在push api的payload中的"notification"的"android"节点下添加以下字段:
关键字
类型
示例
说明
uri_action
String
"com.example.jpushdemo.OpenClickActivity"
该字段用于指定开发者想要打开的 activity。值为该activity下您配置的特殊action name
示例代码:
-
{ "platform":[ "android" ], "audience":"all", "notification":{ "android":{ "alert":"在线alert003", "title":"在线title003", "uri_action":"com.example.jpushdemo.OpenClickActivity" } }, "message":{ "msg_content":"自定义消息内容003" } }
极光提供服务端JAVASDK,下载地址https://github.com/jpush/jpush-api-java-client/tree/huawei内含有example样例。可以拉取最新的代码自行打包,也可以直接使用libs文件夹下的jar。
示例代码如下:
-
public static PushPayload buildPushObject_huawei() { Notification notification = Notification.newBuilder() .addPlatformNotification(AndroidNotification.newBuilder() .setAlert(ALERT) .setBigPicPath("path to big picture") .setBigText("long text") .setBuilderId(1) .setCategory("CATEGORY_SOCIAL") .setStyle(1) .setTitle("Alert test") .setPriority(1) .setAlert(ALERT) .setUriAction("com.example.jpushdemo.OpenClickActivity") .build()) .build(); return PushPayload.newBuilder() .setPlatform(Platform.android()) .setAudience(Audience.newBuilder() .addAudienceTarget(AudienceTarget.alias("123321")).build()) .setNotification(notification) .setMessage(Message.content(MSG_CONTENT)) .build(); }
- APP端配置
-
1. 在 AndroidManifest.xml 中配置点击通知要打开的 activity
-
<activity android:name="您配置的activity" android:exported="true"> <intent-filter> <action android:name="您配置的特殊action"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
2.获取通知相关信息
在您配置的 activity 中的onCreate方法中进行处理,获取通知信息。
通过 getIntent().getExtras().getString("JMessageExtra") 获取到数据。获取到的数据是 JSON 字符串,通过解析可以获得通知相关内容。
JSON 示例如下:
-
{ "msg_id":"123456", "n_content":"this is content", "n_extras":{ "key1":"value1", "key2":"value2" }, "n_title":"this is title", "rom_type":0 }
JSON 内容字段说明:
字段
取值类型
描述
msg_id
String
通过此key获取到通知的msgid
n_title
String
通过此key获取到通知标题
n_content
String
通过此key获取到通知内容
n_extras
String
通过此key获取到通知附加字段
rom_type
byte
通过此key获取到下发通知的平台。得到值说明:byte类型的整数,0为极光,1为小米,2为华为,3为魅族,4为OPPO,8为FCM。
注: rom_type 用于点击事件的上报,一般情况下开发者只需要取到该字段的值用于上报,不需要关心具体取值。
3.通知点击上报
解析通知内容后,需主动调用接口来进行通知点击上报,上报接口如下:
注: 点击上报必须传入正确的 whichPushSDK 参数,否则会造成统计数据错误。
-
/** * context 上下文 * msgId 消息ID * whichPushSDK 收到推送的平台,即 rom_type 字段的取值。 **/ JPushInterface.reportNotificationOpened(Context context, String msgId, byte whichPushSDK);
4.富媒体调整
为 PushActivity 增加 <action android:name="cn.jpush.android.ui.PushActivity" />。
为 PopWinActivity 增加 <action android:name="cn.jpush.android.ui.PopWinActivity" />。
-
<activity android:name="cn.jpush.android.ui.PushActivity" android:configChanges="orientation|keyboardHidden" android:theme="@android:style/Theme.NoTitleBar"> <intent-filter> <action android:name="cn.jpush.android.ui.PushActivity" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="您的应用的包名" /> </intent-filter> </activity>
5.Activity 示例代码
package com.example.jpushdemo; import android.app.Activity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.widget.TextView; import org.json.JSONException; import org.json.JSONObject; import cn.jpush.android.api.JPushInterface; /** * Created by jiguang. */ public class OpenClickActivity extends Activity { private static final String TAG = "OpenClickActivity"; /**消息Id**/ private static final String KEY_MSGID = "msg_id"; /**该通知的下发通道**/ private static final String KEY_WHICH_PUSH_SDK = "rom_type"; /**通知标题**/ private static final String KEY_TITLE = "n_title"; /**通知内容**/ private static final String KEY_CONTENT = "n_content"; /**通知附加字段**/ private static final String KEY_EXTRAS = "n_extras"; private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mTextView = new TextView(this); setContentView(mTextView); handleOpenClick(); } /** * 处理点击事件,当前启动配置的Activity都是使用 * Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK * 方式启动,只需要在onCreat中调用此方法进行处理 */ private void handleOpenClick() { Log.d(TAG, "用户点击打开了通知"); String data = null; //获取华为平台附带的jpush信息 if (getIntent().getData() != null) { data = getIntent().getData().toString(); } //获取fcm/oppo平台附带的jpush信息 if(TextUtils.isEmpty(data) && getIntent().getExtras() != null){ data = getIntent().getExtras().getString("JMessageExtra"); } Log.w(TAG, "msg content is " + String.valueOf(data)); if (TextUtils.isEmpty(data)) return; try { JSONObject jsonObject = new JSONObject(data); String msgId = jsonObject.optString(KEY_MSGID); byte whichPushSDK = (byte) jsonObject.optInt(KEY_WHICH_PUSH_SDK); String title = jsonObject.optString(KEY_TITLE); String content = jsonObject.optString(KEY_CONTENT); String extras = jsonObject.optString(KEY_EXTRAS); StringBuilder sb = new StringBuilder(); sb.append("msgId:"); sb.append(String.valueOf(msgId)); sb.append("\n"); sb.append("title:"); sb.append(String.valueOf(title)); sb.append("\n"); sb.append("content:"); sb.append(String.valueOf(content)); sb.append("\n"); sb.append("extras:"); sb.append(String.valueOf(extras)); sb.append("\n"); sb.append("platform:"); sb.append(getPushSDKName(whichPushSDK)); mTextView.setText(sb.toString()); //上报点击事件 JPushInterface.reportNotificationOpened(this, msgId, whichPushSDK); } catch (JSONException e) { Log.w(TAG, "parse notification error"); } } private String getPushSDKName(byte whichPushSDK) { String name; switch (whichPushSDK){ case 0: name = "jpush"; break; case 1: name = "xiaomi"; break; case 2: name = "huawei"; break; case 3: name = "meizu"; break; case 4: name = "oppo"; break; case 8: name = "fcm"; break; default: name = "jpush"; } return name; } }
成功
JPush集成OPPO sdk成功 打印日志:
-
D/JIGUANG-JPush: [PluginOppoPushService] processMessage type:4105,messageID:0,taskID:null,appPackage:xxxxxxx,registerID:null,sdkVersion:null,command:12289,responseCode:0,content:CN_7a4511397d4b453e19abf6f0ada40c99 [OPushHelper] OPush registerID is CN_7a4511397d4b453e19abf6f0ada40c99
7、OPPO厂商通道测试方法
- 在您的App中集成极光3.2.0及以上版本的SDK,并且按照「第三方通知通道集成指南」集成所需的厂商SDK;
- 联系极光技术支持确认已在极光的后台配置好了相关的应用信息。如果开通成功了再进行下一个步骤;
- 将集成好的App(测试版本)安装在测试机(需要运行 ColorOS版本 3.1及以上的手机)上,并且运行App
- 保持App在前台运行,尝试对设备进行推送;
- 如果应用收到消息,将App退到后台,并且杀掉所有App进程;
- 再次进行推送,如果能够收到推送,则表明厂商通道集成成功。
- vivo集成指南
-
1、使用JCenter自动化集成步骤
- 确认androidstudio的Project根目录的主gradle中配置了jcenter支持。(新建project默认配置就支持)。
-
在应用module的gradle中dependencies节点添加如下代码:buildscript{ repositories{ jcenter() } } allprojects{ repositories{ jcenter() } }
-
dependencies{ compile 'cn.jiguang.sdk.plugin:vivo:3.x.x'//此版本插件仅支持JPushSDK3.2.0及以上版本 }
在应用module的gradle中defaultConfig节点添加如下代码:
-
manifestPlaceholders=[ JPUSH_PKGNAME:"您应用的包名" //设置manifest.xml中的变量 VIVO_APPKEY : "您的应用对应的vivo的AppKey", // VIVO平台注册的appkey VIVO_APPID : "您的应用对应的vivo的AppID", // VIVO平台注册的appid ]
2、配置AndroidManifest.xml集成步骤
注意:(JCenter自动化集成与配置AndroidManifest.xml集成二者选择一种即可,如果您完成以上步骤,您可以跳过本段)
- 导入极光的插件包以及vivo的SDK的jar
-
将极光提供的libs包中的jpush-android-plugin-vivo-v3.x.x.jar(vivo插件包)及pushsdk_v2.3.1.jar (vivo推送包)导入到工程libs/目录下。
- 配置vivo 推送的必须的组件
-
<receiver android:name="cn.jpush.android.service.PluginVivoMessageReceiver"> <intent-filter> <!-- 接收 push 消息 --> <action android:name="com.vivo.pushclient.action.RECEIVE" /> </intent-filter> </receiver> <service android:name="com.vivo.push.sdk.service.CommandClientService" android:exported="true" /> <activity android:name="com.vivo.push.sdk.LinkProxyClientActivity" android:exported="false" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
配置vivo 推送的相关参数
<meta-data android:name="com.vivo.push.api_key" android:value="您的应用对应的vivo的AppKey" /> <meta-data android:name="com.vivo.push.app_id" android:value="您的应用对应的vivo的AppID" />
3、vivo SDK的编译混淆问题
若需要混淆 app,请在混淆文件中添加以下说明,防止 SDK 内容被二次混淆
-
-dontwarn com.vivo.push.** -keep class com.vivo.push.**{*; } -keep class com.vivo.vms.**{*; }
4、集成结果判断
成功
JPush集成vivo sdk成功 打印日志
-
I/JIGUANG-JPush: [PluginPlatformRidUpdate] onUpdateRidSuccess rid:18263 ,pluginPlatformRegIDBean:PluginPlatformRegIDBean{pluginPlatformType=5, regid='15480619114881085348378', rid=18263, retryCount=0}
5、vivo厂商通道测试方法
- 在您的App中集成极光3.2.0及以上版本的SDK,并且按照「第三方通知通道集成指南」集成所需的厂商SDK;
- 联系极光技术支持确认已在极光的后台配置好了相关的应用信息。如果开通成功了再进行下一个步骤;
- 将集成好的App(测试版本)安装在测试机(需要支持vivo推送的设备)上,并且运行App
- 保持App在前台运行,尝试对设备进行推送;
- 如果应用收到消息,将App退到后台,并且杀掉所有App进程;
- 再次进行推送,如果能够收到推送,则表明厂商通道集成成功。
-
6、vivo厂商通道限制
- 推送鉴权限制:一天限制调用不超过 10000 次。
- 目前vivo手机接收的消息为7:00-23:00,服务器允许推送时间为7:00-22:00,单推不受此时间限制。
- 在限制时间之外发送的群推或全推,会被抛弃,但是不计算在发送次数限制中。
- 对接入的应用,发送总量默认为该应用的Push SDK订阅数,每天根据Push SDK订阅数更新推送总量(不限制单推和群推的比例,仅限制当天推送总量)。
- 对新接入的APP,有最低保护阈值,即当天最低可推送量为10000。
- 用户可以收到的单推数量不受限制,群推消息只能收到5条。
- 单推和群推的接口调用次数会分别计算进消息总数里面;
- 用户接收条数只要消息到达了客户端就会算,例如消息到达客户端后因为其他原因没有展示出来,这种也会计入接收条数中;发送失败等其他消息没有到达客户端的情况不计入接收总数。
- 消息数限制,单推占总用户数的10%, 群推占总用户数的90%
- 目前SDK仅支持下表中的机型和对应的系统及以上系统。