极光平台
流程:
客户端集成 极光推送,然后在软件启动的时候,获取RID(也可以自定义别名和标签) 然后上传值给服务器,当触发了某个事件时,进行网络请求,服务器端接收到会通过极光推送,发送推送(给不同标签组)。客户端再去根据不同的需求去接受数据,处理数据
appkey是可以对应 android和苹果端的
对于同一个账号 在不同设备登录(同系统或者不同系统) 不会两个地方都推送,会挤掉前一个设备 只会推送给后面的设备,因为RID更新了
一、注册和配置
按照官方文档配置即可
https://docs.jiguang.cn/jpush/client/Android/android_3m/
比如这里通过jcenter自动配置:
1 project的build.gradle 中
buildscript {
repositories {
google()
jcenter()
}
allprojects {
repositories {
google()
jcenter()
}
}
2 module的build.gradle中
android {
......
defaultConfig {
applicationId "com.xxx.xxx" //JPush上注册的包名.
......
ndk {
//选择要添加的对应cpu类型的.so库。
abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'
// 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
}
manifestPlaceholders = [
JPUSH_PKGNAME : applicationId,
JPUSH_APPKEY : "你的appkey", //JPush上注册的包名对应的appkey.
JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
]
......
}
......
}
dependencies {
......
compile 'cn.jiguang.sdk:jpush:3.1.1' // 此处以JPush 3.1.1 版本为例。
compile 'cn.jiguang.sdk:jcore:1.1.9' // 此处以JCore 1.1.9 版本为例。
......
}
注意:如果在添加以上 abiFilter 配置之后android Studio出现以下提示:
NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin
则在 Project 根目录的gradle.properties文件中添加:
android.useDeprecatedNdk=true
3 Android Manifest中配置必要权限和必要receiver等设置
下载Demo 将 manifest中写的requried的内容复制
问题
Error:Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute provider#cn.jpush.android.service.DataProvider@exported value=(true) from AndroidManifest.xml:63:13-36
is also present at [cn.jiguang.sdk:jpush:3.1.1] AndroidManifest.xml:116:13-37 value=(false).
Suggestion: add 'tools:replace="android:exported"' to <provider> element at AndroidManifest.xml:60:9-64:15 to override.
解析: is also present at 出现了重复配置
解决:将提示的manifest中重复部分注解掉
4 界面初始化中添加:
JPushInterface.setDebugMode(true); // 设置调试模式
JPushInterface.init(this); // 开启JPush
5 自定义Receiver去获取数据 处理数据
在Manifest中,记得一定要添加
<!-- User defined. For test only 用户自定义的广播接收器-->
<receiver
android:name="Your Receiver所在package"
android:exported="false"
android:enabled="true">
<intent-filter>
<action android:name="cn.jpush.android.intent.REGISTRATION" /> <!--Required 用户注册SDK的intent-->
<action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" /> <!--Required 用户接收SDK消息的intent-->
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" /> <!--Required 用户接收SDK通知栏信息的intent-->
<action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" /> <!--Required 用户打开自定义通知栏的intent-->
<action android:name="cn.jpush.android.intent.CONNECTION" /><!-- 接收网络变化 连接/断开 since 1.6.3 -->
<category android:name="主包名" />
</intent-filter>
</receiver>
分析:
动作1 :
< action android:name=”cn.jpush.android.intent.REGISTRATION” />
获取 RegistrationID
一般不需要使用 Registration ID 去 取得自己保存App用户与JPush 用户关系
通过别名与标签更方便
动作2:
< action android:name=”cn.jpush.android.intent.MESSAGE_RECEIVED” />
保存服务器推送下来的消息的标题
Bundle bundle = intent.getExtras();
String title = bundle.getString(JPushInterface.EXTRA_TITLE);
保存服务器推送下来的消息内容
Bundle bundle = intent.getExtras();
String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
保存服务器推送下来的附加字段。这是个 JSON 字符串
Bundle bundle = intent.getExtras();
String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
唯一标识消息的 ID, 可用于上报统计
Bundle bundle = intent.getExtras();
String file = bundle.getString(JPushInterface.EXTRA_MSG_ID);
动作3:
< action android:name=”cn.jpush.android.intent.NOTIFICATION_RECEIVED” />
见官方文档:https://docs.jiguang.cn/jpush/client/Android/android_api/
动作4:
< action android:name=”cn.jpush.android.intent.NOTIFICATION_OPENED” />
如果开发者在 AndroidManifest.xml 里没有配置此 receiver action,则默认点击通知消息打开应用程序的主 Activity,相当于用户点击桌面图标的效果
如果开发者在 AndroidManifest.xml 里配置了此 receiver action,那么,当用户点击通知时,SDK 不会做动作。开发者应该在自己写的 BroadcastReceiver 类里处理,比如打开某 Activity
保存服务器推送下来的通知的标题
Bundle bundle = intent.getExtras();
String title = bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);
保存服务器推送下来的通知内容
Bundle bundle = intent.getExtras();
String content = bundle.getString(JPushInterface.EXTRA_ALERT);
保存服务器推送下来的附加字段。这是个 JSON 字符串
Bundle bundle = intent.getExtras();
String type = bundle.getString(JPushInterface.EXTRA_EXTRA);
唯一标识调整消息的 ID, 可用于上报统计等
Bundle bundle = intent.getExtras();
String file = bundle.getString(JPushInterface.EXTRA_MSG_ID);
动作5:
< action android:name=”cn.jpush.android.intent.NOTIFICATION_CLICK_ACTION” />
只有开发者使用了 MultiActionsNotificationBuilder 构建携带按钮的通知栏的通知时,可通过该 action 捕获到用户点击通知栏按钮的操作,并自行处理
参考文档
动作6:
< action android:name=”cn.jpush.android.intent.CONNECTION” />
JPush 服务的连接状态发生变化。(注:不是指 Android 系统的网络连接状态。)
Bundle bundle = intent.getExtras();
boolean connected = bundle.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);
6 将demo中的Myreceiver复制到自己创建的Receiver类中(如上面的自己创建的类名为JPushReceiver)
public class JPushReceiver extends BroadcastReceiver {
private static final String TAG = "JIGUANGTAG";
@Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
Log.e(TAG, "[JPushReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));
if(bundle!=null){
// 1 获取RegisterID
if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
Log.e("执行了获取RID","执行了获取RID");
String regId;
regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
Log.e(TAG, "[JPushReceiver] 接收Registration Id : " + regId);
} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
// 获取自定义消息(透传消息)
Log.e(TAG, "[JPushReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
processCustomMessage(context, bundle);
} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
// 接受通知的内容
Log.e(TAG, "[JPushReceiver] 接收到推送下来的通知");
int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
Log.e(TAG, "[JPushReceiver] 接收到推送下来的通知的ID: " + notifactionId);
} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
// 接受点击了通知消息后跳转界面操作和获取数据
Log.e(TAG, "[JPushReceiver] 用户点击打开了通知");
//通过获取回传的不同值 去打开不同的自定义的Activity
/*String title = bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);
String content = bundle.getString(JPushInterface.EXTRA_ALERT);*/
String jsonData = bundle.getString(JPushInterface.EXTRA_EXTRA);
/*Log.e(TAG,title);
Log.e(TAG,content);*/
Gson gson = new Gson();
JPushJumpActivityBean jPushJumpActivityBean = gson.fromJson(jsonData,JPushJumpActivityBean.class);
String jumpCode = jPushJumpActivityBean.getJumpCode();
switch (jumpCode) {
case "OA-001":
Intent oa_1 = new Intent(context, OAListActivity.class);
oa_1.putExtra("selectedPosition", 2);
oa_1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
/*oa_1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);*/
context.startActivity(oa_1);
break;
case "OA-002":
Intent oa_2 = new Intent(context, OAListActivity.class);
oa_2.putExtra("selectedPosition", 3);
oa_2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
/*oa_2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);*/
context.startActivity(oa_2);
break;
default:
Log.e(TAG, "哪儿也不跳转~");
break;
}
} else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {
Log.e(TAG, "[JPushReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));
//在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等..
} else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {
// JPush 服务的连接状态发生变化
boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);
Log.w(TAG, "[JPushReceiver]" + intent.getAction() + " connected state change to " + connected);
} else {
Log.e(TAG, "[JPushReceiver] Unhandled intent - " + intent.getAction());
}
}
} catch (Exception e){
e.printStackTrace();
}
}
// 打印所有的 intent extra 数据
private static String printBundle(Bundle bundle) {
StringBuilder sb = new StringBuilder();
for (String key : bundle.keySet()) {
switch (key) {
case JPushInterface.EXTRA_NOTIFICATION_ID:
sb.append("\nkey:").append(key).append(", value:").append(bundle.getInt(key));
break;
case JPushInterface.EXTRA_CONNECTION_CHANGE:
sb.append("\nkey:").append(key).append(", value:").append(bundle.getBoolean(key));
break;
case JPushInterface.EXTRA_EXTRA:
if (TextUtils.isEmpty(bundle.getString(JPushInterface.EXTRA_EXTRA))) {
Log.i(TAG, "This message has no Extra data");
continue;
}
try {
JSONObject json = new JSONObject(bundle.getString(JPushInterface.EXTRA_EXTRA));
Iterator<String> it = json.keys();
while (it.hasNext()) {
String myKey = it.next();
sb.append("\nkey:").append(key).append(", value: [").append(myKey).append(" - ").append(json.optString(myKey)).append("]");
}
} catch (JSONException e) {
Log.e(TAG, "Get message extra JSON error!");
}
break;
default:
sb.append("\nkey:").append(key).append(", value:").append(bundle.getString(key));
break;
}
}
return sb.toString();
}
//send msg to MainActivity
private void processCustomMessage(Context context, Bundle bundle) {
/*if (MainActivity.isForeground) {
String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
Intent msgIntent = new Intent(MainActivity.MESSAGE_RECEIVED_ACTION);
msgIntent.putExtra(MainActivity.KEY_MESSAGE, message);
if (!ExampleUtil.isEmpty(extras)) {
try {
JSONObject extraJson = new JSONObject(extras);
if (extraJson.length() > 0) {
msgIntent.putExtra(MainActivity.KEY_EXTRAS, extras);
}
} catch (JSONException e) {
}
}
LocalBroadcastManager.getInstance(context).sendBroadcast(msgIntent);
}*/
}
}
点不点击通知, 都是能收到数据的 只是 在不同的动作下 使用不同的数据,处理不同的操作
7 (可选) 退出登录(默认软件未启动还是会收到消息) 想要退出登录不接收推送 则 调用这个
注销:
JPushInterface.stopPush(getApplicationContext());
8 重启JPush
JPushInterface.resumePush(getApplicationContext());
9 (可选)设置别名和标签
设置别名标签:(让后台知道当前用户的分类类型)
别名alias与标签tag接口回调触发cn.jpush.android.service.JPushMessageReceiver
回调接口参考文档:
http://docs.jiguang.cn/jpush/client/Android/android_api/ 的 新的消息回调方式说明 部分
设置别名:(新的调用会覆盖之前的设置)
public static void setAlias(Context context, int sequence, String alias);
sequence:用户自定义的操作序列号, 同操作结果一起返回,用来标识一次操作的唯一性
alias:每次调用设置有效的别名
删除别名:
public static void deleteAlias(Context context,int sequence);
查询别名:
public static void getAlias(Context context,int sequence);
设置标签:(可以设置多个唯一标签,但是每次调用该方法也是覆盖逻辑)
public static void setTags(Context context, int sequence,Set tags);
新增标签:(原有基础上新增)
public static void addTags(Context context, int sequence,Set tags);
删除指定标签:
public static void deleteTags(Context context, int sequence,Set tags);
清除所有标签:
public static void cleanTags(Context context, int sequence);
查询所有标签
public static void getAllTags(Context context, int sequence);
问题:
1实际测试发现,按照Demo给的Servicer,Log.d输出不了,可以改成Log.e可以正确输出或者通过下面方法解决
分析:因为使用的是华为Honor系列的手机,他默认关闭了debug的输出
可以:
1 进入拨号界面输入:##2846579##
2 点击后台设置->Log设置 勾选 AP日志
参考:
https://www.baidu.com/link?url=BhbrPdlZXBhPEhWa7-MONFhY7ZQlLBbTRoij8Aykn8rgTyCQZFqPiTlbonA7N2O56RHe_9xIlzeVatXfUDw-K_M4TgM_xjDDEAXgCgrFw27&wd=&eqid=d9c49c7c0001ee5b000000065a98e64f
2 获取不了RegistrationID
分析: 需要在极光连接注册成功后,才获取RID,否则RID获取为空
解决: 延迟获取RID
3 在onReceive中获取不了 registerID 但是可以获取其他的数据
有博主说onReceive中是获取不了registerID的
则 在别的地方通过 JPushInterface.getRegistrationID(this); 方式获取 (注意要等极光连接注册成功后再获取)
注意:没有res/drawable-xxxx/jpush_notification_icon这个资源默认使用应用图标作为通知icon,在5.0以上系统将应用图标作为statusbar icon可能显示不正常,用户可定义没有阴影和渐变色的icon替换这个文件,文件名不要变
客户端错误码:
http://docs.jiguang.cn/jpush/client/Android/android_api/ 客户端错误码定义 部分
通知和自定义消息
通知是 会提示的 在通知栏处显示的
而自定义消息默认不会被SDK展示到通知栏上,相当于透传消息