java集成极光推送

一. 前言:

上篇小熙介绍了信鸽推送,这篇继续分享下极光推送的集成。

极光推送是第三方推送平台,部分免费的第三方消息推送服务,目前各方面都还不错。极光推送让开发者可以即时地向其应用程序的用户推送通知或消息,与用户保持互动,从而有效地提高留存率。官方整合了Android推送、iOS推送的统一推送服务,发送用户的指定范围也是有很多全面的选择,等等其他更好功能的选择。
极光官网

二. 视图:

展示图:
极光

三. 依赖:

极光官网依赖坐标:

		<!-- 极光推送 -->
        <dependency>
            <groupId>cn.jpush.api</groupId>
            <artifactId>jpush-client</artifactId>
            <version>3.4.3</version>
        </dependency>

四. 官网摘录:

  1. audience:推送目标

    推送设备对象,表示一条推送可以被推送到哪些设备列表。确认推送设备对象,JPush 提供了多种方式,比如:别名、标签、注册 ID、分群、广播等。

    all
    如果要发广播(全部设备),则直接填写 “all”。

    基于业务优化的需求,极光将于 3 月 10 日对「广播推送」的频率进行限制,调整为 10 次每天,超过调用限制时将返回报错码 2008,官网控制台将与 Push API 同步调整。

    注意:本次调整仅限制广播,对广播外的推送不影响。如广播推送需更高频率,请联系商务,详情请阅读公告。

    关键字类型含义说明备注
    tagJSON Array标签OR数组。多个标签之间是 OR 的关系,即取并集。 用标签来进行大规模的设备属性、用户属性分群。 一次推送最多 20 个。
    • 有效的 tag 组成:字母(区分大小写)、数字、下划线、汉字、特殊字符@!#$&*+=.|¥。
    • 限制:每一个 tag 的长度限制为 40 字节。(判断长度需采用 UTF-8 编码)
    tag_andJSON Array标签AND数组。多个标签之间是 AND 关系,即取交集。注意与 tag 区分。一次推送最多 20 个。
    tag_notJSON Array标签NOT数组。多个标签之间,先取多标签的并集,再对该结果取补集。一次推送最多 20 个。
    aliasJSON Array别名数组。多个别名之间是 OR 关系,即取并集。用别名来标识一个用户。一个设备只能绑定一个别名,但多个设备可以绑定同一个别名。一次推送最多 1000 个。
    • 有效的 alias 组成:字母(区分大小写)、数字、下划线、汉字、特殊字符@!#$&*+=.|¥。
    • 限制:每一个 alias 的长度限制为 40 字节。(判断长度需采用 UTF-8 编码)
    registration_idJSON Array注册ID数组。多个注册 ID 之间是 OR 关系,即取并集。设备标识。一次推送最多 1000 个。客户端集成 SDK 后可获取到该值。如果您一次推送的 registration_id 值超过 1000 个,可以直接使用 文件推送 功能。
    segmentJSON Array用户分群 ID 在页面创建的用户分群的 ID。定义为数组,但目前限制一次只能推送一个。目前限制是一次只能推送一个。
    abtestJSON ArrayA/B Test ID在页面创建的 A/B 测试的 ID。定义为数组,但目前限制是一次只能推送一个。目前限制一次只能推送一个。

官网更多详情

五. 配置代码:

  1. yml中的数据:

    # 极光推送 (true表示生产,false表示开发)
    jpush:
      environment: false
      appKey: d88ba5384916a5c839xxxxxxx
      masterSecret: 1d6cb3e961ec5d360xxxxxx
    
  2. 拓展信息封装类:

    package com.chengxi.datalom.utils.jPush;
    
    import lombok.Data;
    import lombok.experimental.Accessors;
    
    /**
     * 极光拓展字段不能传输object,限制了类型,所以封装更好些
     * 此类为极光推送拓展字段封装类(目前字段是暂定,你也可以拓展)
     *
     * @author chengxi
     * @date 2020/12/9 14:08
     */
    @Data
    @Accessors(chain = true)
    public class JPushVO {
    
        private Long id;
    
        private String userName;
    
        private String content;
    
    }
    
    
  3. 抽象工具父类:

    package com.chengxi.datalom.utils.jPush;
    
    import cn.jiguang.common.resp.APIConnectionException;
    import cn.jiguang.common.resp.APIRequestException;
    import cn.jpush.api.JPushClient;
    import cn.jpush.api.push.PushResult;
    import cn.jpush.api.push.model.Message;
    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.AndroidNotification;
    import cn.jpush.api.push.model.notification.IosAlert;
    import cn.jpush.api.push.model.notification.IosNotification;
    import cn.jpush.api.push.model.notification.Notification;
    import com.alibaba.fastjson.JSON;
    import com.chengxi.datalom.config.jPush.JPushConfig;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    
    /**
     * 程熙cjp:https://blog.csdn.net/weixin_41133233
     * 极光抽象推送工具类
     *
     * @author chengxi
     * @date 2020/12/9 16:06
     */
    @Slf4j
    @Component
    public abstract class AbstractJPushToolUtil {
    
        @Autowired
        private JPushConfig jPush;
    
        protected static AbstractJPushToolUtil abstractJPushToolUtils;
    
        @PostConstruct
        public void init() {
            abstractJPushToolUtils = this;
        }
    
        /**
         * 获取JPushClient实例
         *
         * @return
         */
        private static JPushClient getJPushClient() {
            JPushClient jPushClient = new JPushClient(abstractJPushToolUtils.jPush.getMasterSecret(), abstractJPushToolUtils.jPush.getAppKey());
            return jPushClient;
        }
    
    
        /**
         * 获取推送创建build
         *
         * @param platform
         * @param audience
         * @param offlineSaveSeconds
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param sendNo
         * @return
         */
        protected static PushPayload.Builder queryPushPayloadBuilder(Platform platform, Audience audience, Long offlineSaveSeconds, String msgTitle, String msgContent, JPushVO jPushVO, Integer sendNo) {
            return PushPayload.newBuilder()
                    //指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android、ios等具体平台
                    .setPlatform(platform)
                    //指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
                    .setAudience(audience)
                    //Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
                    // sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
                    // [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
                    .setMessage(Message.newBuilder().setTitle(msgTitle).setMsgContent(msgContent).addExtra("data", JSON.toJSONString(jPushVO)).build())
                    .setOptions(Options.newBuilder()
                            //此字段的值是用来指定本推送要推送的apns环境,true表示生产,false表示开发;对android和自定义消息无意义
                            .setApnsProduction(abstractJPushToolUtils.jPush.getEnvironment())
                            //此字段是给开发者自己给推送编号,方便推送者分辨推送记录,默认为1
                            .setSendno(sendNo == null ? 1 : sendNo)
                            //此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                            .setTimeToLive(offlineSaveSeconds)
                            .build());
        }
    
        /**
         * 发送给所有用户(目前默认安卓和ios)
         *
         * @param audience
         * @param offlineSaveSeconds
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param sendNo
         * @return
         */
        public static boolean sendToAll(Audience audience, Long offlineSaveSeconds, String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, Integer sendNo) {
            boolean result = false;
            try {
                PushPayload pushPayload = queryPushPayloadBuilder(Platform.android_ios(), audience, offlineSaveSeconds, msgTitle, msgContent, null, sendNo)
                        .setNotification(Notification.newBuilder()
                                //指定当前推送的android通知
                                .addPlatformNotification(queryAndroidNotification(notificationTitle, msgContent, jPushVO))
                                //指定当前推送的ios通知
                                .addPlatformNotification(queryIosNotification(queryIosAlert(notificationTitle, msgContent, msgContent), jPushVO))
                                .build())
                        .build();
                PushResult pushResult = getJPushClient().sendPush(pushPayload);
                if (pushResult.getResponseCode() == 200) {
                    result = true;
                }
                log.info("[极光推送]PushResult result is " + pushResult);
            } catch (APIConnectionException e) {
                log.error("[极光推送]Connection error. Should retry later. ", e);
            } catch (APIRequestException e) {
                log.error("[极光推送]Error response from JPush server. Should review and fix it. ", e);
                printAPIRequestErrorLogInfo(e);
            }
    
            return result;
        }
    
        /**
         * 发送给安卓用户
         *
         * @param audience
         * @param offlineSaveSeconds
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @return
         */
        public static boolean sendToAndroid(Audience audience, Long offlineSaveSeconds, String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, Integer sendNo) {
            boolean result = false;
            try {
                PushPayload pushPayload = queryPushPayloadBuilder(Platform.android(), audience, offlineSaveSeconds, msgTitle, msgContent, null, sendNo)
                        .setNotification(Notification.newBuilder()
                                //指定当前推送的android通知
                                .addPlatformNotification(queryAndroidNotification(notificationTitle, msgContent, jPushVO))
                                .build())
                        .build();
                PushResult pushResult = getJPushClient().sendPush(pushPayload);
                if (pushResult.getResponseCode() == 200) {
                    result = true;
                }
                log.info("[极光推送]PushResult result is " + pushResult);
            } catch (APIConnectionException e) {
                log.error("[极光推送]Connection error. Should retry later. ", e);
            } catch (APIRequestException e) {
                log.error("[极光推送]Error response from JPush server. Should review and fix it. ", e);
                printAPIRequestErrorLogInfo(e);
            }
    
            return result;
        }
    
    
        /**
         * 发送给IOS用户
         *
         * @param audience
         * @param offlineSaveSeconds
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @return
         */
        public static boolean sendToIos(Audience audience, Long offlineSaveSeconds, String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, Integer sendNo) {
            boolean result = false;
            try {
                PushPayload pushPayload = queryPushPayloadBuilder(Platform.ios(), audience, offlineSaveSeconds, msgTitle, msgContent, jPushVO, sendNo)
                        .setNotification(Notification.newBuilder()
                                //指定当前推送的Ios通知
                                // .addPlatformNotification(builder.build()).build())
                                .addPlatformNotification(queryIosNotification(queryIosAlert(notificationTitle, msgTitle, msgContent), jPushVO))
                                .build())
                        .build();
                PushResult pushResult = getJPushClient().sendPush(pushPayload);
                if (pushResult.getResponseCode() == 200) {
                    result = true;
                }
                log.info("[极光推送]PushResult result is " + pushResult);
            } catch (APIConnectionException e) {
                log.error("[极光推送]Connection error. Should retry later. ", e);
            } catch (APIRequestException e) {
                log.error("[极光推送]Error response from JPush server. Should review and fix it. ", e);
                printAPIRequestErrorLogInfo(e);
            }
    
            return result;
        }
    
        /**
         * 打印APIRequestErrorLogInfo
         *
         * @param e
         */
        private static void printAPIRequestErrorLogInfo(APIRequestException e) {
            log.info("[极光推送]HTTP Status: " + e.getStatus());
            log.info("[极光推送]Error Code: " + e.getErrorCode());
            log.info("[极光推送]Error Message: " + e.getErrorMessage());
        }
    
        /**
         * AndroidNotification
         *
         * @param notificationTitle
         * @param msgContent
         * @param jPushVO
         * @return
         */
        private static AndroidNotification queryAndroidNotification(String notificationTitle, String msgContent, JPushVO jPushVO) {
            return AndroidNotification.newBuilder()
                    .setTitle(notificationTitle)
                    .setAlert(msgContent)
                    //此字段为透传字段(类型被极光限定,不能传object),不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                    .addExtra("data", JSON.toJSONString(jPushVO))
                    .build();
        }
    
        /**
         * 获取IosNotificationBuilder
         *
         * @param iosAlert
         * @param jPushVO
         * @return
         */
        private static IosNotification queryIosNotification(IosAlert iosAlert, JPushVO jPushVO) {
            return IosNotification.newBuilder()
                    //ios不支持直接设置title,你可以传一个IosAlert对象哪里再解析,指定apns title、title、subtitle(这里的key参考官方文档)等
    //                .setAlert(IosAlert.newBuilder().setTitleAndBody(notificationTitle, null, msgContent).build())
                    .setAlert(iosAlert)
                    //直接传alert
                    //此项是指定此推送的badge自动加1
                    .incrBadge(1)
                    // .setBadge(+1)
                    //此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
                    // 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
                    .setSound("sound.caf")
                    // .setSound("happy")
                    //此字段为透传字段(类型被极光限定,不能传object),不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                    .addExtra("data", JSON.toJSONString(jPushVO))
                    //此项说明此推送是一个background推送,想了解background看:http://docs.jpush.io/client/ios_tutorials/#ios-7-background-remote-notification
                    // .setContentAvailable(true)
                    .build();
        }
    
        /**
         * 获取IOS的IosAlert
         *
         * @param notificationTitle
         * @param subTitle
         * @param msgContent
         * @return
         */
        private static IosAlert queryIosAlert(String notificationTitle, String subTitle, String msgContent) {
            return IosAlert.newBuilder().setTitleAndBody(notificationTitle, subTitle, msgContent).build();
        }
    
        /**
         * 获取IOS的IosAlert
         *
         * @param notificationTitle
         * @param msgContent
         * @return
         */
        private static IosAlert queryIosAlert(String notificationTitle, String msgContent) {
            return queryIosAlert(notificationTitle, null, msgContent);
        }
    
    }
    
    
  4. 使用工具类:

    package com.chengxi.datalom.utils.jPush;
    
    import cn.jpush.api.push.model.audience.Audience;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    
    /**
     * 程熙cjp:https://blog.csdn.net/weixin_41133233
     * 极光推送工具类
     * audience 类型还有很多用法,这里是基础的可以根据需要发送的范围进行修改。更多拓展请参考官网。
     * 请参考官网详细说明:http://docs.jiguang.cn/jpush/server/push/rest_api_v3_push/#audience
     *
     * @author chengxi
     * @date 2020/12/9 15:53
     */
    @Slf4j
    @Component
    public class JPushToolUtil extends AbstractJPushToolUtil {
    
        /**
         * 发送给所有用户(默认安卓和ios端)
         *
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @return
         */
        public static boolean sendToAll(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO) {
            return sendToAll(Audience.all(), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给批量(别名)用户(默认安卓和ios端)
         *
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param aliasList
         * @return
         */
        public static boolean sendToAliasListAll(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, List<String> aliasList) {
            return sendToAll(Audience.alias(aliasList), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给批量(标签)用户(默认安卓和ios端)
         *
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param tagList
         * @return
         */
        public static boolean sendToTagListAll(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, List<String> tagList) {
            return sendToAll(Audience.tag(tagList), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给批量(不在标签集合中的)用户(默认安卓和ios端)
         *
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param tagNotList
         * @return
         */
        public static boolean sendToNotTagListAll(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, List<String> tagNotList) {
            return sendToAll(Audience.tag_not(tagNotList), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给所有安卓用户(默认全部并且保留离线保存时长为一天)
         *
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @return
         */
        public static boolean sendToAllAndroid(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO) {
            return sendToAndroid(Audience.all(), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给批量(别名)安卓用户(默认全部并且保留离线保存时长为一天)
         *
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param aliasList
         * @return
         */
        public static boolean sendToAliasListAndroid(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, List<String> aliasList) {
            return sendToAndroid(Audience.alias(aliasList), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给批量(标签中的)安卓用户(默认全部并且保留离线保存时长为一天)
         *
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param tagList
         * @return
         */
        public static boolean sendToTagListAndroid(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, List<String> tagList) {
            return sendToAndroid(Audience.tag(tagList), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给批量(不在标签中的)安卓用户(默认全部并且保留离线保存时长为一天)
         *
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param tagNotList
         * @return
         */
        public static boolean sendToNotTagListAndroid(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, List<String> tagNotList) {
            return sendToAndroid(Audience.tag(tagNotList), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给所有ios用户(默认全部并且保留离线保存时长为一天)
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @return
         */
        public static boolean sendToAllIos(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO) {
            return sendToIos(Audience.all(), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给批量(别名)ios用户(默认全部并且保留离线保存时长为一天)
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @return
         */
        public static boolean sendToAliasListIos(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, List<String> aliasList) {
            return sendToIos(Audience.alias(aliasList), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给批量(标签中的)ios用户(默认全部并且保留离线保存时长为一天)
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param tagList
         * @return
         */
        public static boolean sendToTagListIos(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, List<String> tagList) {
            return sendToIos(Audience.tag(tagList), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
        /**
         * 发送给批量(不在标签中的)ios用户(默认全部并且保留离线保存时长为一天)
         * @param notificationTitle
         * @param msgTitle
         * @param msgContent
         * @param jPushVO
         * @param tagNotList
         * @return
         */
        public static boolean sendToNotTagListIos(String notificationTitle, String msgTitle, String msgContent, JPushVO jPushVO, List<String> tagNotList) {
            return sendToIos(Audience.tag(tagNotList), 86400L, notificationTitle, msgTitle, msgContent, jPushVO, null);
        }
    
    
    }
    
    

六. 示例:

下面是小熙的测试用例:

    @Test
    public void testJPush() {
        JPushVO pushVO = new JPushVO();
        pushVO.setId(1L);
        pushVO.setUserName("程熙");
        pushVO.setContent("My name is Xiao Xi");
        System.err.println(JPushToolUtil.sendToAll("通知标题", "消息标题", "消息内容", pushVO));
    }

七. 后语:

至此小熙就分享完后端集成极光推送了,前端集成也是还需要按照官网流程操作生成应用,获取对应key,想实现更多功能还是建议多看看官方文档。他的玩法和示例比信鸽要全很多。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值