笔者最近有个需求:pc端创建任务后需要实时下发到app端,即安装app的用户在任务创建之后能实时收到通知。
因为项目一直是基于uni-app开发的,故利用个推的开发文档进行开发
话不多说,直接开干:
STEP1:登录个推开发者中心,注册应用,获取AppID、AppKey、MasterSecret等参数。点此查看操作说明,如果是DCloud uniPush的用户,获取AppID、AppKey、MasterSecret等信息请参考DCloud文档。
STEP2:集成服务端SDK,点此查看集成指南
<dependencies>
<!--unipush-->
<dependency>
<groupId>com.gexin.platform</groupId>
<artifactId>gexin-rp-sdk-base</artifactId>
<version>4.0.0.30</version>
</dependency>
<dependency>
<groupId>com.gexin.platform</groupId>
<artifactId>gexin-rp-sdk-template</artifactId>
<version>4.0.0.24</version>
</dependency>
<dependency>
<groupId>com.gexin.platform</groupId>
<artifactId>gexin-rp-sdk-http</artifactId>
<version>4.1.0.5</version>
</dependency>
<dependency>
<groupId>com.gexin.platform</groupId>
<artifactId>gexin-rp-fastjson</artifactId>
<version>1.0.0.3</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.5.0</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>getui-nexus</id>
<url>http://mvn.gt.getui.com/nexus/content/repositories/releases/</url>
</repository>
</repositories>
STEP3:查看接口说明,按需调用
笔者使用的是【toList】执行批量推
- 先定义实体bo
public class PushStyle {
private String title;//通知栏标题
private String text;//通知栏内容
private String logo;//通知的图标名称,包含后缀名(需要在客户端开发时嵌入),如“icon.png”小LOGO,默认push_small.png,需要提前内置到客户端
private String logoUrl;//通知栏网络图标
private String channel;//通知渠道id
private String channelName;//通知渠道名称
private Integer channelLevel;//通知渠道重要性 具体值有0、1、2、3、4;设置之后不能修改;具体展示形式如下:0:无声音,无震动,不显示。(不推荐)
//1:无声音,无震动,锁屏不显示,通知栏中被折叠显示,导航栏无logo。
//2:无声音,无震动,锁屏和通知栏中都显示,通知不唤醒屏幕。
//3:有声音,有震动,锁屏和通知栏中都显示,通知唤醒屏幕。(推荐)
//4:有声音,有震动,亮屏下通知悬浮展示,锁屏通知以默认形式展示且唤醒屏幕。(推荐)
//以下两种方式选一种
private String bigImageUrl;//通知展示大图样式,参数是大图的URL地址
private String bigText;//通知展示文本+长文本样式,参数是长文本
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getLogo() {
return logo;
}
public void setLogo(String logo) {
this.logo = logo;
}
public String getLogoUrl() {
return logoUrl;
}
public void setLogoUrl(String logoUrl) {
this.logoUrl = logoUrl;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public String getChannelName() {
return channelName;
}
public void setChannelName(String channelName) {
this.channelName = channelName;
}
public Integer getChannelLevel() {
return channelLevel;
}
public void setChannelLevel(Integer channelLevel) {
this.channelLevel = channelLevel;
}
public String getBigImageUrl() {
return bigImageUrl;
}
public void setBigImageUrl(String bigImageUrl) {
this.bigImageUrl = bigImageUrl;
}
public String getBigText() {
return bigText;
}
public void setBigText(String bigText) {
this.bigText = bigText;
}
/*设定默认值*/
public PushStyle() {
this.logoUrl="";
this.channel = "Default";
this.channelName = "Default";
this.channelLevel = 3;
this.bigImageUrl="";
this.bigText="";
}
}
2.然后定义一个配置类
@Configuration
public class PushConfig {
public static String appId;
public static String appKey;
public static String masterSecret;
public static String host;
public static long offlineExpireTime;//过多久该消息离线失效(单位毫秒) 支持1-72小时*3600000毫秒
@Value("${spring.push.appId}")
public void setAppId(String appId) {
PushConfig.appId = appId;
}
@Value("${spring.push.appKey}")
public void setAppKey(String appKey) {
PushConfig.appKey = appKey;
}
@Value("${spring.push.masterSecret}")
public void setMasterSecret(String masterSecret) {
PushConfig.masterSecret = masterSecret;
}
@Value("${spring.push.host}")
public void setHost(String host) {
PushConfig.host = host;
}
@Value("${spring.push.offlineExpireTime}")
public void setOfflineExpireTime(long offlineExpireTime) {
PushConfig.offlineExpireTime = offlineExpireTime;
}
}
3.接着定义一个工具类
@Component
public class PushHelper {
/**
* 批量推送
* @param pushStyle 通知样式
* @param appPushList 通知范围 存储clientId字符串
*/
public void pushMessage(PushStyle pushStyle, List<String> appPushList) {
System.setProperty("gexin_pushList_needDetails", "true");
IGtPush push = new IGtPush(PushConfig.host, PushConfig.appKey, PushConfig.masterSecret);
NotificationTemplate template = getNotificationTemplate(pushStyle);
// 采用toList方案,定义ListMessage消息类型
ListMessage message = new ListMessage();
message.setData(template);
message.setOffline(true);
message.setOfflineExpireTime(PushConfig.offlineExpireTime); // 时间单位为毫秒
String contentId = push.getContentId(message);
// 获取推送目标
List targets = new ArrayList();//推送目标列表,单次推送数量限制1000以内
for (String ap : appPushList) {
Target target = new Target();
target.setAppId(PushConfig.appId);
target.setClientId(ap);
targets.add(target);
}
IPushResult ret = push.pushMessageToList(contentId, targets);
System.out.println(ret.getResponse().toString());
}
/**
* 群推-即所有安装app的可执行用户
* 注:也可以设定筛选条件,择出符合要求的推送用户
* @param pushStyle 通知样式
*/
public void pushToApp(PushStyle pushStyle) {
System.setProperty("gexin_pushList_needDetails", "true");
IGtPush push = new IGtPush(PushConfig.host, PushConfig.appKey, PushConfig.masterSecret);
NotificationTemplate template = getNotificationTemplate(pushStyle);
// 采用toApp方案,AppMessage
List<String> appIds = new ArrayList<String>();
appIds.add(PushConfig.appId);
AppMessage message = new AppMessage();
message.setData(template);
message.setAppIdList(appIds);
message.setOffline(true);
message.setOfflineExpireTime(PushConfig.offlineExpireTime); // 时间单位为毫秒
//执行推送
IPushResult ret = push.pushMessageToApp(message);
System.out.println(ret.getResponse().toString());
}
//配置通知模板
private static NotificationTemplate getNotificationTemplate(PushStyle pushStyle) {
NotificationTemplate template = new NotificationTemplate();
// 设置APPID与APPKEY
template.setAppId(PushConfig.appId);
template.setAppkey(PushConfig.appKey);
if(StringUtil.isEmpty(pushStyle.getBigImageUrl()) && StringUtil.isEmpty(pushStyle.getBigText())) {//系统样式
Style0 style = new Style0();
// 设置通知栏标题与内容
style.setTitle(pushStyle.getTitle());
style.setText(pushStyle.getText());
// 配置通知栏图标
// style.setLogo("icon.png");
// 配置通知栏网络图标
style.setLogoUrl(pushStyle.getLogoUrl());
// 设置通知是否响铃,震动,或者可清除
style.setRing(true);
style.setVibrate(true);
style.setClearable(true);
style.setChannel(pushStyle.getChannel());
style.setChannelName(pushStyle.getChannelName());
style.setChannelLevel(pushStyle.getChannelLevel()); //设置通知渠道重要性
template.setStyle(style);
}else{//大图+文本样式
Style6 style = new Style6();
style.setTitle(pushStyle.getTitle());
style.setText(pushStyle.getText());
style.setLogoUrl(pushStyle.getLogoUrl());
style.setBigStyle1(pushStyle.getBigImageUrl());
style.setBigStyle2(pushStyle.getBigText());
style.setRing(true);
style.setVibrate(true);
style.setClearable(true);
style.setChannel(pushStyle.getChannel());
style.setChannelName(pushStyle.getChannelName());
style.setChannelLevel(pushStyle.getChannelLevel());
template.setStyle(style);
}
template.setTransmissionType(1); // 透传消息接受方式设置,1:立即启动APP,2:客户端收到消息后需要自行处理
template.setTransmissionContent(JSONObject.fromObject(pushStyle).toString());
//template.setAPNInfo(getAPNPayload()); //详见【推送模板说明】iOS通知样式设置
return template;
}
}
4.最后就是调用了
@RequestMapping("/getTest")
@ResponseBody
@ApiOperation(value = "测试app端消息推送接口", response = ResponseResult.class)
@ApiVersion(group = ApiVersionConstant.EDU_SYSTEM_MANAGEMENT_VERSION_1_0)
@ApiImplicitParams({
@ApiImplicitParam(name = "access_token", paramType = "query", value = "认证", required = true, dataType = "String")})
public void getTest(){
try {
PushStyle style=new PushStyle();
style.setTitle("这是一个标题");
style.setText("这是一条信息推送测试!");
List<String> list=new ArrayList<>();
list.add("41281d5b190321fdccd91fffc820b729");
list.add("a425be5fe63ce8a410cccd816cf215d8");
pushHelper.pushMessage(style,list);
} catch (Exception e) {
logger.error("测试app端消息推送{}",e.getMessage());
e.printStackTrace();
}
}
到此在线app消息推送完毕,或许有人要问离线怎么办?笔者也正在研究,待研究好了再来与大家一起探讨。
注:笔者在开发时遇到的问题
1.调用IGtPush push = new IGtPush(host, appKey, masterSecret)方法报错:
Can not get hosts from [http://sdk.open.api.igexin.com/serviceex, http://sdk.open.api.gepush.com/serviceex,http://sdk.open.api.getui.net/serviceex]
出现原因:配置文件读取属性出错,值为空
2.执行 String contentId = push.getContentId(message)方法报空指针
出现原因:Style0对象中属性setLogoUrl,channel,channelName值可以为空但是不能为null