app 集成第三方实现消息推送功能
国内推送平台较多,常见的有:
- 极光推送
- 阿里云推送
- 友盟推送
- 腾讯云推送
- 个推推送
个人目前已经做了两次推送了,都是用的极光推送,我并不是为极光打广告啊,是因为极光有免费版的,哈哈,其他的平台没用过所以不太清楚有没有免费版的,这次总结一下我集成极光推送的过程,以后忘了的话还可以再看看
一:注册登录极光官网(最好是公司账号,手机号)
二:登录服务中心(头像下边),进入开发者平台,点击消息推送
三:创建应用,获取AppKey 和 Master Secret,以便之后在你的 yml 配置文件中进行配置
四:推送设置,这时候需要和前端沟通,获取安卓应用包名及 ios 证书
五:设置完成后,就开始咱们的配置和业务代码啦,注意,之下代码可以引用,有些推送业务代码中可能不包括
pom依赖添加:
<!--极光推送-->
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jpush-client</artifactId>
<version>3.3.10</version>
</dependency>
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jiguang-common</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
config 配置文件:JPushConfig
package cn.xof.config;
import cn.jpush.api.JPushClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
@Data
@ConfigurationProperties(prefix = "xym.push")
public class JPushConfig {
private String appkey;
private String secret;
private boolean apns;
private JPushClient jPushClient;
/**
* 推送客户端
* @return
*/
@PostConstruct
public void initJPushClient() {
jPushClient = new JPushClient(secret, appkey);
}
/**
* 获取推送客户端
* @return
*/
public JPushClient getJPushClient() {
return jPushClient;
}
/**
* 区分开发和线上环境
* @return
*/
public boolean getApns() {
return apns;
}
}
PushService:
package cn.xof.tzy.service;
import cn.xof.tzy.entity.PushBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 推送服务
* 封装业务功能相关
* @author xym
*/
@Service
public class PushService {
/** 一次推送最大数量 (极光限制1000) */
private static final int max_size = 800;
@Autowired
private JPushService jPushService;
/**
* 推送全部, 不支持附加信息
* @author xym
* @return
*/
public boolean pushAll(PushBean pushBean){
return jPushService.pushAll(pushBean);
}
/**
* 推送全部ios
* @author xym
* @return
*/
public boolean pushIos(PushBean pushBean){
return jPushService.pushIos(pushBean);
}
/**
* 推送ios 指定id
* @author xym
* @return
*/
public boolean pushIos(PushBean pushBean, String ... registids){
registids = checkRegistids(registids); // 剔除无效registed
while (registids.length > max_size) { // 每次推送max_size个
jPushService.pushIos(pushBean, Arrays.copyOfRange(registids, 0, max_size));
registids = Arrays.copyOfRange(registids, max_size, registids.length);
}
return jPushService.pushIos(pushBean, registids);
}
/**
* 推送全部android
* @author xym
* @return
*/
public boolean pushAndroid(PushBean pushBean){
return jPushService.pushAndroid(pushBean);
}
/**
* 推送android 指定id
* @author xym
* @return
*/
public boolean pushAndroid(PushBean pushBean, String ... registids){
registids = checkRegistids(registids); // 剔除无效registed
while (registids.length > max_size) { // 每次推送max_size个
jPushService.pushAndroid(pushBean, Arrays.copyOfRange(registids, 0, max_size));
registids = Arrays.copyOfRange(registids, max_size, registids.length);
}
return jPushService.pushAndroid(pushBean, registids);
}
/**
* 剔除无效registed
* @author xym [2016年7月15日 下午4:03:31]
* @param registids
* @return
*/
private String[] checkRegistids(String[] registids) {
List<String> regList = new ArrayList<String>(registids.length);
for (String registid : registids) {
if (registid!=null && !"".equals(registid.trim())) {
regList.add(registid);
}
}
return regList.toArray(new String[0]);
}
}
JPushService:
package cn.xof.tzy.service;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import cn.xof.config.JPushConfig;
import cn.xof.tzy.entity.PushBean;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 极光推送
* 封装第三方api相关
* @author xym
*/
@Service
@Slf4j
public class JPushService {
@Autowired
private JPushConfig jPushConfig;
//@Autowired
//private TbPushHistoryService pushHistoryService;
/**
* 广播 (所有平台,所有设备, 不支持附加信息)
* @author xym
* @param pushBean 推送内容
* @return
*/
public boolean pushAll(PushBean pushBean){
return sendPush(PushPayload.newBuilder()
.setPlatform(Platform.all())
.setAudience(Audience.all())
.setNotification(Notification.alert(pushBean.getAlert()))
.setOptions(Options.newBuilder().setApnsProduction(jPushConfig.getApns()).build())
.build());
}
/**
* ios广播
* @author xym
* @param pushBean 推送内容
* @return
*/
public boolean pushIos(PushBean pushBean){
return sendPush(PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.all())
.setNotification(Notification.ios(pushBean.getAlert(), pushBean.getExtras()))
.setOptions(Options.newBuilder().setApnsProduction(jPushConfig.getApns()).build())
.build());
}
/**
* ios通过registid推送 (一次推送最多 1000 个)
* @author xym
* @param pushBean 推送内容
* @param registids 推送id
* @return
*/
public boolean pushIos(PushBean pushBean, String ... registids){
return sendPush(PushPayload.newBuilder()
.setPlatform(Platform.ios())
//.setAudience(Audience.registrationId(registids))
.setAudience(Audience.alias(registids))
//.setNotification(Notification.ios(pushBean.getAlert(), pushBean.getExtras()))
.setNotification(Notification.newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert(pushBean.getAlert())
.setBadge(1)
.setSound("default")
.addExtras(pushBean.getExtras())
.build())
.build())
.setOptions(Options.newBuilder().setApnsProduction(jPushConfig.getApns()).build())
.build());
}
/**
* android广播
* @author xym
* @param pushBean 推送内容
* @return
*/
public boolean pushAndroid(PushBean pushBean){
return sendPush(PushPayload.newBuilder()
.setPlatform(Platform.android())
.setAudience(Audience.all())
.setNotification(Notification.android(pushBean.getAlert(), pushBean.getTitle(), pushBean.getExtras()))
.setOptions(Options.newBuilder().setApnsProduction(jPushConfig.getApns()).build())
.build());
}
/**
* android通过registid推送 (一次推送最多 1000 个)
* @author xym
* @param pushBean 推送内容
* @param registids 推送id
* @return
*/
public boolean pushAndroid(PushBean pushBean, String ... registids){
return sendPush(PushPayload.newBuilder()
.setPlatform(Platform.android())
//pushPayloadBuilder.setAudience(Audience.alias(alias.toString()));
.setAudience(Audience.alias(registids))
// .setAudience(Audience.registrationId(registids))
.setNotification(Notification.android(pushBean.getAlert(), pushBean.getTitle(), pushBean.getExtras()))
.setOptions(Options.newBuilder().setApnsProduction(jPushConfig.getApns()).build())
.build());
}
//PushPayload
/**
* 调用api推送
* @author xym
* @param pushPayload 推送实体
* @return
*/
private boolean sendPush(PushPayload pushPayload){
//pushHistoryService
//TbPushHistory pushHistory = new TbPushHistory();
JsonParser parse =new JsonParser(); //创建json解析器
JsonObject json=(JsonObject) parse.parse(pushPayload.toString()); //创建jsonObject对象
log.info("发送极光推送请求: {}", pushPayload);
PushResult result = null;
//PushBean pushBean=new PushBean();
try{
result = jPushConfig.getJPushClient().sendPush(pushPayload);
} catch (APIConnectionException e) {
log.error("极光推送连接异常: ",e.isReadTimedout());
return false;
} catch (APIRequestException e) {
log.error("极光推送请求异常: ", e.getErrorMessage());
return false;
}
String platform = json.get("platform").toString();
//pushHistory.setCreateTime(new Date());
//pushHistory.setDeviceType(platform);
/* if (platform!="all")
{
String alias = json.get("audience").getAsJsonObject().get("alias").toString();
pushHistory.setAlias(alias);
}*/
//String notification = json.get("notification").getAsJsonObject().get("android").getAsJsonObject().get("alert").toString();
String notification = json.get("notification").toString();
//pushHistory.setMessage(notification);
String options = json.get("options").toString();
//pushHistory.setExtras(options);
if (result!=null && result.isResultOK()) {
//pushHistory.setStatus(0);
//pushHistoryService.insert(pushHistory);
//String alias2 = json.get("notification").getAsJsonObject().get("android").getAsJsonObject().get("title").toString();
//String alias3 = json.get("options").getAsJsonObject().get("sendno").toString();
//String alias4 = json.get("options").getAsJsonObject().get("apns_production").toString();
//JsonObject result=json.get("result").getAsJsonObject();
//JSONObject object = JSONObject.parseObject(pushPayload.toString());
// JsonObject result=json.get("result").getAsJsonObject();
//Object platform = object.get("platform");
//Object audience = object.get("audience");
//Object notification = object.get("notification");
//object.get("options");
log.info("极光推送请求成功: {}", result);
return true;
}else {
//pushHistory.setStatus(1);
//pushHistoryService.insert(pushHistory);
log.info("极光推送请求失败: {}", result);
return false;
}
}
}
PushController:
package cn.xof.tzy.controller;
import cn.xof.common.Result;
import cn.xof.tzy.entity.PushBean;
import cn.xof.tzy.service.PushService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
@RestController
@RequestMapping("/push")
@Slf4j
@CrossOrigin
@Api(value ="极光推送",description = "极光推送")
public class PushController {
@Autowired
private PushService pushService;
/**
* 推送全部(包括ios和android)
* @param pushBean
* @return
*/
@ApiOperation("推送全部(包括ios和android")
@RequestMapping(value="/all", method= RequestMethod.POST)
public Result pushAll(@RequestBody PushBean pushBean) {
if (pushService.pushAll(pushBean)){
return Result.success("推送成功!");
}else {
return Result.failure("推送失败!");
}
}
/**
* 推送全部ios
* @param pushBean
* @return
*/
@ApiOperation("推送全部ios")
@RequestMapping(value="/ios/all", method= RequestMethod.POST)
public Result pushIos(PushBean pushBean){
if (pushService.pushIos(pushBean)){
return Result.success("推送成功!");
}else {
return Result.failure("推送失败!");
}
}
/**
* 推送指定ios
* @param pushBean
* @return
*/
@ApiOperation("推送指定ios,多个别名ID")
@RequestMapping(value="/ios", method= RequestMethod.POST)
public Result pushIos(PushBean pushBean, String[] registerids){
if(pushService.pushIos(pushBean, registerids)){
return Result.success("推送成功!");
}else {
return Result.failure("推送失败!");
}
}
/**
* 推送全部android
* @param pushBean
* @return
*/
@ApiOperation("推送全部android")
@RequestMapping(value="/android/all", method= RequestMethod.POST)
public Result pushAndroid(PushBean pushBean){
if(pushService.pushAndroid(pushBean)){
return Result.success("推送成功!");
}else {
return Result.failure("推送失败!");
}
}
/**
* 推送指定android
* @param pushBean
* @return
*/
@ApiOperation("推送指定android,多个别名ID")
@RequestMapping(value="/android", method= RequestMethod.POST)
public Result pushAndroid(PushBean pushBean, String[] registerids){
if(pushService.pushAndroid(pushBean, registerids)){
return Result.success("推送成功!");
}else {
return Result.failure("推送失败!");
}
}
@ApiOperation("多个别名ID,全设备推送")
@RequestMapping(value="/allbyids", method= RequestMethod.POST)
public Result pushAllbyids(@RequestBody PushBean pushBean, String[] registerids){
if(pushService.pushAndroid(pushBean, registerids)){
log.info(registerids.toString()+"指定别名Android推送成功");
log.error(registerids.toString()+"指定别名Android推送失败!");
}
if(pushService.pushIos(pushBean, registerids)){
log.info(registerids.toString()+"指定别名Android推送成功");
}else {
log.error(registerids.toString()+"指定别名Android推送失败!");
}
return Result.success("推送成功!");
}
//定时任务,每天下午2点,推送全部(包括ios和android)
@Scheduled(cron = "0 0 14 * * ?")
public void pushing(){
PushBean pushBean = new PushBean();
//可选,通知标题
pushBean.setTitle("");
//必填, 通知内容
pushBean.setAlert("速~来~赚~钱~一大波任务来袭!");
if (pushService.pushAll(pushBean)){
log.info("{},推送成功!", LocalDateTime.now());
}else {
log.error("{},推送失败!", LocalDateTime.now());
}
}
}
PushBean:
package cn.xof.tzy.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PushBean {
// 必填, 通知内容, 内容可以为空字符串,则表示不展示到通知栏。
private String alert;
// 可选, 附加信息, 供业务使用。
private Map<String, String> extras;
//android专用// 可选, 通知标题 如果指定了,则通知里原来展示 App名称的地方,将展示成这个字段。
private String title;
}
yml 添加配置:
#极光推送
push:
appkey: bdbdabc57feec51b567620xx
secret: a291ae194a16e7166575f1xx
apns: false
记得在你的 config 配置文件里把 xym 改成你自己的:@ConfigurationProperties(prefix = “xym.push”)
六:测试
你可以在开发者服务里测试(分类:1、tag 2、alias 3、全部 , 发推送的时候在下方有选择),也可以在代码中进行测试,不过如果你还未购买的话,建议使用指定 android 或者指定 ios 接口测试,比如 JPushService 里的 :
public boolean pushAndroid(PushBean pushBean, String ... registids){
return sendPush(PushPayload.newBuilder()
.setPlatform(Platform.android())
//pushPayloadBuilder.setAudience(Audience.alias(alias.toString()));
.setAudience(Audience.alias(“666”))
// .setAudience(Audience.registrationId(registids))
.setNotification(Notification.android(pushBean.getAlert(), pushBean.getTitle(), pushBean.getExtras()))
.setOptions(Options.newBuilder().setApnsProduction(jPushConfig.getApns()).build())
.build());
}
点击高级功能
各位多试试,挺好玩的,接下来就坐等 android 和 ios 端的小伙伴集成了
之前极光能按月收费,也挺划算的,现在是按年48000,折扣0.6折后28800,这个看公司买不买了,不买的话就用免费版的,不过到时候需要技术的小伙伴设置发送类别了,另外有兴趣的可以看看其他平台的价格,欢迎留言评论