Springboot项目集成JPush极光推送(Java SDK)

1.由于项目的需求,需要在Android APP上实现消息推送功能,所以引用了极光推送(官网:https://www.jiguang.cn/,  文档:http://docs.jiguang.cn/)

2.极光推送是经过考验的大规模app推送平台,极光推送目前每天推送消息数超过20亿条。 开发者集成SDK后,可以通过调用API推送消息。同时,极光推送提供可视化的web端控制台发送通知,统计分析推送效果。 极光推送全面支持 Android, iOS, Winphone 三大手机平台。

3.要在自己项目集成极光推送功能,首先需要在逛网注册一个极光账号,获取AppKey和masterSecret


4.项目集成java SDK,导入maven依赖

    <dependency>
            <groupId>cn.jpush.api</groupId>
            <artifactId>jpush-client</artifactId>
            <version>3.4.3</version>
    </dependency>
        
    <dependency>
        <groupId>cn.jpush.api</groupId>
        <artifactId>jiguang-common</artifactId>
        <version>1.1.7</version>
    </dependency>
    
    <!--以上部分为极光推送所依赖的jar包-->

5.application.yml需要添加的配置

jpush:
  appKey: 81a89169e875c793c1e1d862
  masterSecret: 630c4f475810e7426f065b14
  liveTime: 1000
  apnsProduction: false # 是否生成环境,true表示生成环境

6.创建极光推送基本配置信息

@Component("jpushConfig")
public class JpushConfig {

    /**
     * 极光推送的用户名
     */
    @Value("${jpush.appKey}")
    private String appkey;
    /**
     * 极光推送的密码
     */
    @Value("${jpush.masterSecret}")
    private String masterSecret;
    /**
     * 极光推送设置过期时间
     */
    @Value("${jpush.liveTime}")
    private String liveTime;

    public String getAppkey() {
        return appkey;
    }

    public void setAppkey(String appkey) {
        this.appkey = appkey;
    }

    public String getMasterSecret() {
        return masterSecret;
    }

    public void setMasterSecret(String masterSecret) {
        this.masterSecret = masterSecret;
    }

    public String getLiveTime() {
        return liveTime;
    }

    public void setLiveTime(String liveTime) {
        this.liveTime = liveTime;
    }

7.编写极光推送工具类

@Service("jpushService")
@Slf4j
public class JpushUtils {

    @Resource
    JpushConfig jpushConfig;

    /**
     * 发送自定义消息,由APP端拦截信息后再决定是否创建通知(目前APP用此种方式)
     *
     * @param title     App通知栏标题
     * @param content   App通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
     * @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
     * @param alias     别名数组,设定哪些用户手机能接收信息(为空则所有用户都推送)
     * @return PushResult
     */
    public PushResult sendCustomPush(String title, String content, Map<String, String> extrasMap, String... alias) throws APIConnectionException, APIRequestException {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(Long.parseLong(jpushConfig.getLiveTime()));
        // 使用NativeHttpClient网络客户端,连接网络的方式,不提供回调函数
        JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey(), null,
                clientConfig);
        // 设置为消息推送方式为仅推送消息,不创建通知栏提醒
//        PushPayload payload = buildCustomPushPayload(title, content, extrasMap, alias);
        PushPayload payload = buildCustomPushPayload(title, content, extrasMap, alias);
        PushResult result = jpushClient.sendPush(payload);
        return result;
    }


    /**
     * 发送通知消息
     *
     * @param title     App通知栏标题
     * @param content   App通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
     * @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
     * @param tags     标签数组,设定哪些用户手机能接收信息(为空则所有用户都推送)
     */
    public PushResult sendPush(String title, String content, Map<String, String> extrasMap, String... tags) throws APIConnectionException, APIRequestException {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(Long.valueOf(jpushConfig.getLiveTime()));
        // 使用NativeHttpClient网络客户端,连接网络的方式,不提供回调函数
        JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey(), null,
                clientConfig);
        // 设置推送方式
        PushPayload payload = buildPushLoadByTags(title, content, extrasMap, tags);
        PushResult result = jpushClient.sendPush(payload);
        return result;
    }


    /**
     * 异步请求推送方式
     * 使用NettyHttpClient,异步接口发送请求,通过回调函数可以获取推送成功与否情况
     *
     * @param title     通知栏标题
     * @param content   通知栏内容(为了单行显示全,尽量保持在22个汉字以下)
     * @param extrasMap 额外推送信息(不会显示在通知栏,传递数据用)
     * @param alias     需接收的用户别名数组(为空则所有用户都推送)
     */
    public void sendPushWithCallback(String title, String content, Map<String, String> extrasMap, String... alias) {
        ClientConfig clientConfig = ClientConfig.getInstance();
        clientConfig.setTimeToLive(Long.valueOf(jpushConfig.getLiveTime()));
        String host = (String) clientConfig.get(ClientConfig.PUSH_HOST_NAME);
        NettyHttpClient client = new NettyHttpClient(
                ServiceHelper.getBasicAuthorization(jpushConfig.getAppkey(), jpushConfig.getMasterSecret()), null,
                clientConfig);
        try {
            URI uri = new URI(host + clientConfig.get(ClientConfig.PUSH_PATH));
            PushPayload payload = buildPushPayload(title, content, extrasMap, alias);
            client.sendRequest(HttpMethod.POST, payload.toString(), uri, new NettyHttpClient.BaseCallback() {
                @Override
                public void onSucceed(ResponseWrapper responseWrapper) {
                    if (200 == responseWrapper.responseCode) {
                        log.info("极光推送成功");
                    } else {
                        log.info("极光推送失败,返回结果: " + responseWrapper.responseContent);
                    }
                }
            });
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } finally {
            // 需要手动关闭Netty请求进程,否则会一直保留
            client.close();
        }

    }

    /**
     * 设置、更新、设备的 tag, alias 信息。
     *
     * @param registrationId 设备的registrationId
     * @param alias          更新设备的别名属性
     * @param tagsToAdd      添加设备的tag属性
     * @param tagsToRemove   移除设备的tag属性
     */
    public void UpdateDeviceTagAlias(String registrationId, String alias, Set<String> tagsToAdd, Set<String> tagsToRemove) throws APIConnectionException, APIRequestException {
        JPushClient jpushClient = new JPushClient(jpushConfig.getMasterSecret(), jpushConfig.getAppkey());
        jpushClient.updateDeviceTagAlias(registrationId, alias, tagsToAdd, tagsToRemove);
    }

    /**
     * 构建Android和IOS的推送通知对象
     *
     * @return PushPayload
     */
    private PushPayload buildPushPayload(String title, String content, Map<String, String> extrasMap, String... alias) {
        if (extrasMap == null || extrasMap.isEmpty()) {
            extrasMap = new HashMap<String, String>();
        }
        // 批量删除数组中空元素
        String[] newAlias = removeArrayEmptyElement(alias);
        return PushPayload.newBuilder().setPlatform(Platform.android_ios())
                // 别名为空,全员推送;别名不为空,按别名推送
                .setAudience((null == newAlias || newAlias.length == 0) ? Audience.all() : Audience.alias(alias))
//                .setAudience(Audience.registrationId("d"))
                .setNotification(Notification.newBuilder().setAlert(content)
                        .addPlatformNotification(
                                AndroidNotification.newBuilder().setTitle(title).addExtras(extrasMap).build())
                        .addPlatformNotification(IosNotification.newBuilder().incrBadge(1).addExtras(extrasMap).build())
                        .build())
                .build();
    }


    /**
     * 根据标签推送相应的消息
     * @param title 推送消息标题
     * @param content 推送消息内容
     * @param map 推送额外信息
     * @param tags 推送的目标标签
     * @return
     */
    public PushPayload buildPushLoadByTags(String title,String content,Map<String,String> map,String... tags) {
    if(map.isEmpty()){
        map = new HashMap<>();
    }
        //批量删除数组中的空元素
        String[] newTags = removeArrayEmptyElement(tags);
    return PushPayload.newBuilder()
            //设置推送平台为安卓
            .setPlatform(Platform.android())
            //设置标签
            .setAudience(Audience.tag(tags))
            //设置 推送的标签标题
            // 设置通知方式(以alert方式提醒)
            .setNotification(Notification.newBuilder().setAlert(content)
            .addPlatformNotification(AndroidNotification.newBuilder().setTitle(title).addExtras(map).build()).build())
            //sendno int 可选 推送序号 纯粹用来作为 API 调用标识
            //离线消息保留时长 推送当前用户不在线时,为该用户保留多长时间的离线消息(默认 86400 (1 天),最长 10 天。设置为 0 表示不保留离线消息,只有推送当前在线的用户可以收到)
            //apns_production boolean 可选 APNs是否生产环境  True 表示推送生产环境,False 表示要推送开发环境; 如果不指定则为推送生产环境
            //big_push_duration int 可选 定速推送时长(分钟) 又名缓慢推送,把原本尽可能快的推送速度,降低下来,在给定的 n 分钟内,均匀地向这次推送的目标用户推送。最大值为 1440。未设置则不是定速推送
//            .setOptions(Options.newBuilder().setApnsProduction(false).setTimeToLive(8600).setBigPushDuration(1).build())
            //设置通知内容
//            .setMessage(Message.newBuilder().setTitle("").setMsgContent("").setContentType("").build())
            .build();
    }


    /**
     * 构建Android和IOS的自定义消息的推送消息对象
     *
     * @return PushPayload
     */
    private PushPayload buildCustomPushPayload(String title, String content, Map<String, String> extrasMap, String... alias) {
        // 批量删除数组中空元素
        String[] newAlias = removeArrayEmptyElement(alias);
        return PushPayload.newBuilder().setPlatform(Platform.android_ios())
                .setAudience((null == newAlias || newAlias.length == 0) ? Audience.all() : Audience.alias(alias))
                .setNotification(Notification.newBuilder().setAlert(content)
                .addPlatformNotification(AndroidNotification.newBuilder().setTitle(title).addExtras(extrasMap).build()).build())
                .setMessage(Message.newBuilder().setTitle(title).setMsgContent(content).addExtras(extrasMap).build())
                .build();
    }


    /**
     * 删除别名中的空元素(需删除如:null,""," ")
     *
     * @param strArray
     * @return String[]
     */
    private String[] removeArrayEmptyElement(String... strArray) {
        if (null == strArray || strArray.length == 0) {
            return null;
        }
        List<String> tempList = Arrays.asList(strArray);
        List<String> strList = new ArrayList<String>();
        Iterator<String> iterator = tempList.iterator();
        while (iterator.hasNext()) {
            String str = iterator.next();
            // 消除空格后再做比较
            if (null != str && !"".equals(str.trim())) {
                strList.add(str);
            }
        }
        // 若仅输入"",则会将数组长度置为0
        String[] newStrArray = strList.toArray(new String[strList.size()]);
        return newStrArray;
    }

8.测试类

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class JgTest {
    @Autowired
    JpushUtils jpushUtils;


    @Test
    public void testSendMessage() throws APIConnectionException, APIRequestException {
        String title = "工单受理";
        String content = "工单已发起,请开始受理工单信息,谢谢!";
        Map<String,String> map = new HashedMap<>();
        //设置标签
        HashSet hashSet = new HashSet();
        hashSet.add("ywb");
        //可以设置多个tag别名
        //hashSet.add("客服");
        map.put("message","额外的message消息"); //13_1711406300 12_1743331095
        PushResult pushResult = jpushUtils.sendCustomPush(title, content, map, "17_ywb");
        System.out.println(pushResult.getResponseCode());
        //log.info(String.valueOf(pushResult.statusCode));
        log.info(String.valueOf(pushResult.sendno));
        //设置、更新、设备的 tag, alias 信息。140fe1da9e38e9efd3e
        jpushUtils.UpdateDeviceTagAlias("140fe1da9ec6c5fc7af",null,hashSet,null);
    }

    @Test
    public void testSendMessageByTags() throws APIConnectionException, APIRequestException {
        String title = "工单受理new";
        String content = "工单已发起,请开始受理工单信息,谢谢!";
        Map<String,String> map = new HashedMap<>();
        //设置标签
        HashSet hashSet = new HashSet();
        hashSet.add("ywb");
        //可以设置多个tag标签
        //hashSet.add("客服");
        map.put("message","其他的message消息");
        String[] tags = new String[]{"support"};
        PushResult pushResult = jpushUtils.sendPush(title, content, map, tags);
        System.out.println(pushResult.getResponseCode());
    }
}

9.通过账号登录官网可以看到推送历史记录

详细信息

 

10:注:手机安装相应的App,安卓端需要知道当前注册账号的AppKey,然后就可以收到服务端发送的消息

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-03-07 18:23  yiwanbin  阅读(7428)  评论(9编辑  收藏  举报