java服务端集成极光推送-通知(2) : java代码代码实现客户端推送

本代码可以根据类型、推送目标等进行推送、可以手动选择类型、目标等
1、按照客户端类型进行发送 :ios、android、ios&android
2、按照推送目标发送:tag、tag_and、tag_not、alias(别名)、registrationId(设备id)
3.设置离线消息

1、添加极光的maven依赖

	<dependency>
    <groupId>cn.jpush.api</groupId>
    <artifactId>jpush-client</artifactId>
    <version>3.3.10</version>
	</dependency>

2、设置应用的app_key、masterSecret和apnsProduction
apnsProduction True 表示推送生产环境,False 表示要推送开发环境,
该字段仅对 iOS 的 Notification 有效。

1.将其放在apollo中:
@Value("${app-push.app_key}")
private String appKey;
@Value("${app-push.master_secret}")
private String masterSecret;
@Value("${app-push.app_apns_production}")
private Boolean appApnsProduction;

2.直接在代码中写死(不建议)

private static String APP_KEY = "*************";
private static String MASTER_SECRET = "*************";
private static Boolean APNS_PRODUCTION = false;

3 、构建Android通知推送

    private AndroidNotification getAndroidNotification(PushMessageDTO pushMessage) throws UnsupportedEncodingException {
        return AndroidNotification.newBuilder()
                //消息体
                .setTitle(pushMessage.getTitle())
                .setAlert(pushMessage.getContent())
                .addExtras(getAppExtra(pushMessage))
                .build();
    }

4、构建IOS通知推送

    private IosNotification getIosNotification(PushMessageDTO pushMessage) throws UnsupportedEncodingException {
        IosAlert alert = IosAlert.newBuilder().setTitleAndBody(pushMessage.getTitle(), pushMessage.getSubTitle(), pushMessage.getContent()).build();
        return IosNotification.newBuilder()
                //消息体
                .setAlert(alert)
                .setSound(pushMessage.getSound())
                .setBadge(pushMessage.getBadge())
                .addExtras(getAppExtra(pushMessage))
                .setMutableContent(true)
                .build();
    }

5、获取Cid

    /**
     * 获取 cid, 避免同一个通知被调用多次
     *
     * @return 返回cid
     */
    private String getCidAndReturnOneOfThem(JPushClient jPushClient) {
        String value = null;
        try {
            CIDResult cidResult = jPushClient.getCidList(Constant.CID_COUNT, Constant.CID_TYPE);
            value = cidResult.cidlist.get(0);
        } catch (APIConnectionException | APIRequestException e) {
            log.error("获取极光cid失败 ", e);
            throw new ServiceException(ErrorCode.JPUSH_PARTNER_SYSTEM_ERROR);
        }
        return value;
    }

6、设置推送平台

private NotificationPlatfo
rm pushIosMessage(PushMessageDTO pushMessage) throws UnsupportedEncodingException {
        Platform platform = Platform.ios();
        Notification notification = Notification.newBuilder()
                .addPlatformNotification(getIosNotification(pushMessage))
                .build();
        return NotificationPlatform.builder()
                .platform(platform)
                .notification(notification)
                .build();
    }

    private NotificationPlatform pushAndroidMessage(PushMessageDTO pushMessage) throws UnsupportedEncodingException {
        Platform platform = Platform.android();
        Notification notification = Notification.newBuilder()
                .addPlatformNotification(getAndroidNotification(pushMessage))
                .build();
        return NotificationPlatform.builder()
                .notification(notification)
                .platform(platform)
                .build();
    }

    private NotificationPlatform pushIosAndAndroidMessage(PushMessageDTO pushMessage) throws UnsupportedEncodingException {
        Platform platform = Platform.all();
        Notification notification = Notification.newBuilder()
                .addPlatformNotification(getAndroidNotification(pushMessage))
                .addPlatformNotification(getIosNotification(pushMessage))
                .build();
        return NotificationPlatform.builder()
                .notification(notification)
                .platform(platform)
                .build();
    }

7、生成缓存唯一的key

  private String getPushKey(PushMessageDTO pushMessage) {
        return DigestUtils.md5Hex(pushMessage.getContent() + pushMessage.getSound() +
                pushMessage.getPushType() + pushMessage.getTitle() + pushMessage.getAudienceType()
                + DateUtil.getTodayTime());
    }

8、生成cid缓存的key

    private String getCidPushKey(PushMessageDTO pushMessage, List<String> part) {
        return DigestUtils.md5Hex(pushMessage.getContent() + pushMessage.getSound() +
                pushMessage.getPushType() + pushMessage.getTitle() + pushMessage.getAudienceType()
                + DateUtil.getTodayTime() + part.toString());
    }

9、按照发送目标进行推送

    private void pushMessageParts(List<List<String>> parts, Integer audienceType,
                                  PushMessageDTO pushMessage, JPushClient jPushClient,
                                  NotificationPlatform notificationPlatform, String pushKey) {
        if (CollectionUtils.isEmpty(parts)) {
            pushSendMessage(pushMessage, jPushClient, audienceType, notificationPlatform, pushKey, Collections.emptyList());
            return;
        }

        for (List<String> part : parts) {
            pushSendMessage(pushMessage, jPushClient, audienceType, notificationPlatform, pushKey, part);
        }

    }

10、添加客户端额外参数

    private Map<String, String> getAppExtra(PushMessageDTO pushMessage) throws UnsupportedEncodingException {
        Map<String, String> extra = new HashMap<>(16);
        extra.put(Constant.APP_PUSH_ACTION, pushMessage.getAction());
        extra.put(Constant.APP_PUSH_PAYLOAD, URLEncoder.encode(JsonUtil.toJsonString(pushMessage.getPayload()), StandardCharsets.UTF_8.name()));
        return extra;
    }

11、发送消息体

   private void pushSendMessage(PushMessageDTO pushMessage, JPushClient jPushClient, Integer audienceType,
                                 NotificationPlatform notificationPlatform, String pushKey, List<String> part) {
        Audience audience;
        if (CollectionUtils.isEmpty(part) && audienceType != 5) {
            log.info("发送目标为空. pushMessage:{} ", pushMessage.toString());
            return;
        }
        switch (audienceType) {
            // 按标签推送
            case 1:
                audience = Audience.tag(part);
                break;
            //按registrationId发送
            case 2:
                audience = Audience.registrationId(part);
                break;
            //标签并集发送
            case 3:
                audience = Audience.tag_and(part);
                break;
            //标签先取并集 再取补集
            case 4:
                audience = Audience.tag_not(part);
                break;
            case 5:
                audience = Audience.all();
                part = Collections.emptyList();
                break;
            //按别名发送
            case 6:
                audience = Audience.alias(part);
                break;
            default:
                log.error("推送目标类型参数错误: audience:{}  ", audienceType.toString());
                throw new ServiceException(ErrorCode.AUDIENCE_PUSH_TYPE_ERROR);
        }

        // 缓存key audience信息+内容+日期
        String cidPushKey = getCidPushKey(pushMessage, part);
        String pushKeyValue = redisUtil.get(cidPushKey);
        if (StringUtils.isBlank(pushKeyValue)) {
            pushKeyValue = getCidAndReturnOneOfThem(jPushClient);
            redisUtil.set(cidPushKey, pushKeyValue);
        }
        String cid = pushKeyValue;
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(notificationPlatform.getPlatform())
                .setAudience(audience)
                .setNotification(notificationPlatform.getNotification())
                .setOptions(Options.newBuilder().setApnsProduction(appApnsProduction)
                        .setTimeToLive(pushMessage.getTimeToLive())
                        .build())
                .setCid(cid)
                .build();
        try {
            jPushClient.sendPush(payload);
            String[] audienceValue = part.toArray(new String[0]);
            if (CollectionUtils.isNotEmpty(part)) {
                redisUtil.lAddAll(pushKey, audienceValue, Constant.ONE_DAY);
            }
        } catch (APIConnectionException | APIRequestException e) {
            log.error("消息发送失败: req:{}", payload, e);
            throw new ServiceException(ErrorCode.JPUSH_PARTNER_SYSTEM_ERROR);
        }
    }

12、发送消息

private void pushMessageByType(PushMessageDTO pushMessage, NotificationPlatform notificationPlatform) {
        JPushClient jPushClient = new JPushClient(masterSecret, appKey);
        List<String> audienceInfoList = pushMessage.getAudienceInfo();
        // 对发送的信息进行排序
        Collections.sort(audienceInfoList);

        // 过滤重复的信息 日期+内容等
        String pushKey = getPushKey(pushMessage);

        List<String> redisAudienceList = redisUtil.getList(pushKey);
        if (CollectionUtils.isNotEmpty(redisAudienceList)) {
            audienceInfoList = audienceInfoList.stream().filter(x -> !redisAudienceList.contains(x)).collect(Collectors.toList());
        }

        Integer audienceType = pushMessage.getAudienceType();

        // 极光别名最多可以推送900个 数量超过则分开推送-- 极光官方支持1000 保险起见设为900
        Integer step = Constant.PUSH_MAX_NUMBER;
        if (audienceType.equals(Constant.TAG_PUSH_TYPE) || audienceType.equals(Constant.TAG_AND)
                || audienceType.equals(Constant.TAG_NOT)) {
            // 标签最多客推15个 极光官方支持20 保险起见设为15
            step = Constant.TAG_MAX_NUMBER;
        }
        List<List<String>> parts = ListUtils.partition(audienceInfoList, step);

        pushMessageParts(parts, audienceType, pushMessage, jPushClient, notificationPlatform, pushKey);
        jPushClient.close();
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值