app 集成第三方实现消息推送功能

it2026-01-12  11

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,这个看公司买不买了,不买的话就用免费版的,不过到时候需要技术的小伙伴设置发送类别了,另外有兴趣的可以看看其他平台的价格,欢迎留言评论

最新回复(0)