为什么需要推送?
通过推送消息可以形成和用户的互动,进一步带来产品使用度的提升。
消息类型
[通知栏消息] 由操作系统展现在通知栏的消息,用户可以点击消息并且打开应用
[应用内消息] 直接透传给Android终端的消息,不会主动展示在通知栏,由App在接受后进行处理
推送流程【了解】
[Push_Token] Push_Token是由信鸽生成的,对一个设备的标识(下文简称Token),用于对设备进行推送,是推送的最小单位。
[设备推送注册] 设备的推送注册,表示着设备和信鸽服务器成功的建立了长连接。设备将会和服务器进行通信
[长连接] 长连接是信鸽 Android SDK 维持的和信鸽后台的持续连接,在连接有效时能够将推送消息进行下发和展示。当长连接无法建立时,推送消息会被存储在信鸽后台,等待连接成功后下发
[账号] 在精准推送中会用到的概念,其他的推送系统中也称作别名/Alias。账号可以在终端SDK & 信鸽后台进行设置和管理。在完成绑定之后就可以使用账号来作为推送目标来进行消息推送了
[标签] 同样是精准推送中会用到的概念,开发者可以调用信鸽SDK & 后台API,为设备绑定一个/多个标签。在完成绑定之后,就可以针对标签来进行推送了,方便进行更精细化的运营
信鸽集成【查看官网】:
https://xg.qq.com/docs/android_access/upgrade_guide.html
API相关
https://xg.qq.com/docs/android_access/android_api.html
注意一定要在Application里进行初始化
// 在主进程设置信鸽相关的内容
if (isMainProcess()) {
// 为保证弹出通知前一定调用本方法,需要在application的onCreate注册
// 收到通知时,会调用本回调函数。
// 相当于这个回调会拦截在信鸽的弹出通知之前被截取
// 一般上针对需要获取通知内容、标题,设置通知点击的跳转逻辑等等
XGPushManager
.setNotifactionCallback(new XGPushNotifactionCallback() {
@Override
public void handleNotify(XGNotifaction xGNotifaction) {
Log.i(TAG, "处理信鸽通知:" + xGNotifaction);
// 获取标签、内容、自定义内容
String title = xGNotifaction.getTitle();
String content = xGNotifaction.getContent();
String customContent = xGNotifaction
.getCustomContent();
// 其它的处理
// 如果还要弹出通知,可直接调用以下代码或自己创建Notifaction,否则,本通知将不会弹出在通知栏中。
xGNotifaction.doNotify();
}
});
}
//检查是否是主进程
public boolean isMainProcess() {
ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
List processInfos = am.getRunningAppProcesses();
String mainProcessName = getPackageName();
int myPid = android.os.Process.myPid();
for (ActivityManager.RunningAppProcessInfo info : processInfos) {
if (info.pid == myPid && mainProcessName.equals(info.processName)) {
return true;
}
}
return false;
}
一般应用程序中,都会有开启推送和关闭推送,这里有一个工具类,就是注册和反注册
public class XgUtils {
/**
* 通过手机号注册信鸽
*
* @param ctx
* @param phone 手机号\*
*/
public static void inData(final Context ctx, String phone) {
//启动时,注册信鸽推送
XGPushManager.registerPush(ctx, phone, new XGIOperateCallback() {
@Override
public void onSuccess(Object data, int flag) {
Log.d("TPush", "启动APP注册,设备token为:" + data);
SharedPreUtils.put(ctx, "token", data.toString());//存储token值
// SharedPreUtils.put(ctx, "push_click", true);
}
@Override
public void onFail(Object data, int errCode, String msg) {
Log.d("TPush", "启动APP注册失败,错误码:" + errCode + ",错误信息:" + msg);
}
});
}
/**
* 反注册
*
* @param ctx
*/
public static void unData(final Context ctx) {
XGPushManager.unregisterPush(ctx);
}
/**
* 设置标签
*/
public static void setXGPushTag(final Context ctx) {
if (UserInFoNew.getUserInFoNew().getPermissions() != null
&& !UserInFoNew.getUserInFoNew().getPermissions().isEmpty()) {
List tagList = new ArrayList<>();
tagList.clear();
for (int a = 0; a < UserInFoNew.getUserInFoNew().getPermissions().size(); a++) {
UserInFoNew.Permissions bean = UserInFoNew.getUserInFoNew().getPermissions().get(a);
String product = bean.getProductid();
Log.d("TPush", "启动APP注册,设备Tag为:" + product);
tagList.add(product);
XGPushManager.setTag(ctx, product);
}
delXGPush(ctx, tagList);
} else {
delXGPush(ctx, null);
}
}
private static void delXGPush(final Context ctx, final List tagList) {
new VideoHelper().getAllProducts(ctx, new VideoHelper.OnTelPhoneListener() {
@Override
public void success(List datas) {
for (int a = 0; a < datas.size(); a++) {
String tag = datas.get(a);
if (tagList != null && !tagList.contains(tag)) {
Log.d("TPush", "ALL,设备Tag为:" + tag + "===" + tagList.size());
XGPushManager.deleteTag(ctx, tag);
}
}
}
});
}
/**
* 删除标签
*/
public static void delXGPushTag(Context ctx) {
try {
if (UserInFoNew.getUserInFoNew().getPermissions() != null && !UserInFoNew.getUserInFoNew().getPermissions().isEmpty()) {
for (int a = 0; a < UserInFoNew.getUserInFoNew().getPermissions().size(); a++) {
UserInFoNew.Permissions bean = UserInFoNew.getUserInFoNew().getPermissions().get(a);
Log.d("TPush", "delete,设备Tag为:" + bean.getProductid());
XGPushManager.deleteTag(ctx, bean.getProductid());
}
}
} catch (Exception e) {
}
}
}
单写广播类,继承XGPushBaseReceiver,在清单文件里注册
public class MessageReceiver extends XGPushBaseReceiver
消息通知类型之通知栏显示
在onTextMessage方法里,进行消息类型判断
如果在后台,就在通知栏展示
private void show(Context context, XGPushTextMessage xgPushTextMessage, String type) {
String title = xgPushTextMessage.getTitle();
if (!TextUtils.isEmpty(col_name)) {
title = col_name;
}
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle(title)//设置通知栏标题
.setContentText(xgPushTextMessage.getContent())
.setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL, context)) //设置通知栏点击意图
.setTicker(xgPushTextMessage.getContent()) //通知首次出现在通知栏,带上升动画效果的
.setWhen(System.currentTimeMillis())//通知产生的时间,会在通知信息里显示,一般是系统获取到的时间
.setPriority(Notification.PRIORITY_DEFAULT) //设置该通知优先级
.setAutoCancel(true)//设置这个标志当用户单击面板就可以让通知将自动取消
.setOngoing(false)//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
.setDefaults(Notification.DEFAULT_VIBRATE)//向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合
.setSound(Uri.withAppendedPath(
MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "5"))
.setSmallIcon(R.drawable.ic_launcher);//设置通知小ICON
if ("1".equals(type)) {
//查询股票内容
readDatabase(context, stockName, stockCode, mBuilder);
} else if ("2".equals(type) || "5".equals(type)) {
/* Intent intent = new Intent(context, MyNewActivity.class);
intent.putExtra("pageNode", "2");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
mBuilder.setContentIntent(pendingIntent);*/
stackBuilder("2", context, mBuilder, MyNewActivity.class);
} else if ("3".equals(type)) {
//跳转到专家问股
stackBuilder("3", context, mBuilder, ExpertsQuestionUnitActivity.class);
} else if ("4".equals(type)) {
//跳转到私聊问股
stackBuilder("4", context, mBuilder, MyChatQuestionUnitActivity.class);
} else if ("6".equals(type)) {//资讯
startNewsActivity(context, mBuilder);
} else if ("7".equals(type)) {//公告
startNewsActivity(context, mBuilder);
} else if ("8".equals(type)) {//战报
startNewsActivity(context, mBuilder);
}
mNotificationManager.notify(3, mBuilder.build());
}
如果应用内,就透传,弹框显示
if (MyApplication.getApplicationLifecycle() == ApplicationLifecycle.Started) { //前台弹出对话框
MessageDialogActivity.show(context, message.getTitle(),
message.getContent(), stockCode, stockName, type, details_url, col_name);
return;
}
判断前后台:
可以在BaseActivity里进行前后台判断:
OnStop,onResume