admin
2024-01-23 81da61b828e29b7745e1382dfbbaeb685dc083ef
fanli/src/main/java/com/yeshi/fanli/util/push/HWPushUtil.java
@@ -1,446 +1,432 @@
package com.yeshi.fanli.util.push;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.annotation.PostConstruct;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.yeshi.utils.annotation.MapUtil;
import com.alibaba.fastjson.JSONObject;
import com.yeshi.fanli.entity.config.push.HWPushConfig;
import com.yeshi.fanli.exception.PushException;
import com.yeshi.fanli.service.inter.config.BusinessSystemService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.taobao.TaoBaoUtil;
import net.sf.json.JSONArray;
@Component
public class HWPushUtil {
   private static HWPushUtil hWPushUtil;
   @Autowired
   private BusinessSystemService businessSystemService;
   @PostConstruct
   public void init() {
      hWPushUtil = this;
      hWPushUtil.businessSystemService = this.businessSystemService;
   }
   private static String appSecret = "";
   private static String appId = "";// 用户在华为开发者联盟申请的appId和appSecret(会员中心->我的产品,点击产品对应的Push服务,点击“移动应用详情”获取)
   private static String tokenUrl = "https://login.cloud.huawei.com/oauth2/v2/token"; // 获取认证Token的URL
   private static String apiUrl = "https://api.push.hicloud.com/pushsend.do"; // 应用级消息下发API
   private static String accessToken;// 下发通知消息的认证Token
   private static long tokenExpiredTime; // accessToken的过期时间
   static {
      Properties ps = org.yeshi.utils.PropertiesUtil
            .getProperties(TaoBaoUtil.class.getClassLoader().getResourceAsStream("push_hw.properties"));
      HWPushConfig config = (HWPushConfig) MapUtil.parseMap(HWPushConfig.class, ps);
      appId = config.getAppId();
      appSecret = config.getAppSecret();
   }
   /**
    * 推送商品
    *
    * @param deviceTokens
    *            -最大值1000
    * @param title
    * @param content
    * @param goodsType
    * @param goodsId
    * @throws PushException
    */
   public static void pushGoods(List<String> deviceTokens, String title, String content, int goodsType, Long goodsId)
         throws PushException {
      if (deviceTokens != null && deviceTokens.size() > 1000)
         throw new PushException(1, "设备数不能超过1000个");
      String activity = Constant.systemCommonConfig.getAndroidBaseactivityName()
            + ".ui.recommend.GoodsBrowserActivity";
      activity = activity.replace(Constant.systemCommonConfig.getAndroidPackageName(),
            Constant.systemCommonConfig.getAndroidPackageName() + "/");
      String intent = "intent:#Intent;launchFlags=0x4000000;component=" + activity + ";S.id=" + goodsId + ";end";
      try {
         String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent, null);
         net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
         if (!"success".equalsIgnoreCase(data.optString("msg")))
            throw new PushException(2, result);
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   /**
    * 网页推送
    *
    * @param deviceTokens
    *            最大值1000
    * @param title
    * @param content
    * @param url
    *            -网页链接
    * @throws PushException
    */
   public static void pushWeb(List<String> deviceTokens, String title, String content, String url)
         throws PushException {
      if (deviceTokens != null && deviceTokens.size() > 1000)
         throw new PushException(1, "设备数不能超过1000个");
      String activity = Constant.systemCommonConfig.getAndroidBaseactivityName() + ".ui.invite.ShareBrowserActivity";
      activity = activity.replace(Constant.systemCommonConfig.getAndroidPackageName(),
            Constant.systemCommonConfig.getAndroidPackageName() + "/");
      String intent = "intent:#Intent;launchFlags=0x4000000;component=" + activity + ";S.url="
            + URLEncoder.encode(url) + ";end";
      try {
         String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent, null);
         net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
         if (!"success".equalsIgnoreCase(data.optString("msg")))
            throw new PushException(2, result);
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   /**
    * 站内信推送
    *
    * @param deviceTokens
    *            最大值1000
    * @param title
    * @param content
    * @param url
    *            -网页链接
    * @throws PushException
    */
   public static void pushZNX(List<String> deviceTokens, String title, String content) throws PushException {
      if (deviceTokens != null && deviceTokens.size() > 100)
         throw new PushException(1, "设备数不能超过100个");
//      String activity = Constant.systemCommonConfig.getAndroidBaseactivityName() + ".ui.mine.MainActivity";
//      activity = activity.replace(Constant.systemCommonConfig.getAndroidPackageName(),
//            Constant.systemCommonConfig.getAndroidPackageName() + "/");
//
//      Map<String, String> custom = new HashMap<String, String>();
//      custom.put("type", "ZNX");
//      custom.put("type1", "ZNX");
//      String intent = "intent:#Intent;launchFlags=0x4000000;component=" + activity + ";end";
//      try {
//         String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent, custom);
//         net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
//         if (!"success".equalsIgnoreCase(data.optString("msg")))
//            throw new PushException(2, result);
//      } catch (IOException e) {
//         e.printStackTrace();
//      }
      try {
         sendMsg(deviceTokens,title,content, null);
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   /**
    * 推送简单文字
    *
    * @param deviceTokens
    * @param title
    * @param content
    * @throws PushException
    */
   public static void pushSimpleText(List<String> deviceTokens, String title, String content) throws PushException {
      if (deviceTokens != null && deviceTokens.size() > 1000)
         throw new PushException(1, "设备数不能超过1000个");
      try {
         String result = sendPushHWMessageForOpenApp(deviceTokens, title, content);
         net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
         if (!"success".equalsIgnoreCase(data.optString("msg")))
            throw new PushException(2, result);
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   /**
    * 推送设备消息
    *
    * @param deviceTokens
    *            -最大1000条
    * @param title
    *            -标题
    * @param content
    *            -内容
    * @param intent
    *            如:intent:#Intent;component=com.yeshi.ec.rebate/.myapplication.
    *            ui.invite.ShareBrowserActivity;S.url="+URLEncoder.encode("http
    *            ://www.baidu.com")+";end
    * @return
    * @throws IOException
    */
   private static String sendPushHWMessageForIntent(List<String> deviceTokens, String title, String content,
         String intent, Map<String, String> customizeMap) throws IOException {
      if (tokenExpiredTime <= System.currentTimeMillis()) {
         refreshToken();
      }
      /* PushManager.requestToken为客户端申请token的方法,可以调用多次以防止申请token失败 */
      /* PushToken不支持手动编写,需使用客户端的onToken方法获取 */
      JSONArray deviceTokenList = new JSONArray();// 目标设备Token
      for (String deviceToken : deviceTokens) {
         deviceTokenList.add(deviceToken);
      }
      // 仅通知栏消息需要设置标题和内容,透传消息key和value为用户自定义
      JSONObject body = new JSONObject();
      body.put("title", title);// 消息标题
      body.put("content", content);// 消息内容体
      // 定义需要打开的appPkgName
      JSONObject param = new JSONObject();
      // param.put("intent", intent);
      param.put("appPkgName", "com.yeshi.ec.rebate");
      JSONObject action = new JSONObject();
      action.put("type", 3);// (1 自定义行为:行为由参数intent定义;2 打开URL:URL地址由参数url定义;3
                        // 打开APP:默认值,打开App的首页)
      action.put("param", param);// 消息点击动作参数
      JSONObject msg = new JSONObject();
      msg.put("type", 3);// 3: 通知栏消息,异步透传消息请根据接口文档设置
      msg.put("action", action);// 消息点击动作
      msg.put("body", body);// 通知栏消息body内容
      // 扩展信息,含BI消息统计,特定展示风格,消息折叠。
      JSONObject ext = new JSONObject();
      ext.put("biTag", "Trump");
      if (customizeMap != null) {// 传递自定义参数
         JSONArray array = new JSONArray();
         for (Iterator<String> its = customizeMap.keySet().iterator(); its.hasNext();) {
            String key = its.next();
            JSONObject json = new JSONObject();
            json.put(key, customizeMap.get(key));
            array.add(json);
         }
         ext.put("customize", array);
      }
      // ext.put("icon",
      // "http://pic.qiantucdn.com/58pic/12/38/18/13758PIC4GV.jpg");//
      // 自定义推送消息在通知栏的图标,value为一个公网可以访问的URL
      // 华为PUSH消息总结构体
      JSONObject hps = new JSONObject();
      hps.put("msg", msg);
      hps.put("ext", ext);
      JSONObject payload = new JSONObject();
      payload.put("hps", hps);
      System.out.println(payload.toJSONString());
      String postBody = MessageFormat.format(
            "access_token={0}&nsp_svc={1}&nsp_ts={2}&device_token_list={3}&payload={4}",
            URLEncoder.encode(accessToken, "UTF-8"), URLEncoder.encode("openpush.message.api.send", "UTF-8"),
            URLEncoder.encode(String.valueOf(System.currentTimeMillis() / 1000), "UTF-8"),
            URLEncoder.encode(deviceTokenList.toString(), "UTF-8"), URLEncoder.encode(payload.toString(), "UTF-8"));
      String postUrl = apiUrl + "?nsp_ctx="
            + URLEncoder.encode("{\"ver\":\"1\", \"appId\":\"" + appId + "\"}", "UTF-8");
      String result = httpPost(postUrl, postBody, 5000, 5000);
      return result;
   }
   private static String sendMsg(List<String> deviceTokens,String title,String content,  Map<String, String> customizeMap) throws IOException {
      if (tokenExpiredTime <= System.currentTimeMillis()) {
         refreshToken();
      }
      /* PushManager.requestToken为客户端申请token的方法,可以调用多次以防止申请token失败 */
      /* PushToken不支持手动编写,需使用客户端的onToken方法获取 */
      JSONArray deviceTokenList = new JSONArray();// 目标设备Token
      for (String deviceToken : deviceTokens) {
         deviceTokenList.add(deviceToken);
      }
      // 仅通知栏消息需要设置标题和内容,透传消息key和value为用户自定义
      JSONObject body = new JSONObject();
      body.put("type", "ZNX");// 消息标题
      body.put("title", title);// 消息标题
      body.put("content",content);// 消息标题
      JSONObject msg = new JSONObject();
      msg.put("type", 1);// 3: 通知栏消息,异步透传消息请根据接口文档设置
      msg.put("body", body);// 通知栏消息body内容
      JSONObject hps = new JSONObject();
      hps.put("msg", msg);
      JSONObject payload = new JSONObject();
      payload.put("hps", hps);
      System.out.println(payload.toJSONString());
      String postBody = MessageFormat.format(
            "access_token={0}&nsp_svc={1}&nsp_ts={2}&device_token_list={3}&payload={4}",
            URLEncoder.encode(accessToken, "UTF-8"), URLEncoder.encode("openpush.message.api.send", "UTF-8"),
            URLEncoder.encode(String.valueOf(System.currentTimeMillis() / 1000), "UTF-8"),
            URLEncoder.encode(deviceTokenList.toString(), "UTF-8"), URLEncoder.encode(payload.toString(), "UTF-8"));
      String postUrl = apiUrl + "?nsp_ctx="
            + URLEncoder.encode("{\"ver\":\"1\", \"appId\":\"" + appId + "\"}", "UTF-8");
      String result = httpPost(postUrl, postBody, 5000, 5000);
      return result;
   }
   /**
    * 推送打开APP的消息
    *
    * @param deviceTokens
    * @param title
    * @param content
    * @return
    * @throws IOException
    */
   private static String sendPushHWMessageForOpenApp(List<String> deviceTokens, String title, String content)
         throws IOException {
      if (tokenExpiredTime <= System.currentTimeMillis()) {
         refreshToken();
      }
      /* PushManager.requestToken为客户端申请token的方法,可以调用多次以防止申请token失败 */
      /* PushToken不支持手动编写,需使用客户端的onToken方法获取 */
      JSONArray deviceTokenList = new JSONArray();// 目标设备Token
      for (String deviceToken : deviceTokens) {
         deviceTokenList.add(deviceToken);
      }
      // 仅通知栏消息需要设置标题和内容,透传消息key和value为用户自定义
      JSONObject body = new JSONObject();
      body.put("title", title);// 消息标题
      body.put("content", content);// 消息内容体
      // 定义需要打开的appPkgName
      JSONObject param = new JSONObject();
      JSONObject action = new JSONObject();
      action.put("type", 3);// (1 自定义行为:行为由参数intent定义;2 打开URL:URL地址由参数url定义;3
                        // 打开APP:默认值,打开App的首页)
      action.put("param", param);// 消息点击动作参数
      JSONObject msg = new JSONObject();
      msg.put("type", 3);// 3: 通知栏消息,异步透传消息请根据接口文档设置
      msg.put("action", action);// 消息点击动作
      msg.put("body", body);// 通知栏消息body内容
      // 扩展信息,含BI消息统计,特定展示风格,消息折叠。
      JSONObject ext = new JSONObject();
      ext.put("biTag", "Trump");// 设置消息标签,如果带了这个标签,会在回执中推送给CP用于检测某种类型消息的到达率和状态
      // ext.put("icon",
      // "http://pic.qiantucdn.com/58pic/12/38/18/13758PIC4GV.jpg");//
      // 自定义推送消息在通知栏的图标,value为一个公网可以访问的URL
      // 华为PUSH消息总结构体
      JSONObject hps = new JSONObject();
      hps.put("msg", msg);
      hps.put("ext", ext);
      JSONObject payload = new JSONObject();
      payload.put("hps", hps);
      String postBody = MessageFormat.format(
            "access_token={0}&nsp_svc={1}&nsp_ts={2}&device_token_list={3}&payload={4}",
            URLEncoder.encode(accessToken, "UTF-8"), URLEncoder.encode("openpush.message.api.send", "UTF-8"),
            URLEncoder.encode(String.valueOf(System.currentTimeMillis() / 1000), "UTF-8"),
            URLEncoder.encode(deviceTokenList.toString(), "UTF-8"), URLEncoder.encode(payload.toString(), "UTF-8"));
      String postUrl = apiUrl + "?nsp_ctx="
            + URLEncoder.encode("{\"ver\":\"1\", \"appId\":\"" + appId + "\"}", "UTF-8");
      String result = httpPost(postUrl, postBody, 5000, 5000);
      return result;
   }
   /**
    *
    * 方法说明: 获取下发通知消息的认证Token
    *
    * @author mawurui createTime 2018年5月14日 下午4:47:26
    * @throws IOException
    */
   private static void refreshToken() throws IOException {
      String msgBody = MessageFormat.format("grant_type=client_credentials&client_secret={0}&client_id={1}",
            URLEncoder.encode(appSecret, "UTF-8"), appId);
      String response = httpPost(tokenUrl, msgBody, 5000, 5000);
      JSONObject obj = JSONObject.parseObject(response);
      accessToken = obj.getString("access_token");
      tokenExpiredTime = System.currentTimeMillis() + obj.getLong("expires_in") * 1000 - 5 * 60 * 1000;
   }
   public static String httpPost(String httpUrl, String data, int connectTimeout, int readTimeout) throws IOException {
      OutputStream outPut = null;
      HttpURLConnection urlConnection = null;
      InputStream in = null;
      try {
         URL url = new URL(httpUrl);
         urlConnection = (HttpURLConnection) url.openConnection();
         urlConnection.setRequestMethod("POST");
         urlConnection.setDoOutput(true);
         urlConnection.setDoInput(true);
         urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
         urlConnection.setConnectTimeout(connectTimeout);
         urlConnection.setReadTimeout(readTimeout);
         urlConnection.connect();
         // POST data
         outPut = urlConnection.getOutputStream();
         outPut.write(data.getBytes("UTF-8"));
         outPut.flush();
         if (urlConnection.getResponseCode() < 400) {
            in = urlConnection.getInputStream();
         } else {
            in = urlConnection.getErrorStream();
         }
         List<String> lines = IOUtils.readLines(in, urlConnection.getContentEncoding());
         StringBuffer strBuf = new StringBuffer();
         for (String line : lines) {
            strBuf.append(line);
         }
         System.out.println(strBuf.toString());
         return strBuf.toString();
      } finally {
         IOUtils.closeQuietly(outPut);
         IOUtils.closeQuietly(in);
         if (urlConnection != null) {
            urlConnection.disconnect();
         }
      }
   }
}
package com.yeshi.fanli.util.push;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.List;
import java.util.Properties;
import javax.annotation.PostConstruct;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.yeshi.utils.annotation.MapUtil;
import com.alibaba.fastjson.JSONObject;
import com.yeshi.fanli.entity.config.push.HWPushConfig;
import com.yeshi.fanli.exception.push.PushException;
import com.yeshi.fanli.service.inter.config.BusinessSystemService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.taobao.TaoBaoUtil;
import net.sf.json.JSONArray;
@Component
public class HWPushUtil {
    private static HWPushUtil hWPushUtil;
    @Autowired
    private BusinessSystemService businessSystemService;
    @PostConstruct
    public void init() {
        hWPushUtil = this;
        hWPushUtil.businessSystemService = this.businessSystemService;
    }
    private static String appSecret = "";
    private static String appId = "";// 用户在华为开发者联盟申请的appId和appSecret(会员中心->我的产品,点击产品对应的Push服务,点击“移动应用详情”获取)
    private static String tokenUrl = "https://login.cloud.huawei.com/oauth2/v2/token"; // 获取认证Token的URL
    private static String apiUrl = "https://api.push.hicloud.com/pushsend.do"; // 应用级消息下发API
    private static String accessToken;// 下发通知消息的认证Token
    private static long tokenExpiredTime; // accessToken的过期时间
    static {
        Properties ps = org.yeshi.utils.PropertiesUtil
                .getProperties(TaoBaoUtil.class.getClassLoader().getResourceAsStream("push_hw.properties"));
        HWPushConfig config = (HWPushConfig) MapUtil.parseMap(HWPushConfig.class, ps);
        appId = config.getAppId();
        appSecret = config.getAppSecret();
    }
    private static String getIntent(String type, String activity, String url, String webUrl, String id) {
        net.sf.json.JSONObject data = new net.sf.json.JSONObject();
        if (type != null)
            data.put("type", type);
        if (activity != null)
            data.put("activity", activity);
        if (url != null)
            data.put("url", url);
        if (webUrl != null)
            data.put("webUrl", webUrl);
        if (id != null)
            data.put("id", id);
        try {
            return String.format(
                    "intent://flq/hmpush?data=%s#Intent;scheme=banliapp;launchFlags=0x4000000;end",
                    URLDecoder.decode(data.toString(), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 推送商品
     *
     * @param deviceTokens -最大值1000
     * @param title
     * @param content
     * @param goodsType
     * @param goodsId
     * @throws PushException
     */
    public static void pushGoods(List<String> deviceTokens, String title, String content, int goodsType, String goodsId, String androidBaseActivityName)
            throws PushException {
        if (deviceTokens != null && deviceTokens.size() > 100)
            throw new PushException(1, "设备数不能超过100个");
        String activity = androidBaseActivityName
                + ".ui.recommend.GoodsBrowserActivity";
        String intent = getIntent("goodsdetail", activity, null, null, goodsId);
        try {
            String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent);
            net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
            if (!"success".equalsIgnoreCase(data.optString("msg")))
                throw new PushException(2, result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 网页推送
     *
     * @param deviceTokens 最大值1000
     * @param title
     * @param content
     * @param url          -网页链接
     * @throws PushException
     */
    public static void pushUrl(List<String> deviceTokens, String title, String content, String url, String androidBaseActivityName)
            throws PushException {
        if (deviceTokens != null && deviceTokens.size() > 100)
            throw new PushException(1, "设备数不能超过1000个");
        String activity = androidBaseActivityName + ".ui.invite.ShareBrowserActivity";
        String intent = getIntent("url", activity, null, url, null);
        try {
            String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent);
            net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
            if (!"success".equalsIgnoreCase(data.optString("msg")))
                throw new PushException(2, result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 站内信推送
     *
     * @param deviceTokens 最大值1000
     * @param title
     * @param content
     * @param url          -网页链接
     * @throws PushException
     */
    public static void pushZNX(List<String> deviceTokens, String title, String content) throws PushException {
        if (deviceTokens != null && deviceTokens.size() > 100)
            throw new PushException(1, "设备数不能超过100个");
        String intent = getIntent("ZNX", null, null, null, null);
        if (intent == null)
            return;
        try {
            String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent);
            net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
            if (!"success".equalsIgnoreCase(data.optString("msg")))
                throw new PushException(2, result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void pushWEEX(List<String> deviceTokens, String title, String content, String weexUrl, String androidBaseActivityName)
            throws PushException {
        String activity = androidBaseActivityName + ".ui.mine.weex.WeexApplicationActivity";
        String intent = getIntent("weex", activity, weexUrl, weexUrl, null);
        if (intent == null)
            return;
        try {
            String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent);
            net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
            if (!"success".equalsIgnoreCase(data.optString("msg")))
                throw new PushException(2, result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void pushBaiChuanUrl(List<String> deviceTokens, String title, String content, String url)
            throws PushException {
        String intent = getIntent("baichuan", null, url, null, null);
        if (intent == null)
            return;
        try {
            String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent);
            net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
            if (!"success".equalsIgnoreCase(data.optString("msg")))
                throw new PushException(2, result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void pushWelfareCenter(List<String> deviceTokens, String title, String content, String androidBaseActivityName) throws PushException {
        String activity = androidBaseActivityName + ".ui.mine.WelfareCenterActivity";
        String intent = getIntent("welfare", activity, null, null, null);
        if (intent == null)
            return;
        try {
            String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent);
            net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
            if (!"success".equalsIgnoreCase(data.optString("msg")))
                throw new PushException(2, result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void pushUserSignInNotification(List<String> deviceTokens, String title, String content, String androidBaseActivityName) throws PushException {
        String activity = androidBaseActivityName + ".ui.goldtask.GoldTaskActivity";
        String intent = getIntent("signin", activity, null, null, null);
        if (intent == null)
            return;
        try {
            String result = sendPushHWMessageForIntent(deviceTokens, title, content, intent);
            net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(result);
            if (!"success".equalsIgnoreCase(data.optString("msg")))
                throw new PushException(2, result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 推送设备消息
     *
     * @param deviceTokens -最大1000条
     * @param title        -标题
     * @param content      -内容
     * @param intent       如:intent:#Intent;component=com.yeshi.ec.rebate/.myapplication.
     *                     ui.invite.ShareBrowserActivity;S.url="+URLEncoder.encode("http
     *                     ://www.baidu.com")+";end
     * @return
     * @throws IOException
     */
    private static String sendPushHWMessageForIntent(List<String> deviceTokens, String title, String content,
                                                     String intent) throws IOException {
        if (tokenExpiredTime <= System.currentTimeMillis()) {
            refreshToken();
        }
        /* PushManager.requestToken为客户端申请token的方法,可以调用多次以防止申请token失败 */
        /* PushToken不支持手动编写,需使用客户端的onToken方法获取 */
        JSONArray deviceTokenList = new JSONArray();// 目标设备Token
        for (String deviceToken : deviceTokens) {
            deviceTokenList.add(deviceToken);
        }
        // 仅通知栏消息需要设置标题和内容,透传消息key和value为用户自定义
        JSONObject body = new JSONObject();
        body.put("title", title);// 消息标题
        body.put("content", content);// 消息内容体
        // 定义需要打开的appPkgName
        JSONObject param = new JSONObject();
        // param.put("url", "http://www.baidu.com");
        param.put("intent", intent);
        // param.put("appPkgName", "com.yeshi.ec.rebate");
        JSONObject action = new JSONObject();
        action.put("type", 1);// (1 自定义行为:行为由参数intent定义;2 打开URL:URL地址由参数url定义;3
        // 打开APP:默认值,打开App的首页)
        action.put("param", param);// 消息点击动作参数
        JSONObject msg = new JSONObject();
        msg.put("type", 3);// 3: 通知栏消息,异步透传消息请根据接口文档设置
        msg.put("action", action);// 消息点击动作
        msg.put("body", body);// 通知栏消息body内容
        // 扩展信息,含BI消息统计,特定展示风格,消息折叠。
        JSONObject ext = new JSONObject();
        // ext.put("icon",
        // "http://pic.qiantucdn.com/58pic/12/38/18/13758PIC4GV.jpg");//
        // 自定义推送消息在通知栏的图标,value为一个公网可以访问的URL
        // 华为PUSH消息总结构体
        JSONObject hps = new JSONObject();
        hps.put("msg", msg);
        hps.put("ext", ext);
        JSONObject payload = new JSONObject();
        payload.put("hps", hps);
        System.out.println(payload.toJSONString());
        String postBody = MessageFormat.format(
                "access_token={0}&nsp_svc={1}&nsp_ts={2}&device_token_list={3}&payload={4}",
                URLEncoder.encode(accessToken, "UTF-8"), URLEncoder.encode("openpush.message.api.send", "UTF-8"),
                URLEncoder.encode(String.valueOf(System.currentTimeMillis() / 1000), "UTF-8"),
                URLEncoder.encode(deviceTokenList.toString(), "UTF-8"), URLEncoder.encode(payload.toString(), "UTF-8"));
        String postUrl = apiUrl + "?nsp_ctx="
                + URLEncoder.encode("{\"ver\":\"1\", \"appId\":\"" + appId + "\"}", "UTF-8");
        String result = httpPost(postUrl, postBody, 5000, 5000);
        return result;
    }
    /**
     * 推送打开APP的消息
     *
     * @param deviceTokens
     * @param title
     * @param content
     * @return
     * @throws IOException
     */
    private static String sendPushHWMessageForOpenApp(List<String> deviceTokens, String title, String content)
            throws IOException {
        if (tokenExpiredTime <= System.currentTimeMillis()) {
            refreshToken();
        }
        /* PushManager.requestToken为客户端申请token的方法,可以调用多次以防止申请token失败 */
        /* PushToken不支持手动编写,需使用客户端的onToken方法获取 */
        JSONArray deviceTokenList = new JSONArray();// 目标设备Token
        for (String deviceToken : deviceTokens) {
            deviceTokenList.add(deviceToken);
        }
        // 仅通知栏消息需要设置标题和内容,透传消息key和value为用户自定义
        JSONObject body = new JSONObject();
        body.put("title", title);// 消息标题
        body.put("content", content);// 消息内容体
        // 定义需要打开的appPkgName
        JSONObject param = new JSONObject();
        JSONObject action = new JSONObject();
        action.put("type", 3);// (1 自定义行为:行为由参数intent定义;2 打开URL:URL地址由参数url定义;3
        // 打开APP:默认值,打开App的首页)
        action.put("param", param);// 消息点击动作参数
        JSONObject msg = new JSONObject();
        msg.put("type", 3);// 3: 通知栏消息,异步透传消息请根据接口文档设置
        msg.put("action", action);// 消息点击动作
        msg.put("body", body);// 通知栏消息body内容
        // 扩展信息,含BI消息统计,特定展示风格,消息折叠。
        JSONObject ext = new JSONObject();
        ext.put("biTag", "Trump");// 设置消息标签,如果带了这个标签,会在回执中推送给CP用于检测某种类型消息的到达率和状态
        // ext.put("icon",
        // "http://pic.qiantucdn.com/58pic/12/38/18/13758PIC4GV.jpg");//
        // 自定义推送消息在通知栏的图标,value为一个公网可以访问的URL
        // 华为PUSH消息总结构体
        JSONObject hps = new JSONObject();
        hps.put("msg", msg);
        hps.put("ext", ext);
        JSONObject payload = new JSONObject();
        payload.put("hps", hps);
        String postBody = MessageFormat.format(
                "access_token={0}&nsp_svc={1}&nsp_ts={2}&device_token_list={3}&payload={4}",
                URLEncoder.encode(accessToken, "UTF-8"), URLEncoder.encode("openpush.message.api.send", "UTF-8"),
                URLEncoder.encode(String.valueOf(System.currentTimeMillis() / 1000), "UTF-8"),
                URLEncoder.encode(deviceTokenList.toString(), "UTF-8"), URLEncoder.encode(payload.toString(), "UTF-8"));
        String postUrl = apiUrl + "?nsp_ctx="
                + URLEncoder.encode("{\"ver\":\"1\", \"appId\":\"" + appId + "\"}", "UTF-8");
        String result = httpPost(postUrl, postBody, 5000, 5000);
        return result;
    }
    /**
     * 方法说明: 获取下发通知消息的认证Token
     *
     * @throws IOException
     * @author mawurui createTime 2018年5月14日 下午4:47:26
     */
    private static void refreshToken() throws IOException {
        String msgBody = MessageFormat.format("grant_type=client_credentials&client_secret={0}&client_id={1}",
                URLEncoder.encode(appSecret, "UTF-8"), appId);
        String response = httpPost(tokenUrl, msgBody, 5000, 5000);
        JSONObject obj = JSONObject.parseObject(response);
        accessToken = obj.getString("access_token");
        tokenExpiredTime = System.currentTimeMillis() + obj.getLong("expires_in") * 1000 - 5 * 60 * 1000;
    }
    public static String httpPost(String httpUrl, String data, int connectTimeout, int readTimeout) throws IOException {
        OutputStream outPut = null;
        HttpURLConnection urlConnection = null;
        InputStream in = null;
        try {
            URL url = new URL(httpUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            urlConnection.setConnectTimeout(connectTimeout);
            urlConnection.setReadTimeout(readTimeout);
            urlConnection.connect();
            // POST data
            outPut = urlConnection.getOutputStream();
            outPut.write(data.getBytes("UTF-8"));
            outPut.flush();
            if (urlConnection.getResponseCode() < 400) {
                in = urlConnection.getInputStream();
            } else {
                in = urlConnection.getErrorStream();
            }
            List<String> lines = IOUtils.readLines(in, urlConnection.getContentEncoding());
            StringBuffer strBuf = new StringBuffer();
            for (String line : lines) {
                strBuf.append(line);
            }
            System.out.println(strBuf.toString());
            return strBuf.toString();
        } finally {
            IOUtils.closeQuietly(outPut);
            IOUtils.closeQuietly(in);
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
    }
}