前言
在极光推送(一)——配置中讲过了极光推送的配置,这节讲讲极光推送的使用
参考文档
极光官网
下面以我写的demo为例进行讲解.
一.先展示我jpush文件结构

里面有6个类,它们的解释如下:
JpushConfig --------- 极光推送方法类,外部调用所有有关极光推送的方法,都通过此类
JpushHelper --------- 极光推送中tag,alias的设置,删除等具体逻辑均在此类中进行
TagAliasBean -------- 设置极光推送的tag,alias需要的model类
JpushReceiver ------- 定义极光推送的广播类,用于接收极光推送的消息
JpushContract -------- 处理极光推送消息的接口
JpushPresenter ------ 极光推送消息处理的具体类,该类实现JpushContract接口,
用户需要处理的极光消息均在此类中做具体处理
ok,下面来具体讲讲每个类。
二.TagAliasBean设置极光的model类
极光推送的设置无非涉及到一个tag,一个alias的操作,这里将要设置的tag和alias统一封装到TagAliasBean,便于后续处理,以下为TagAliasBean代码:
package com.jpushdemo.jpush;
import java.util.Set;
/**
* Title:
* Description:
* <p>
* Created by pei
* Date: 2017/11/30
*/
public class TagAliasBean{
private int action;
private Set<String> tags;
private String alias;
private boolean isAliasAction;
public int getAction() {
return action;
}
public void setAction(int action) {
this.action = action;
}
public Set<String> getTags() {
return tags;
}
public void setTags(Set<String> tags) {
this.tags = tags;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public boolean isAliasAction() {
return isAliasAction;
}
public void setAliasAction(boolean aliasAction) {
isAliasAction = aliasAction;
}
}
其中 action为增删改查的类型,tags为要设置的tag集合,alias为要设置的别名,isAliasAction则用来表示当前操作的data是否为alias。
三.JpushHelper类
此类实现tag和alias相关操作(添加,删除,设置等)的具体实现细节
package com.jpushdemo.jpush;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.SparseArray;
import com.jpushdemo.app.AppContext;
import com.jpushdemo.util.LogUtil;
import com.jpushdemo.util.NetUtil;
import java.lang.ref.WeakReference;
import cn.jpush.android.api.JPushInterface;
import cn.jpush.android.api.JPushMessage;
/**
* Title:Tag,Alias逻辑处理相关帮助类
* Description:
* <p>
* Created by pei
* Date: 2017/11/30
*/
public class JpushHelper {
/**增加*/
public static final int ACTION_ADD = 1;
/**覆盖*/
public static final int ACTION_SET = 2;
/**删除部分*/
public static final int ACTION_DELETE = 3;
/**删除所有*/
public static final int ACTION_CLEAN = 4;
/**查询*/
public static final int ACTION_GET = 5;
/**检测**/
public static final int ACTION_CHECK = 6;
/**重新设置messageCode**/
private static final int DELAY_SEND_ACTION=7;
/**重设时长间隔**/
private static final long DELAY_TIME=1000*60;//一分钟
public static int mSequence=1;
private static JpushHelper mInstance;
private SparseArray<TagAliasBean> mTagAliasActionCache = new SparseArray<TagAliasBean>();
private Handler delaySendHandler = new JpushHandler(JpushHelper.this);
private JpushHelper(){}
public static JpushHelper getInstance(){
if(mInstance == null){
synchronized (JpushHelper.class){
if(mInstance == null){
mInstance = new JpushHelper();
}
}
}
return mInstance;
}
public void put(int sequence,TagAliasBean tagAliasBean){
mTagAliasActionCache.put(sequence,tagAliasBean);
}
public TagAliasBean get(int sequence){
return mTagAliasActionCache.get(sequence);
}
public TagAliasBean remove(int sequence){
return mTagAliasActionCache.get(sequence);
}
/**处理tag和alias的操作**/
public void handleAction(int sequence, TagAliasBean tagAliasBean){
Context context= AppContext.getInstance();
if(tagAliasBean==null){
LogUtil.e(JpushHelper.class,"=====tagAliasBean was null=====");
return;
}
put(sequence,tagAliasBean);
if(tagAliasBean.isAliasAction()){
//别名的处理(Alias)
handleAlias(context,sequence,tagAliasBean);
}else{
//标签的处理(Tag)
handleTags(context,sequence,tagAliasBean);
}
}
/**别名的处理(Alias)**/
private void handleAlias(Context context,int sequence, TagAliasBean tagAliasBean){
switch (tagAliasBean.getAction()){
case ACTION_GET://获取
JPushInterface.getAlias(context,sequence);
break;
case ACTION_DELETE://删除
JPushInterface.deleteAlias(context,sequence);
break;
case ACTION_SET://设置
JPushInterface.setAlias(context,sequence,tagAliasBean.getAlias());
break;
default:
LogUtil.e(JpushHelper.class,"====unsupport alias action type===");
break;
}
}
/**标签的处理(Tag)**/
private void handleTags(Context context,int sequence, TagAliasBean tagAliasBean){
switch (tagAliasBean.getAction()) {
case ACTION_ADD://添加
JPushInterface.addTags(context, sequence, tagAliasBean.getTags());
break;
case ACTION_SET://设置
JPushInterface.setTags(context, sequence, tagAliasBean.getTags());
break;
case ACTION_DELETE://删除
JPushInterface.deleteTags(context, sequence, tagAliasBean.getTags());
break;
case ACTION_CHECK://检查
//一次只能check一个tag
String tag = (String)tagAliasBean.getTags().toArray()[0];
JPushInterface.checkTagBindState(context,sequence,tag);
break;
case ACTION_GET://获取
JPushInterface.getAllTags(context, sequence);
break;
case ACTION_CLEAN://清除
JPushInterface.cleanTags(context, sequence);
break;
default:
LogUtil.e(JpushHelper.class,"====unsupport tag action type===");
break;
}
}
/**是否需要重新设置**/
private boolean retryActionIfNeeded(int errorCode,TagAliasBean tagAliasBean){
if(!NetUtil.isNetworkConnected()){
//检测网络链接
LogUtil.e(JpushHelper.class,"=======no network=======");
return false;
}
//返回的错误码为6002 超时,6014 服务器繁忙,都建议延迟重试
if(errorCode == 6002 || errorCode == 6014){
LogUtil.e(JpushHelper.class,"=======need retry=======");
if(tagAliasBean!=null){
Message message = new Message();
message.what = DELAY_SEND_ACTION;
message.obj = tagAliasBean;
delaySendHandler.sendMessageDelayed(message,DELAY_TIME);
return true;
}
}
return false;
}
static class JpushHandler extends Handler{
//弱引用(引用外部类)
WeakReference<JpushHelper>mCls;
JpushHandler(JpushHelper cls){
//构造弱引用
mCls=new WeakReference<JpushHelper>(cls);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//通过弱引用获取外部类.
JpushHelper cls = mCls.get();
//进行非空再操作
if (cls != null) {
switch (msg.what) {
case DELAY_SEND_ACTION:
if (msg.obj != null && msg.obj instanceof TagAliasBean) {
LogUtil.e(JpushHelper.class, "===on delay time===");
JpushHelper.mSequence++;
TagAliasBean tagAliasBean = (TagAliasBean) msg.obj;
cls.put(JpushHelper.mSequence, tagAliasBean);
cls.handleAction(JpushHelper.mSequence, tagAliasBean);
} else {
LogUtil.e(JpushHelper.class, "====unexcepted - msg obj was incorrect===");
}
break;
default:
break;
}
}
}
}
/**tag增删查改的操作会在此方法中回调结果**/
public void onTagOperatorResult(Context context, JPushMessage jPushMessage){
int sequence = jPushMessage.getSequence();
LogUtil.e(JpushHelper.class,"action - onTagOperatorResult, sequence:"+sequence+",tags:"+jPushMessage.getTags());
LogUtil.e(JpushHelper.class,"tags size:"+jPushMessage.getTags().size());
//根据sequence从之前操作缓存中获取缓存记录
TagAliasBean tagAliasBean =get(sequence);
if(tagAliasBean == null){
LogUtil.e(JpushHelper.class,"获取缓存记录失败");
return;
}
if(jPushMessage.getErrorCode() == 0){
LogUtil.e(JpushHelper.class,"action - modify tag Success,sequence:"+sequence);
remove(sequence);
}else{
String logs=null;
if(jPushMessage.getErrorCode() == 6018){
//tag数量超过限制,需要先清除一部分再add
logs = "tag数量超过限制,需要先清除一部分再add";
}
logs += ", errorCode:" + jPushMessage.getErrorCode();
if(!retryActionIfNeeded(jPushMessage.getErrorCode(),tagAliasBean)) {
LogUtil.e(JpushHelper.class,logs);
}
}
};
/**查询某个tag与当前用户的绑定状态的操作会在此方法中回调结果**/
public void onCheckTagOperatorResult(Context context, JPushMessage jPushMessage){
int sequence = jPushMessage.getSequence();
LogUtil.e(JpushHelper.class,"action - onCheckTagOperatorResult, sequence:"+sequence+",checktag:"+jPushMessage.getCheckTag());
//根据sequence从之前操作缓存中获取缓存记录
TagAliasBean tagAliasBean =get(sequence);
if(tagAliasBean == null){
LogUtil.e(JpushHelper.class,"===onCheckTagOperatorResult==获取缓存记录失败==");
return;
}
if(jPushMessage.getErrorCode() == 0){
LogUtil.e(JpushHelper.class,"tagBean:"+tagAliasBean);
remove(sequence);
}else{
if(!retryActionIfNeeded(jPushMessage.getErrorCode(),tagAliasBean)) {
LogUtil.e(JpushHelper.class,"====="+jPushMessage.getErrorCode()+"====");
}
}
}
/**alias相关的操作会在此方法中回调结果**/
public void onAliasOperatorResult(Context context, JPushMessage jPushMessage) {
int sequence = jPushMessage.getSequence();
LogUtil.e(JpushHelper.class,"action - onAliasOperatorResult, sequence:"+sequence+",alias:"+jPushMessage.getAlias());
//根据sequence从之前操作缓存中获取缓存记录
TagAliasBean tagAliasBean =get(sequence);
if(tagAliasBean == null){
LogUtil.e(JpushHelper.class,"===onAliasOperatorResult获取缓存记录失败===");
return;
}
if(jPushMessage.getErrorCode() == 0){
LogUtil.e(JpushHelper.class,"action - modify alias Success,sequence:"+sequence);
remove(sequence);
}else{
if(!retryActionIfNeeded(jPushMessage.getErrorCode(),tagAliasBean)) {
LogUtil.e(JpushHelper.class,"=====alias, errorCode:"+jPushMessage.getErrorCode()+"====");
}
}
}
}
四.JpushConfig类
此类其实是对JpushHelper类中方法的一个提炼,目的是方便用户在activity中调用极光tag和alias设置的方法,用户只需要用JpushConfig去调用极光相关方法就好,无需关注方法的实现细节
package com.jpushdemo.jpush;
import android.content.Context;
import com.jpushdemo.app.AppContext;
import com.jpushdemo.util.StringUtil;
import java.util.LinkedHashSet;
import java.util.Set;
import cn.jpush.android.api.JPushInterface;
/**
* Title:
* Description:
* <p>
* Created by pei
* Date: 2017/11/30
*/
public class JpushConfig {
private Context mContext;
private JpushConfig() {
mContext= AppContext.getInstance();
}
private static class Holder {
private static JpushConfig instance = new JpushConfig();
}
public static JpushConfig getInstance() {
return Holder.instance;
}
/**初始化极光,在Application的oncreate()方法中调用**/
public void initJpush(){
//极光推送
JPushInterface.setDebugMode(true);
JPushInterface.init(mContext);
}
/**添加tag**/
public void addTag(String tag){
handleTag(tag,JpushHelper.ACTION_ADD);
}
/**设置tag**/
public void setTag(String tag){
handleTag(tag,JpushHelper.ACTION_SET);
}
/**删除tag**/
public void deleteTag(String tag){
handleTag(tag,JpushHelper.ACTION_DELETE);
}
/**获取所有tag**/
public void getAllTags(){
handleTag(null,JpushHelper.ACTION_GET);
}
/**清除所有tag**/
public void cleanAllTags(){
handleTag(null,JpushHelper.ACTION_CLEAN);
}
/**检测tag**/
public void checkTag(Set<String> tags){
if(tags==null){
return;
}
TagAliasBean tagAliasBean = new TagAliasBean();
tagAliasBean.setAction(JpushHelper.ACTION_CHECK);
tagAliasBean.setAlias(null);
tagAliasBean.setTags(tags);
tagAliasBean.setAliasAction(false);
JpushHelper.mSequence++;
JpushHelper.getInstance().handleAction(JpushHelper.mSequence,tagAliasBean);
}
/**设置Alias**/
public void setAlias(String alias){
if(StringUtil.isNotEmpty(alias)){
handleAlias(alias,JpushHelper.ACTION_SET);
}
}
/**获取alias**/
public void getAlias(){
handleAlias(null,JpushHelper.ACTION_GET);
}
/**删除alias**/
public void deleteAlias(){
handleAlias(null,JpushHelper.ACTION_DELETE);
}
private void handleTag(String tag,int action){
Set<String> tags = new LinkedHashSet<>();
if(StringUtil.isNotEmpty(tag)){
tags.add(tag);
}
TagAliasBean tagAliasBean = new TagAliasBean();
tagAliasBean.setAction(action);
tagAliasBean.setAlias(null);
tagAliasBean.setTags(tags);
tagAliasBean.setAliasAction(false);
JpushHelper.mSequence++;
JpushHelper.getInstance().handleAction(JpushHelper.mSequence,tagAliasBean);
}
private void handleAlias(String alias,int action){
TagAliasBean tagAliasBean = new TagAliasBean();
tagAliasBean.setAction(action);
tagAliasBean.setAlias(alias);
tagAliasBean.setTags(null);
tagAliasBean.setAliasAction(true);
JpushHelper.mSequence++;
JpushHelper.getInstance().handleAction(JpushHelper.mSequence,tagAliasBean);
}
/**停止极光服务**/
public void stopJpush(){
if(!JPushInterface.isPushStopped(mContext)){
JPushInterface.stopPush(mContext);
}
}
/**恢复极光推送**/
public void resumeJPush(){
JPushInterface.resumePush(mContext);
}
}
JpushConfig类中方法虽多,但我们用到的就那么几个,首先是在项目中自己的application类中初始化极光,需要调用到initJpush()方法,然后是我们在需要设置极光标签(tag)和别名(alias)的地方会用到setTag(String tag)和setAlias(String alias)方法,最后需要注意的是极光服务停止和恢复,即stopJpush()和resumeJPush()方法可能会用到。
然后就是极光消息的获取了,极光消息的获取,我们是通过定义一个广播接收,下面看看广播接收的代码
五.JpushReceiver接收极光消息的广播类
package com.jpushdemo.jpush;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.jpushdemo.util.LogUtil;
import cn.jpush.android.api.JPushInterface;
/**
* 自定义接收器
* <p>
* 如果不定义这个 Receiver,则:
* 1) 默认用户会打开主界面
* 2) 接收不到自定义消息
*/
public class JpushReceiver extends BroadcastReceiver {
private JpushPresenter jpushPresenter = null;
private Context mContext;
@Override
public void onReceive(Context context, Intent intent) {
this.mContext=context;
Bundle bundle = intent.getExtras();
if (bundle == null) {
return;
}
if (jpushPresenter == null) {
jpushPresenter = new JpushPresenter();
}
jpushPresenter.setContext(context);
if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
// SDK 向 JPush Server 注册所得到的注册 全局唯一的 ID
String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
LogUtil.e(JpushReceiver.class, "-Registration Id : " + regId);
//send the Registration Id to your server...
} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
LogUtil.e(JpushReceiver.class, "-推送消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
jpushPresenter.doProcessPushMessage(bundle);
} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
LogUtil.e(JpushReceiver.class, "-推送通知: " + bundle.getString(JPushInterface.EXTRA_ALERT));
jpushPresenter.doProcessPusNotify(bundle);
} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
LogUtil.e(JpushReceiver.class, "-点击推送的通知: " + bundle.getString(JPushInterface.EXTRA_ALERT));
jpushPresenter.doOpenPusNotify(bundle);
} else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {
LogUtil.e(JpushReceiver.class,"-用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));
//在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等..
} else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {
boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);
LogUtil.e(JpushReceiver.class, "-" + intent.getAction() + " connected state change to " + connected);
} else {
LogUtil.e(JpushReceiver.class, "-Unhandled intent - " + intent.getAction());
}
}
}
这是一个静态广播,需要在mainfast中注册,注册代码如下:
<application
android:name=".app.AppContext"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar">
<activity android:name=".ui.MainActivity">
....
.....
</activity>
<!-- Jpush for receive 用户自定义的广播接收器 -->
<receiver
android:name=".jpush.JpushReceiver"
android:enabled="true"
android:exported="false">
<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="com.jpushdemo" />
</intent-filter>
</receiver>
</application>
receiver标签中包含的 <category android:name="com.jpushdemo" />中name需要填当前项目的包名
仔细看JpushReceiver中有一个JpushPresenter对象,虽然JpushReceiver负责接收极光消息,但具体的处理却交给了JpushPresenter类,而JpushPresenter类是实现JpushContract接口的。
六.JpushContract接口类
package com.jpushdemo.jpush;
import android.os.Bundle;
/**
* @author pei
* @date 2016/12/24.19:47
*/
public interface JpushContract {
void doProcessPushMessage(Bundle bundle);
void doProcessPusNotify(Bundle bundle);
void doOpenPusNotify(Bundle bundle);
}
然后是处理消息类JpushPresenter类的代码
七.JpushPresenter具体处理消息类
package com.jpushdemo.jpush;
import android.content.Context;
import android.os.Bundle;
import com.jpushdemo.util.LogUtil;
import cn.jpush.android.api.JPushInterface;
/**
* Title:极光推送具体处理类
* Description:
* <p>
* Created by pei
* Date: 2017/11/30
*/
public class JpushPresenter implements JpushContract {
private Context mContext;
public JpushPresenter() {
}
public void setContext(Context context) {
this.mContext = context;
}
@Override
public void doProcessPushMessage(Bundle bundle) {
String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
LogUtil.e(JpushPresenter.class,"=====doProcessPushMessage=======");
}
@Override
public void doProcessPusNotify(Bundle bundle) {
LogUtil.e(JpushPresenter.class,"=====doProcessPusNotify=======");
}
@Override
public void doOpenPusNotify(Bundle bundle) {
LogUtil.e(JpushPresenter.class,"=====doOpenPusNotify=======");
}
}
八.Jpush在项目中具体使用
在自己项目的application中初始化Jpush
public class AppContext extends Application{
private static AppContext INSTANCE;
public static synchronized AppContext getInstance() {
return INSTANCE;
}
@Override
public void onCreate() {
super.onCreate();
INSTANCE = this;
//初始化极光推送
JpushConfig.getInstance().initJpush();
}
}
在要设置极光tag和alias的地方进行设置
//设置标签
JpushConfig.getInstance().setTag("1.0.1");
//设置别名
JpushConfig.getInstance().setAlias("android");
记得要将上面的''1.0.1"和"android"换成自己的tag和alias。
ok,关于Jpush推送的使用今天就讲到这里了,谢谢哎。
网友评论