写在前面:
1.app是使用uniapp写的,后台是用java写的;
2.unipush支持很多推送模板,有兴趣了解的朋友可以在 官网 查看,因为要给ios实现推送的话只能使用透传模板,所以要实现给安卓和ios都可以推送的话,要在官网示例的透传模板代码上做些许修改;
3.即便代码和推送通道多么健壮,我相信推送成功率仍然是不可能是100%的,这一点android平台需要尤为重视,unipush提供了短信补全的方案,有需要的朋友可以了解一下:传送门。
4.由于需求不同本帖代码不一定适用所有业务,故本帖只做抛砖引玉,其次笔者时间有限,以下代码仅以实现单个客户端推送为例,如有其它问题请请留言交流,内容若有问题,欢迎大家批评指正。
文中代码可以达到的效果:
1.无论是ios还是安卓app,应用前置时不推送系统通知栏通知,但是可以给打开的app推送不在系统通知栏显示的消息;
2.app一旦处于退出状态、或者app处于进行被销毁状态,都会在系统通知栏进行通知推送。
注:
1.退出app或者app进程销毁后,推送的方案是由unipush的厂商推送方案实现的,所以想要实现离线推送,务必保证unipush平台的厂商推送配置是正确的,这一点根据官网的文档来一般不会有问题,故在此不再做赘述。
1.获取AppID、AppKey、MasterSecret等参数,这一点应该不需要过多赘述了,
2.集成unipush sdk,pom.xml增加如下配置,非maven项目集成方式或更多详情请戳:http://docs.getui.com/getui/server/java/guide/
com.gexin.platform
gexin-rp-sdk-http
4.1.0.5
getui-nexus
http://mvn.gt.igexin.com/nexus/content/repositories/releases/
3.编写getAPNPayload方法(注:此方法是实现给ios推送的,安卓客户端会忽略该方法),更多使用方法请戳:http://docs.getui.com/getui/server/java/template/?id=doc-title-7
private static APNPayload getAPNPayload() {
APNPayload payload = new APNPayload();
//在已有数字基础上加1显示,设置为-1时,在已有数字上减1显示,设置为数字时,显示指定数字
payload.setAutoBadge("+1");
payload.setContentAvailable(1);//推送直接带有透传数据
//ios 12.0 以上可以使用 Dictionary 类型的 sound
payload.setSound("default");
payload.setCategory("$由客户端定义");//在客户端通知栏触发特定的action和button显示
payload.addCustomMsg("由客户自定义消息key", "由客户自定义消息value");//增加自定义的数据,Key-Value形式
//简单模式APNPayload.SimpleMsg
payload.setAlertMsg(new APNPayload.SimpleAlertMsg("hello"));//通知消息体 SimpleAlertMsg: 通知文本消息字符串
// payload.setAlertMsg(getDictionaryAlertMsg()); //字典模式使用APNPayload.DictionaryAlertMsg
//设置语音播报类型,int类型,0.不可用 1.播放body 2.播放自定义文本
// payload.setVoicePlayType(2);
//设置语音播报内容,String类型,非必须参数,用户自定义播放内容,仅在voicePlayMessage=2时生效
//注:当"定义类型"=2, "定义内容"为空时则忽略不播放
// payload.setVoicePlayMessage("定义内容");//设置语音播报内容,String类型,非必须参数,用户自定义播放内容,仅在voicePlayMessage=2时生效
// 添加一个多媒体资源,当前最多传入3个资源
// payload.addMultiMedia(new MultiMedia().setResType(MultiMedia.MediaType.pic)
// .setResUrl("资源文件地址")
// .setOnlyWifi(true));
return payload;
}
4.编写透传模板代码:
public static TransmissionTemplate getTransmissionTemplate() {
TransmissionTemplate template = new TransmissionTemplate();
template.setAppId(APPID);
template.setAppkey(APPKEY);
template.setTransmissionType(1);//搭配transmissionContent使用,可选值为1、2;1:立即启动APP(不推荐使用,影响客户体验)2:客户端收到消息后需要自行处理
template.setTransmissionContent("red"); //透传内容,不支持转义字符
template.setAPNInfo(getAPNPayload()); //ios消息推送,用于设置标题、内容、语音、多媒体、VoIP(基于IP的语音传输)等。离线走APNs时起效果
Notify notify = new Notify();
notify.setTitle("厂商推送title");
notify.setContent("厂商推送内容");
notify.setIntent("intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=com.*.*/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=title;S.content=content;S.payload=test1;end");
notify.setType(GtReq.NotifyInfo.Type._intent);
template.set3rdNotifyInfo(notify);//设置第三方通知
return template;
}
注:component=com.*.*,=后面为uniapp的包名。
注:对Notify做以下细述,来源:https://www.dcloud.io/docs/a/unipush/java.pdf
成员和方法名 | 类型 | 必填 | 说明 |
---|---|---|---|
setTitle | String | 是 | 通知栏标题(长度取最小集) 小米:title 长度限制 50 字 华为:title 长度限制 40 字 魅族:title 长度限制 32 字 OPPO:title 长度限制 32 字 VIVO:title 长度限制 40 英文字符 |
setContent | String | 是 | 通知栏内容(长度取最小集) 小米:content 长度限制 128 字 华为:content 长度小于 80 字 魅族:content 长度限制 100 字 OPPO:content 长度限制 200 字 VIVO:content 长度限制 100 个英文字符 |
setUrl | String | 否 | 点击通知,打开应用的链接 |
setIntent | String | 否 | 长度小于 1000 字节,通知带 intent 传递参数推荐 使用 |
setType | Type | 否 | 取值为(Type._url、Type._intent),如果设置了 url、 intent,需要指定 Type 对应的类型;Type 所在的 包为:com.gexin.rp.sdk.dto.GtReq.NotifyInfo |
5.编写getSingleMessage类,这个类GitHub上的代码有点问题读者可以注意一下注释,我已经把问题写在注释里:
private static SingleMessage getSingleMessage(AbstractTemplate template) {
SingleMessage message = new SingleMessage();
message.setData(template);
// 设置消息离线,并设置离线时间
message.setOffline(true);
// 离线有效时间,单位为毫秒,可选
message.setOfflineExpireTime(72 * 3600 * 1000);
message.setPriority(1);
/**
* !!!2020年01月16日16时34分16秒(星期四) GitHub上这里的代码有坑,透传消息setPushNetWorkType为1的话,客户端连着wifi推送不到!!!
* 官网注释:
* 推送网络要求
* 0:联网方式不限;
* 1:仅wifi;
* 2:仅移动网络
*
*/
message.setPushNetWorkType(0); // 判断客户端是否wifi环境下推送。1为仅在wifi环境下推送,0为不限制网络环境,默认不限
return message;
}
6.编写推送主方法测试:
private static void pushToSingle() {
AbstractTemplate template = PushTemplate.getTransmissionTemplate(); //透传消息模版
SingleMessage message = getSingleMessage(template);
Target target = new Target();
target.setAppId(APPID);
target.setClientId(CID);
IPushResult ret = null;
try {
ret = push.pushMessageToSingle(message, target);
} catch (RequestException e) {
e.printStackTrace();
ret = push.pushMessageToSingle(message, target, e.getRequestId());
}
if (ret != null) {
System.out.println(ret.getResponse().toString());
} else {
System.out.println("服务器响应异常");
}
}
7.事已至此,无论是app是打开状态还是进程销毁状态,推送应该可以推送到手机了。
更多资料:
unipush GitHub主页(2020年01月16日16时34分16秒我看GitHub上的代码有个地方有问题,我在第5步已经指出,大家可以留意一下):https://github.com/GetuiLaboratory/getui-pushapi-java-demo
unipush管理控制台:https://dev.dcloud.net.cn/
unipush常见问题:https://ask.dcloud.net.cn/article/36611
android动态权限申请:https://ask.dcloud.net.cn/article/35861