极光推送java详细使用案例

一、推送在app端使用的比较多,常见的第三方推送有百度推送,极光推送,友盟推送等,其实原理都一样。以下介绍以下原理图:

1.设备绑定流程:

极光推送java详细使用案例_第1张图片

2.消息推送流程:

极光推送java详细使用案例_第2张图片

二、搞清楚了原理,下面我们来进行实战操作了

1.首先在maven工程中引入对应的maven库,如果不是maven工程,可以自行引入jar包,可以到极光官网进行下载:


   cn.jpush.api
   jpush-client
   3.3.10

2.在用户登录接口中进行设备的绑定,我这里是示例代码(我的工程框架是springcloud),你可以酌情使用:

/**
 * 用户设备和极光设备id绑定
 * @param registrationId:app客户端机器的唯一识别码
 * @param  type:app类型 分为 ios或 android                        
 * @return
 */
@PostMapping("app/jpushBind")
@MustLogin
public Object jpushBind(String registrationId,String type) {
   if(ValidateHelper.isNullOrEmpty(registrationId)||ValidateHelper.isNullOrEmpty(type)) {
      return MybData.error("registrationId、type不能为空");
   }
   if(!type.equals("ios")&&!type.equals("android")) {
      return MybData.error("参数有误");
   }
   User user=getUser();//我这里是使用了注解的方式在拦截器层进行了用户的封装
   jpushUtil.bind(user.getId(), new JpushInfo(registrationId, type,user.getCompanyId(),user.getId()));
   return MybData.success();
}

3.jpush工具类,我这里绑定的用户和设备信息是保存在redis数据库中的,实际使用的时候你可以根据自身情况操作。另外,极光的secret和appkey需要在极光应用平台进行申请开通:

@Slf4j
@Component
public class JpushUtil {
    //这里的配置可以配置在配置文件中 
   @Value("${jiguang.isProduct}") //是否是生产环境
   private Boolean isProduct;
   @Value("${jiguang.masterSecret}")
   private String masterSecret;//极光应用的secret
   @Value("${jiguang.appKey}")
   private String appKey;//极光应用的appkey

   @Autowired
   private RedisUtil redis;

   /**
    * 设备绑定
    */
   public void bind(String userId, JpushInfo jpushInfo) {
      List keys = redis.scanMatch(JpushInfo.JPUSH_USER_KEY + ":" + "*");
      String objStr = null;
      String key = null;
      Iterator iterator = keys.iterator();
      JpushInfo temp = null;
      // 接触当前设备以前绑定的设备信息
      while (iterator.hasNext()) {
         key = iterator.next();
         objStr = redis.getString(key);
         if (objStr != null) {
            temp = JSONHelper.convertToObject(objStr, JpushInfo.class);
            if (jpushInfo.getRegistrationId().equals(temp.getRegistrationId())) {
               redis.remove(key);
            }
         }
      }
      log.info("======================用户设备绑定=========================");
      redis.setString(JpushInfo.JPUSH_USER_KEY +  ":" + userId, JSONHelper.convertToJSON(jpushInfo));
   }

   /**
    * 解除设备绑定
    */
   public void unbind( String userId) {
      log.info("======================用户设备取消绑定=========================");
      redis.remove(JpushInfo.JPUSH_USER_KEY  + ":" + userId);
   }

   public void push(List list) {
      try {
         if (ValidateHelper.isNullOrEmpty(list)) {
            return;
         }
         List pushPayloadList = new ArrayList();
         for (JpushNotice notice : list) {
            JpushInfo client = redis.getToObject(JpushInfo.JPUSH_USER_KEY + ":" + notice.getUserId(), JpushInfo.class);
            if (client == null) {
               continue;
            }
            //推送的用户信息和当前登录的用户信息不一致,不进行推送
            if(notice.getCompanyId()!=null&&!notice.getCompanyId().equals(client.getCompanyId())) {
               continue;
            }
            notice.setRegistrationId(client.getRegistrationId());
            if (DeviceType.Android.value().equals(client.getClientType())) {
               pushPayloadList.add(buildPushObject_android_all_alertWithTitle(notice));
            } else {
               pushPayloadList.add(buildPushObject_ios_all_alertWithTitle(notice));
            }
         }
         if (ValidateHelper.isNullOrEmpty(pushPayloadList)) {
            return;
         }
         log.info("======================开始推送消息:共" + pushPayloadList.size() + "条=========================");
         JPushClient jpushClient = new JPushClient(masterSecret, appKey, null, ClientConfig.getInstance());
         for (PushPayload payload : pushPayloadList) {
            System.out.println(payload.toString());
            PushResult result = jpushClient.sendPush(payload);
            log.info(result + "................................");
            log.info("Got result - " + result);
         }
         Thread.sleep(5000);
         jpushClient.close();
      } catch (Exception ex) {
         log.info("==================================jpush推送异常:{}", ex);
      }
   }

   /**
    * @Title: pushPassThrough @Description: 发送穿透消息 @param: @param
    * jpushNotice @return: void @throws
    */
   public void pushPassThrough(JpushNotice jpushNotice) {
      JpushInfo client = redis.getToObject(JpushInfo.JPUSH_USER_KEY + ":"  + jpushNotice.getUserId(), JpushInfo.class);
      if (client == null) {
         log.info("==================================jpush推送异常:{},{}", jpushNotice.getUserId(), "JpushInfo对象不存在");
         return;
      }
      //推送的用户信息和当前登录的用户信息不一致,不进行推送
      if(jpushNotice.getCompanyId()!=null&&!jpushNotice.getCompanyId().equals(client.getCompanyId())) {
         log.info("==================================推送的用户信息和当前登录的用户信息不一致,不进行推送");
         return;
      }
      jpushNotice.setRegistrationId(client.getRegistrationId());
      PushPayload pushPayload;
      if (DeviceType.Android.value().equals(client.getClientType())) {
         pushPayload = buildPushObject_android_passThrough_alertWithTitle(jpushNotice);
      } else {
         pushPayload = buildPushObject_ios_passThrough_alertWithTitle(jpushNotice);
      }
      JPushClient jpushClient = new JPushClient(masterSecret, appKey, null, ClientConfig.getInstance());
      log.info("推送消息:{}", pushPayload.toString());
      PushResult result = null;
      try {
         result = jpushClient.sendPush(pushPayload);
         log.info(result + "................................");
         log.info("Got result - " + result);
         Thread.sleep(5000);
         jpushClient.close();
      } catch (Exception e) {
         log.error("==================================jpush推送异常:{}", e);
      }

   }

   /**
    * 透传消息android
    */
   private PushPayload buildPushObject_android_passThrough_alertWithTitle(JpushNotice notice) {
      return PushPayload.newBuilder()
            // 指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
            .setPlatform(Platform.android())
            // 指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
            .setAudience(Audience.registrationId(notice.getRegistrationId()))
            // Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
            // sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
            // [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
            .setMessage(Message.newBuilder().setContentType(notice.getContentType()).setMsgContent(notice.getMsgContent()).setTitle(notice.getMsgTitle()).addExtras(notice.getExtrasparamMap()).build()).setOptions(Options.newBuilder()
                  // 此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                  .setSendno(1)
                  // 此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                  // .setTimeToLive(jpushModel.getTimeToLive())
                  // 此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                  .setApnsProduction(isProduct).build())
            .build();
   }

   /**
    * 透传消息ios
    */
   private PushPayload buildPushObject_ios_passThrough_alertWithTitle(JpushNotice notice) {
      return PushPayload.newBuilder()
            // 指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
            .setPlatform(Platform.ios())
            // 指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
            .setAudience(Audience.registrationId(notice.getRegistrationId()))
            // Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
            // sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
            // [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
            .setMessage(Message.newBuilder().setContentType(notice.getContentType()).setMsgContent(notice.getMsgContent()).setTitle(notice.getMsgTitle()).addExtras(notice.getExtrasparamMap()).build()).setOptions(Options.newBuilder()
                  // 此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                  .setApnsProduction(isProduct)
                  // 此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                  .setSendno(1)
                  // 此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                  // .setTimeToLive(jpushModel.getTimeToLive())
                  .build())
            .build();
   }

   /**
    * 构建安卓推送环境
    */
   private PushPayload buildPushObject_android_all_alertWithTitle(JpushNotice notice) {
      return PushPayload.newBuilder()
            // 指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
            .setPlatform(Platform.android())
            // 指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
            .setAudience(Audience.registrationId(notice.getRegistrationId()))
            // jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
            .setNotification(Notification.newBuilder()
                  // 指定当前推送的android通知
                  .addPlatformNotification(AndroidNotification.newBuilder().setAlert(notice.getMsgContent()).setTitle(notice.getMsgTitle())
                        // 此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
                        .addExtras(notice.getExtrasparamMap()).build())
                  .build())
            // Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
            // sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
            // [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
            .setMessage(Message.newBuilder().setContentType(notice.getContentType()).setMsgContent(notice.getMsgContent()).setTitle(notice.getMsgTitle()).addExtras(notice.getExtrasparamMap()).build()).setOptions(Options.newBuilder()
                  // 此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                  .setSendno(1)
                  // 此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                  // .setTimeToLive(jpushModel.getTimeToLive())
                  // 此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                  .setApnsProduction(isProduct).build())
            .build();
   }

   /**
    * 构建ios推送环境
    * 
    * @Title: buildPushObject_ios_all_alertWithTitle
    */
   private PushPayload buildPushObject_ios_all_alertWithTitle(JpushNotice notice) {
      IosNotification.Builder builder = IosNotification.newBuilder()
            // 传一个IosAlert对象,指定apns title、title、subtitle等
            .setAlert(IosAlert.newBuilder().setTitleAndBody(notice.getMsgTitle(), null, notice.getMsgContent()).build())
            // 直接传alert
            // 此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
            // 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
            // .setSound(jpushModel.getSound())
            // 此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
            .addExtras(notice.getExtrasparamMap());
      // 此项说明此推送是一个background推送,想了解background看:http://docs.jpush.io/client/ios_tutorials/#ios-7-background-remote-notification
      // .setContentAvailable(true)

      if (!JpushNotice.PASSTHROUGH.equals(notice.getContentType())) {
         // 此项是指定此推送的badge自动加1
         builder = builder.incrBadge(1);
      }

      return PushPayload.newBuilder()
            // 指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
            .setPlatform(Platform.ios())
            // 指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
            .setAudience(Audience.registrationId(notice.getRegistrationId()))
            // jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
            .setNotification(Notification.newBuilder()
                  // 指定当前推送的android通知
                  .addPlatformNotification(builder.build()).build())
            // Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
            // sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
            // [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
            .setMessage(Message.newBuilder().setContentType(notice.getContentType()).setMsgContent(notice.getMsgContent()).setTitle(notice.getMsgTitle()).addExtras(notice.getExtrasparamMap()).build()).setOptions(Options.newBuilder()
                  // 此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
                  .setApnsProduction(isProduct)
                  // 此字段是给开发者自己给推送编号,方便推送者分辨推送记录
                  .setSendno(1)
                  // 此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
                  // .setTimeToLive(jpushModel.getTimeToLive())
                  .build())
            .build();
   }

}

4.生产消息并开始推到极光的服务器:

//组装开始推送(多条进行推送)
private void sendJpushNotice(List noticeList) {
    if (ValidateHelper.isNullOrEmpty(noticeList)) {
        return;
    }
    List list = new ArrayList<>();
    for (Notice n : noticeList) {
        JpushNotice jn = new JpushNotice();
        Map map = new HashMap<>();
        map.put("orderId", n.getOrderId());
        map.put("goodsId", n.getGoodsId());
        map.put("type", n.getType().toString());
        map.put("id", n.getId() == null ? null : n.getId().toString());
        map.put("title", n.getTitle());
        map.put("summary", n.getSummary());
        map.put("showContent", n.getShowContent());
        map.put("createTime", TimeHelper.formatDate(new Date(), "yyyy-MM月dd日 HH:mm:ss"));
        map.put("status", n.getStatus().toString());
        jn.setExtrasparamMap(map);
        jn.setMsgContent(TextHelper.replaceHTML(n.getShowContent()));
        jn.setMsgTitle(n.getTitle());
        jn.setCompanyId(n.getCompanyId());
        jn.setUserId(n.getReceiverUserId());
        list.add(jn);
    }
    // 开始推送
    jpushUtil.push(list);}

总结,好了,以上就是极光推送的全部流程和部分代码,大家只要明白其中的原理,一般都能做出推送的,还有不清楚的地方请给我留言!

 

你可能感兴趣的:(java交流)