因为工作需要,甲方单位使用极光推送总是出现用户收取不到推送消息,甲方要求我们使用个推。

因为我们访问网络的时候使用的是代理,所以个推提供的接口发送接口不能使用,所以需要重新写一个支持代理的http链接。目前项目中的个推使用流程如下:

目前使用的是群推:pushToList,群推第一步使用taskid ,taskid 就是我们的消息在推送平台对应的一个映射id,通过taskid 来找这个消息。第二部是发送消息。发送消息的流程和获取taskId的流程几乎是一致的,就是在发送的过程中,gt_action 传的参数不一样,获取taskid 时传的是getContentIdAction,而推送消息的时候使用的是pushMessageToListAction。

个推的推送过程是:

个推使用教程-编程之家

http 代理代码如下:

package com.ruim.ifsp.merser.util;import com.alibaba.dubbo.common.utils.StringUtils;
import com.ruim.ifsp.log.IfspLoggerFactory;
import com.ruim.ifsp.merser.cache.CommonConstants;
import com.ruim.ifsp.utils.client.http.IfspHttpClientUtil;
import org.slf4j.Logger;import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
/*** 个推* @author lxw* @deprecated 个推消息推送http链接*/
public class IGtpushHttpClient extends IfspHttpClientUtil {private static Logger logger = IfspLoggerFactory.getLogger(JpushHttpClient.class);static String proxyIp = CommonConstants.getProperties("PROXY_IP");static String proxyProt = CommonConstants.getProperties("PROXY_PORT");//    private static String appId = "TxzlIyCcfS9KuENjjP4ux1";
//    private static String appKey = "rAnoicfrNX7915IxPocAL2";
//    private static String masterSecret = "KFDNBNKAVj9bgykwvqgeA5";
//    static String host = "http://sdk.open.api.igexin.com/apiex.htm";private static String appId = CommonConstants.getProperties("IGTAPP_ID");//个推appidprivate static String appKey = CommonConstants.getProperties("IGTAPP_KEY");//应用appKeyprivate static String masterSecret = CommonConstants.getProperties("IGTMASTER_SECRET");//应用证书号private static String host = CommonConstants.getProperties("IGTPUST_HOST");//个推送地址public static HttpURLConnection buildConnect(String Action) throws Exception {URL url = new URL(host);logger.info("开始初始化服务器连接...");logger.info("服务器地址:[ " + url + " ]");/**启用代理*/Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, Integer.valueOf(proxyProt)));HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(proxy);httpURLConnection.setConnectTimeout(30000);httpURLConnection.setReadTimeout(30000);httpURLConnection.setDoInput(true);httpURLConnection.setDoOutput(true);httpURLConnection.setUseCaches(false);httpURLConnection.setRequestProperty("Content-Type", "text/html;charset=UTF-8");httpURLConnection.setRequestProperty("Gt-Action", Action);httpURLConnection.setRequestMethod("POST");httpURLConnection.connect();logger.info("服务器连接完成...");return httpURLConnection;}public static void sendMsg(HttpURLConnection httpURLConnection,String message) throws Exception {logger.info("上送服务报文开始...");logger.info("上送报文:[" + message + "]");OutputStream outputStream = null;try {outputStream = httpURLConnection.getOutputStream();// 注意编码格式,防止中文乱码if (StringUtils.isNotEmpty(message)) {outputStream.write(message.getBytes("utf-8"));} else {outputStream.write("".getBytes());}if (null != outputStream)outputStream.close();logger.info("上送服务报文完成...");} catch (Exception e) {e.printStackTrace();throw e;} finally {if (null != outputStream)try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}}public static String receiveMsg(HttpURLConnection httpURLConnection) throws IOException {logger.debug("接收服务器响应报文开始...");InputStream in = null;StringBuilder sb = new StringBuilder(1024);BufferedReader br = null;String temp = null;int code = httpURLConnection.getResponseCode();if (200 == code) {in = httpURLConnection.getInputStream();br = new BufferedReader(new InputStreamReader(in, "utf-8"));while (null != (temp = br.readLine())) {sb.append(temp);}} else {in = httpURLConnection.getErrorStream();br = new BufferedReader(new InputStreamReader(in, "utf-8"));while (null != (temp = br.readLine())) {sb.append(temp);}}String str1 = sb.toString();logger.info("报文: [ " + str1 + " ] ");logger.info("接收服务器响应报文完成");return str1;}
}

推送消息代码:

package com.ruim.ifsp.merser.util;import com.gexin.rp.sdk.base.IPushResult;
import com.gexin.rp.sdk.base.impl.*;
import com.gexin.rp.sdk.base.payload.APNPayload;
import com.gexin.rp.sdk.base.payload.Payload;
import com.gexin.rp.sdk.base.uitls.Base64Util;
import com.gexin.rp.sdk.base.uitls.LangUtil;
import com.gexin.rp.sdk.base.uitls.SignUtil;
import com.gexin.rp.sdk.http.IGtPush;
import com.gexin.rp.sdk.http.utils.GTConfig;
import com.gexin.rp.sdk.http.utils.ParamUtils;
import com.gexin.rp.sdk.template.LinkTemplate;
import com.gexin.rp.sdk.template.NotificationTemplate;
import com.ruim.ifsp.exception.BizException;
import com.ruim.ifsp.log.IfspLoggerFactory;
import com.ruim.ifsp.merser.cache.CommonConstants;
import com.ruim.ifsp.utils.message.IfspFastJsonUtil;
import com.ruim.ifsp.utils.verify.IfspDataVerifyUtil;
import org.slf4j.Logger;import java.net.HttpURLConnection;
import java.time.format.TextStyle;
import java.util.*;public class IGtpushThread extends Thread {private static Logger log = IfspLoggerFactory.getLogger(IGtpushThread.class);private static String appId = CommonConstants.getProperties("IGTAPP_ID");;private static String appKey = CommonConstants.getProperties("IGTAPP_KEY");private static String masterSecret = CommonConstants.getProperties("IGTMASTER_SECRET");private static String host = CommonConstants.getProperties("IGTPUST_HOST");private String alias;private String message;private String msgSendType;public IGtpushThread(String alias,String message,String msgSendType) {
//        super();this.alias = alias;this.message = message;this.msgSendType = msgSendType;}/*** If this thread was constructed using a separate* <code>Runnable</code> run object, then that* <code>Runnable</code> object's <code>run</code> method is called;* otherwise, this method does nothing and returns.* <p>* Subclasses of <code>Thread</code> should override this method.** @see #start()* @see #stop()* @see #(ThreadGroup, Runnable, String)*/@Overridepublic void run() {IGTpushMsg(alias,message,msgSendType);}public void IGTpushMsg(String alias,String message,String msgSendType){String respMsg = new String();String[] arr = alias.split(",");// 通知透传模板 消息传递NotificationTemplate template = notificationTemplateDemo(message);ListMessage messages = new ListMessage();messages.setData(template);// 设置消息离线,并设置离线时间messages.setOffline(true);// 离线有效时间,单位为毫秒,可选messages.setOfflineExpireTime(24 * 1000 * 3600);// 配置推送目标List targets = new ArrayList();// taskId用于在推送时去查找对应的messagetry{String taskId = getListAppContentId(messages,null);Map<String,Object> postData = null;for (int i = 0; i < arr.length; i++) {Target target = new Target();target.setAppId(appId);target.setAlias(arr[i]);targets.add(target);//每50个别名(CID)推送一次if (arr.length>50&&targets.size()==50){postData =pushMessageToList(taskId,targets);Map<String,Object> response = httpResponse(postData);if (!"ok".equals(response.get("result"))){response = httpResponse(postData);respMsg = IfspFastJsonUtil.mapTOjson(response);log.info("个推建议值推送结果是:"+respMsg);}targets.clear();}}if (targets.size()>0){postData =pushMessageToList(taskId,targets);Map<String,Object> response = httpResponse(postData);if (!"ok".equals(response.get("result"))){response = httpResponse(postData);respMsg = IfspFastJsonUtil.mapTOjson(response);log.info("个推第二次推送结果是:"+respMsg);}}}catch (Exception e){log.error("个推推送失败,原因是:"+e.getMessage());}}public Map<String, Object> pushMessageToList(String contentId, List<Target> targetList) throws Exception{Map<String, Object> postData = new HashMap();postData.put("authToken", null);postData.put("action", "pushMessageToListAction");postData.put("appkey", appKey);postData.put("contentId", contentId);boolean needDetails = GTConfig.isPushListNeedDetails();postData.put("needDetails", needDetails);boolean async = GTConfig.isPushListAsync();postData.put("async", async);boolean needAliasDetails = GTConfig.isPushListNeedAliasDetails();postData.put("needAliasDetails", needAliasDetails);int limit;if (async && !needDetails) {limit = GTConfig.getAsyncListLimit();} else {limit = GTConfig.getSyncListLimit();}if (targetList.size() > limit) {throw new BizException("1000","target size:" + targetList.size() + " beyond the limit:" + limit);} else {List<String> clientIdList = new ArrayList();List<String> aliasList = new ArrayList();String appId = null;Iterator var12 = targetList.iterator();while(true) {Target target;do {if (!var12.hasNext()) {postData.put("appId", appId);postData.put("clientIdList", clientIdList);postData.put("aliasList", aliasList);postData.put("type", 2);return postData;}target = (Target)var12.next();String targetCid = target.getClientId();String targetAlias = target.getAlias();if (targetCid != null && !"".equals(targetCid.trim())) {clientIdList.add(targetCid);} else if (targetAlias != null && !"".equals(targetAlias.trim())) {aliasList.add(targetAlias);}} while(appId != null && !"".equals(appId.trim()));appId = target.getAppId();}}//苹果参数组装}public NotificationTemplate notificationTemplateDemo(String message) {NotificationTemplate template = new NotificationTemplate();// 设置APPID与APPKEYtemplate.setAppId(appId);template.setAppkey(appKey);// 设置通知栏标题与内容template.setTitle("");template.setText("");
//        // 配置通知栏图标
//        template.setLogo("icon.png");// 配置通知栏网络图标
//        template.setLogoUrl("");// 设置通知是否响铃,震动,或者可清除
//        template.setIsRing(true);
//        template.setIsVibrate(true);
//        template.setIsClearable(true);// 透传消息设置,1为强制启动应用,客户端接收到消息后就会立即启动应用;2为等待应用启动template.setTransmissionType(2);template.setTransmissionContent(message);//ios 消息推送
//        APNPayload apnPayload = new APNPayload();
//        APNPayload.SimpleAlertMsg alertMsg = new APNPayload.SimpleAlertMsg(message);
//        apnPayload.setAlertMsg(alertMsg);
//        template.setAPNInfo(apnPayload);return template;}public static void main(String[] args) throws Exception {//单推测试
//        LinkTemplate template = linkTemplateDemo();
//        SingleMessage message = new SingleMessage();
//        message.setOffline(true);
//        // 离线有效时间,单位为毫秒,可选
//        message.setOfflineExpireTime(24 * 3600 * 1000);
//        message.setData(template);
//        // 可选,1为wifi,0为不限制网络环境。根据手机处于的网络情况,决定是否下发
//        message.setPushNetWorkType(0);
//        Target target = new Target();
//        target.setAppId(appId);
//        target.setAlias("201006700000010_18611111116");
//        IPushResult ret = null;
//        Map<String,Object> reqMap = getSingleMessagePostData(message,target,null);
//        String requestMsg = IfspFastJsonUtil.mapTOjson(reqMap);
//        long startTime=System.currentTimeMillis();HttpURLConnection client = null;
//        try {
//            HttpURLConnection client = null;
//            client = IGtpushHttpClient.buildConnect(reqMap.get("action").toString());
//            IGtpushHttpClient.sendMsg(client, requestMsg);
//            String respMsg =IGtpushHttpClient.receiveMsg(client);
//            client.disconnect();
//            Map<String,Object> responseDate = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(respMsg);
//            if ("sign_error".equals(responseDate.get("result"))){
//                Map<String,Object> post = new HashMap<>();
//                long timeStamp = System.currentTimeMillis();
//                String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);
//                post.put("action", "connect");
//                post.put("appkey", appKey);
//                post.put("timeStamp", timeStamp);
//                post.put("sign", sign);
//                post.put("version", GTConfig.getSDKVersion());
//                client = IGtpushHttpClient.buildConnect(post.get("action").toString());
//                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(post).toString());
//                String resp = IGtpushHttpClient.receiveMsg(client);
//                Map<String,Object> respDate = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(resp);
//                reqMap.put("authToken",respDate.get("authtoken"));
//                client.disconnect();
//            }
//            client = IGtpushHttpClient.buildConnect(reqMap.get("action").toString());client.setRequestProperty("Gt-Action",reqMap.get("action").toString());
//            String reqMsg = IfspFastJsonUtil.mapTOjson(reqMap);
//            IGtpushHttpClient.sendMsg(client, reqMsg);
//            String respMseeage =IGtpushHttpClient.receiveMsg(client);
//
//        } catch (Exception e) {
//try {client = IGtpushHttpClient.buildConnect();IGtpushHttpClient.sendMsg(client, requestMsg);IGtpushHttpClient.receiveMsg(client);} catch (Exception e1) {
//                e.printStackTrace();}
//        }finally {if(client != null){client.disconnect();}
//        }
//        long endTime=System.currentTimeMillis();
//    }
//				群推测试// 通知透传模板
//        NotificationTemplate template = notificationTemplateDemo();
//        ListMessage message = new ListMessage();
//        message.setData(template);
//        // 设置消息离线,并设置离线时间
//        message.setOffline(true);
//        // 离线有效时间,单位为毫秒,可选
//        message.setOfflineExpireTime(24 * 1000 * 3600);
//        // 配置推送目标
//        List targets = new ArrayList();
//        Target target1 = new Target();
//        Target target2 = new Target();
//        target1.setAppId(appId);
//        target1.setAlias("201006700000010_18611111116");
//        targets.add(target1);
//        // taskId用于在推送时去查找对应的message
//        String taskId = getListAppContentId(message,null);
//        Map<String, Object> ret = pushMessageToList(taskId, targets);String requestMsg = IfspFastJsonUtil.mapTOjson(ret);
//        long startTime=System.currentTimeMillis();
//        HttpURLConnection client = null;
//        try {
//            ret.put("version", GTConfig.getSDKVersion());
//            ret.put("authToken",null);
//            String requestMsg = IfspFastJsonUtil.mapTOjson(ret);
//            client = IGtpushHttpClient.buildConnect(ret.get("action").toString());
//            IGtpushHttpClient.sendMsg(client, requestMsg);
//            String response = IGtpushHttpClient.receiveMsg(client);
//            client.disconnect();
//            Map<String,Object> responseDate = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(response);
//            if ("sign_error".equals(responseDate.get("result"))){
//                Map<String,Object> post = new HashMap<>();
//                long timeStamp = System.currentTimeMillis();
//                String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);
//                post.put("action", "connect");
//                post.put("appkey", appKey);
//                post.put("timeStamp", timeStamp);
//                post.put("sign", sign);
//                post.put("version", GTConfig.getSDKVersion());
//                client = IGtpushHttpClient.buildConnect(post.get("action").toString());
//                IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(post).toString());
//                String resp = IGtpushHttpClient.receiveMsg(client);
//                Map<String,Object> respDate = (Map<String, Object>) IfspFastJsonUtil.jsonTOmap(resp);
//                ret.put("authToken",respDate.get("authtoken"));
//                client.disconnect();
//            }
//            client = IGtpushHttpClient.buildConnect(ret.get("action").toString());
//            String reqMsg = IfspFastJsonUtil.mapTOjson(ret);
//            IGtpushHttpClient.sendMsg(client, reqMsg);
//            String respMseeage =IGtpushHttpClient.receiveMsg(client);
//            System.out.println(respMseeage);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }finally {
//            if(client != null){
//                client.disconnect();
//            }
//        }}private String getListAppContentId(Message message, String taskGroupName) {Map<String, Object> postData = new HashMap();Map<String, Object> response = null;if (taskGroupName != null) {postData.put("taskGroupName", taskGroupName);}postData.put("action", "getContentIdAction");postData.put("appkey", appKey);postData.put("clientData", Base64Util.getBASE64(message.getData().getTransparent().toByteArray()));postData.put("transmissionContent", message.getData().getTransmissionContent());postData.put("isOffline", message.isOffline());postData.put("offlineExpireTime", message.getOfflineExpireTime());postData.put("pushType", message.getData().getPushType());postData.put("type", 2);if (message instanceof ListMessage) {postData.put("contentType", 1);} else if (message instanceof AppMessage) {postData.put("contentType", 2);AppMessage appMessage = (AppMessage) message;ParamUtils.checkAppid(message, appMessage.getAppIdList());postData.put("appIdList", appMessage.getAppIdList());List<String> phoneTypeList = null;List<String> provinceList = null;List<String> tagList = null;new ArrayList();if (appMessage.getConditions() == null) {phoneTypeList = appMessage.getPhoneTypeList();provinceList = appMessage.getProvinceList();tagList = appMessage.getTagList();postData.put("phoneTypeList", phoneTypeList);postData.put("provinceList", provinceList);postData.put("tagList", tagList);} else {List<Map<String, Object>> conditions = appMessage.getConditions().getCondition();}postData.put("speed", appMessage.getSpeed());String pushTime = appMessage.getPushTime();if (pushTime != null && !pushTime.isEmpty()) {postData.put("pushTime", pushTime);}}postData.put("pushNetWorkType", message.getPushNetWorkType());//调用个推 获取绑定的个推平台信息绑定的idresponse = httpResponse(postData);String result = LangUtil.parseString(response.get("result"));String contentId = LangUtil.parseString(response.get("contentId"));if ("ok".equals(result) && contentId != null) {return contentId;} else {throw new RuntimeException("host:[" + host + "]获取contentId失败:" + result);}}/*** http 调用方法* @param postData* @return*/public Map<String,Object> httpResponse(Map<String,Object> postData){HttpURLConnection client = null;String response = null;try {postData.put("version", GTConfig.getSDKVersion());postData.put("authToken",null);client = IGtpushHttpClient.buildConnect(postData.get("action").toString());IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());response =IGtpushHttpClient.receiveMsg(client);client.disconnect();Map<String,Object> respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);if ("ok".equals(respData.get("result"))){return respData;}if("sign_error".equals(respData.get("result"))){long timeStamp = System.currentTimeMillis();String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);Map<String, Object> postData1 = new HashMap();postData1.put("action", "connect");postData1.put("appkey", appKey);postData1.put("timeStamp", timeStamp);postData1.put("sign", sign);postData1.put("version", GTConfig.getSDKVersion());client = IGtpushHttpClient.buildConnect(postData1.get("action").toString());IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData1).toString());response =IGtpushHttpClient.receiveMsg(client);client.disconnect();Map<String,Object> respdata =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);//放入authToken 值postData.put("authToken",respdata.get("authtoken"));client = IGtpushHttpClient.buildConnect(postData.get("action").toString());IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());response =IGtpushHttpClient.receiveMsg(client);client.disconnect();respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);if ("ok".equals(respData.get("result"))){return respData;}}} catch (Exception e) {e.printStackTrace();}return null;}
}

运行时需要引入个推的jar包,maven 引入时需要先将jar包上传到服务器中,然后在maven配置文件中。我是用的版本jra包是:

个推使用教程-编程之家

至于详细的文档可以参考官方提供的文档,地址:http://docs.getui.com/getui/server/java/start/

使用个推的时候如果不使用代理的话可以直接使用下载的文件中test工程中的代码,集成jra包后,可以参考单推,群推,直接使用。如果使用代理的话就需要重新写http链接。

个推的单推接口调用没有频次的限制,群推pushToList 接口调用是有频次限制的,就是每天调用200万次,每次发给用户数量建议50,pushToapp 每天不超过100次,每分钟不能超过5次。

使用官方提供的接口时:

每次初始化IGtPush这个类的时候都会去个推平台查询那些可用的推送地址。

然后推送消息的时候,步骤就如我画的流程图一样了,只不过单推pushTosigle 时没有获取TaskId这一步。

—————二更—————————

由于我是使用的服务端,不区分安卓和ios所以使用的消息模板NotificationTemplate(通知)不能够满足要求(这个模板如果添加了iOS带码的话,就不能推送安卓了)所以要将消息模板换成TransmissionTemplate(透传)这个模板,然后在模板中设置三方通知。具体的代码如下:

package com.ruim.ifsp.merser.util;import com.gexin.rp.sdk.base.impl.*;
import com.gexin.rp.sdk.base.notify.Notify;
import com.gexin.rp.sdk.base.payload.APNPayload;
import com.gexin.rp.sdk.base.uitls.Base64Util;
import com.gexin.rp.sdk.base.uitls.LangUtil;
import com.gexin.rp.sdk.base.uitls.SignUtil;
import com.gexin.rp.sdk.dto.GtReq;
import com.gexin.rp.sdk.http.utils.GTConfig;
import com.gexin.rp.sdk.http.utils.ParamUtils;
import com.gexin.rp.sdk.template.TransmissionTemplate;
import com.ruim.ifsp.exception.BizException;
import com.ruim.ifsp.log.IfspLoggerFactory;
import com.ruim.ifsp.merser.cache.CommonConstants;
import com.ruim.ifsp.utils.message.IfspFastJsonUtil;
import org.slf4j.Logger;import java.net.HttpURLConnection;
import java.util.*;public class IGtpushThread extends Thread {private static Logger log = IfspLoggerFactory.getLogger(IGtpushThread.class);private static String appId = CommonConstants.getProperties("IGTAPP_ID");private static String appKey = CommonConstants.getProperties("IGTAPP_KEY");private static String masterSecret = CommonConstants.getProperties("IGTMASTER_SECRET");private static String host = CommonConstants.getProperties("IGTPUST_HOST");private String alias;private String message;private String msgSendType;public IGtpushThread(String alias,String message,String msgSendType) {this.alias = alias;this.message = message;this.msgSendType = msgSendType;}/*** If this thread was constructed using a separate* <code>Runnable</code> run object, then that* <code>Runnable</code> object's <code>run</code> method is called;* otherwise, this method does nothing and returns.* <p>* Subclasses of <code>Thread</code> should override this method.** @see #start()* @see #stop()* @see #(ThreadGroup, Runnable, String)*/@Overridepublic void run() {IGTpushMsg(alias,message,msgSendType);}public void IGTpushMsg(String alias,String message,String msgSendType){String respMsg = new String();String[] arr = alias.split(",");// 通知透传模板 消息传递TransmissionTemplate template = notificationTemplateDemo(message);ListMessage messages = new ListMessage();messages.setData(template);// 设置消息离线,并设置离线时间messages.setOffline(true);// 离线有效时间,单位为毫秒,可选messages.setOfflineExpireTime(24 * 1000 * 3600);// 配置推送目标List targets = new ArrayList();// taskId用于在推送时去查找对应的messagetry{String taskId = getListAppContentId(messages,null);Map<String,Object> postData = null;for (int i = 0; i < arr.length; i++) {Target target = new Target();target.setAppId(appId);target.setAlias(arr[i]);targets.add(target);//每50个别名(CID)推送一次if (arr.length>50&&targets.size()==50){postData =pushMessageToList(taskId,targets);Map<String,Object> response = httpResponse(postData);if (!"ok".equals(response.get("result"))){response = httpResponse(postData);respMsg = IfspFastJsonUtil.mapTOjson(response);log.info("个推建议值推送结果是:"+respMsg);}targets.clear();}}if (targets.size()>0){postData =pushMessageToList(taskId,targets);Map<String,Object> response = httpResponse(postData);if (!"ok".equals(response.get("result"))){response = httpResponse(postData);respMsg = IfspFastJsonUtil.mapTOjson(response);log.info("个推第二次推送结果是:"+respMsg);}}}catch (Exception e){log.error("个推推送失败,原因是:"+e.getMessage());}}public Map<String, Object> pushMessageToList(String contentId, List<Target> targetList) throws Exception{Map<String, Object> postData = new HashMap();postData.put("authToken", null);postData.put("action", "pushMessageToListAction");postData.put("appkey", appKey);postData.put("contentId", contentId);boolean needDetails = GTConfig.isPushListNeedDetails();postData.put("needDetails", needDetails);boolean async = GTConfig.isPushListAsync();postData.put("async", async);boolean needAliasDetails = GTConfig.isPushListNeedAliasDetails();postData.put("needAliasDetails", needAliasDetails);int limit;if (async && !needDetails) {limit = GTConfig.getAsyncListLimit();} else {limit = GTConfig.getSyncListLimit();}if (targetList.size() > limit) {throw new BizException("1000","target size:" + targetList.size() + " beyond the limit:" + limit);} else {List<String> clientIdList = new ArrayList();List<String> aliasList = new ArrayList();String appId = null;Iterator var12 = targetList.iterator();while(true) {Target target;do {if (!var12.hasNext()) {postData.put("appId", appId);postData.put("clientIdList", clientIdList);postData.put("aliasList", aliasList);postData.put("type", 2);return postData;}target = (Target)var12.next();String targetCid = target.getClientId();String targetAlias = target.getAlias();if (targetCid != null && !"".equals(targetCid.trim())) {clientIdList.add(targetCid);} else if (targetAlias != null && !"".equals(targetAlias.trim())) {aliasList.add(targetAlias);}} while(appId != null && !"".equals(appId.trim()));appId = target.getAppId();}}}public TransmissionTemplate notificationTemplateDemo(String message) {
//        NotificationTemplate template = new NotificationTemplate();
//        // 设置APPID与APPKEY
//        template.setAppId(appId);
//        template.setAppkey(appKey);
//        // 设置通知栏标题与内容
//        template.setTitle("黔农E付收款通知");
//        template.setText(message);
//        // 配置通知栏图标
//        template.setLogo("icon.png");// 配置通知栏网络图标
//        template.setLogoUrl("");// 设置通知是否响铃,震动,或者可清除
//        template.setIsRing(true);
//        template.setIsVibrate(true);
//        template.setIsClearable(true);// 透传消息设置,1为强制启动应用,客户端接收到消息后就会立即启动应用;2为等待应用启动
//        template.setTransmissionType(2);
//        template.setTransmissionContent(message);//ios 消息推送
//        APNPayload apnPayload = new APNPayload();
//        APNPayload.SimpleAlertMsg alertMsg = new APNPayload.SimpleAlertMsg(message);
//        apnPayload.setAlertMsg(alertMsg);
//        template.setAPNInfo(apnPayload);
//        return template;TransmissionTemplate template = new TransmissionTemplate();template.setAppId(appId);template.setAppkey(appKey);//设置透传消息template.setTransmissionContent(message);template.setTransmissionType(2);//设置三方通知Notify no = new Notify();no.setTitle("黔农E付收款通知!");no.setContent(message);no.setIntent(""); //客户端生成提供给服务端no.setType(GtReq.NotifyInfo.Type._intent);template.set3rdNotifyInfo(no);//设置ios推送消息APNPayload payload = new APNPayload();payload.setBadge(1);payload.setContentAvailable(1);payload.setSound("default");payload.setCategory("$由客户端定义");//简单模式APNPayload.SimpleMsgpayload.setAlertMsg(new APNPayload.SimpleAlertMsg(message));//字典模式使用下者//payload.setAlertMsg(getDictionaryAlertMsg());template.setAPNInfo(payload);return template;}private String getListAppContentId(Message message, String taskGroupName) {Map<String, Object> postData = new HashMap();Map<String, Object> response = null;if (taskGroupName != null) {postData.put("taskGroupName", taskGroupName);}postData.put("action", "getContentIdAction");postData.put("appkey", appKey);postData.put("clientData", Base64Util.getBASE64(message.getData().getTransparent().toByteArray()));postData.put("transmissionContent", message.getData().getTransmissionContent());postData.put("isOffline", message.isOffline());postData.put("offlineExpireTime", message.getOfflineExpireTime());postData.put("pushType", message.getData().getPushType());postData.put("type", 2);if (message instanceof ListMessage) {postData.put("contentType", 1);} else if (message instanceof AppMessage) {postData.put("contentType", 2);AppMessage appMessage = (AppMessage) message;ParamUtils.checkAppid(message, appMessage.getAppIdList());postData.put("appIdList", appMessage.getAppIdList());List<String> phoneTypeList = null;List<String> provinceList = null;List<String> tagList = null;new ArrayList();if (appMessage.getConditions() == null) {phoneTypeList = appMessage.getPhoneTypeList();provinceList = appMessage.getProvinceList();tagList = appMessage.getTagList();postData.put("phoneTypeList", phoneTypeList);postData.put("provinceList", provinceList);postData.put("tagList", tagList);} else {List<Map<String, Object>> conditions = appMessage.getConditions().getCondition();}postData.put("speed", appMessage.getSpeed());String pushTime = appMessage.getPushTime();if (pushTime != null && !pushTime.isEmpty()) {postData.put("pushTime", pushTime);}}postData.put("pushNetWorkType", message.getPushNetWorkType());//调用个推 获取绑定的个推平台信息绑定的idresponse = httpResponse(postData);String result = LangUtil.parseString(response.get("result"));String contentId = LangUtil.parseString(response.get("contentId"));if ("ok".equals(result) && contentId != null) {return contentId;} else {throw new RuntimeException("host:[" + host + "]获取contentId失败:" + result);}}/*** http 调用方法* @param postData* @return*/public Map<String,Object> httpResponse(Map<String,Object> postData){HttpURLConnection client = null;String response = null;try {postData.put("version", GTConfig.getSDKVersion());postData.put("authToken",null);client = IGtpushHttpClient.buildConnect(postData.get("action").toString());IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());response =IGtpushHttpClient.receiveMsg(client);client.disconnect();Map<String,Object> respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);if ("ok".equals(respData.get("result"))){return respData;}if("sign_error".equals(respData.get("result"))){long timeStamp = System.currentTimeMillis();String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);Map<String, Object> postData1 = new HashMap();postData1.put("action", "connect");postData1.put("appkey", appKey);postData1.put("timeStamp", timeStamp);postData1.put("sign", sign);postData1.put("version", GTConfig.getSDKVersion());client = IGtpushHttpClient.buildConnect(postData1.get("action").toString());IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData1).toString());response =IGtpushHttpClient.receiveMsg(client);client.disconnect();Map<String,Object> respdata =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);//放入authToken 值postData.put("authToken",respdata.get("authtoken"));client = IGtpushHttpClient.buildConnect(postData.get("action").toString());IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());response =IGtpushHttpClient.receiveMsg(client);client.disconnect();respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);if ("ok".equals(respData.get("result"))){return respData;}}} catch (Exception e) {e.printStackTrace();}return null;}//苹果消息弹出框private static APNPayload.DictionaryAlertMsg getDictionaryAlertMsg(){APNPayload.DictionaryAlertMsg alertMsg = new APNPayload.DictionaryAlertMsg();alertMsg.setBody("body");alertMsg.setActionLocKey("ActionLockey");alertMsg.setLocKey("LocKey");alertMsg.addLocArg("loc-args");alertMsg.setLaunchImage("launch-image");// IOS8.2以上版本支持alertMsg.setTitle("Title");alertMsg.setTitleLocKey("TitleLocKey");alertMsg.addTitleLocArg("TitleLocArg");return alertMsg;}
}

透传模板集成到通知中官方提供文档:

1. 概述

  解决接入第三方推送遇到的兼容问题,降低接入成本。

2. 功能名字

2.1应用场景

  为方便接入了第三方厂商推送的客户,更加简便的使用个推透传模板推送,特别对透传模板进行扩展,使透传模板支持以第三方厂商的通知方式进行下发。目前第三方厂商的通知到达率显著高于第三方透传的到达率。

3. 使用方式

3.1使用说明

  使用透传模板时,设置notify对象的title, content, intent等参数。

Notify的说明

成员和方法名

类型

必填

说明

setTitle

String

通知栏标题

setContent

String

通知栏内容

setUrl

String

点击通知,打开应用的链接

setIntent

String

长度小于1000字节,通知带intent传递参数推荐使用,intent最好由Android开发工程师生成,生成方式见附录

setType

Type

取值为(Type._url、Type._intent),如果设置了url、intent,需要指定Type对应的类型;Type所在的包为:com.gexin.rp.sdk.dto.GtReq.NotifyInfo

 

 

 

 

 

 

public static TransmissionTemplate transmissionTemplateDemo(String appId, String appKey){

  TransmissionTemplate template = new TransmissionTemplate();

  template.setAppId(appId);

  template.setAppkey(appKey);

  template.setTransmissionContent("透传内容");

  template.setTransmissionType(2);

  Notify notify = new Notify();

  notify.setTitle("请输入通知栏标题");

  notify.setContent("请输入通知栏内容");

notify.setIntent("intent:#Intent;launchFlags=0x10000000;package=com.pp.yl;component=你的包名

/com.getui.demo.MainActivity;i.parm1=12;end");

notify.setType(Type._intent);

// notify.setUrl("https://dev.getui.com/");

//notify.setType(Type._url);

  template.set3rdNotifyInfo(notify);//设置第三方通知

  return template;

 }

 

4. 功能代码示例

 

 

 

5. 附录:Andriod开发工程师生成intent参考

  Andriod开发工程师生成intent,可以在Android代码中定义一个Intent,然后通过Intent.toUri(Intent.URI_INTENT_SCHEME)获取对应的Intent Uri。

 

Intent intent = new Intent();

 

5.1生成Intent

 

 

5.2设置 package(可选)

  如果设置了package,则表示目标应用必须是package所对应的应用。

 

intent.setPackage("com.getui.demo");

 

 

 

5.3设置 component (必选)

  component为目标页面的准确activity路径,component中包含应用包名和activity类的全路径。

 

intent.setComponent(new ComponentName("com.getui.demo", "com.getui.demo.TestActivity"));

 

 

 

5.4设置 launchFlags (不起作用)

  launcherFlags 可指定在启动activity时的启动方式,个推sdk以及厂商sdk在启动activity时会自动设置为FLAG_ACTIVITY_NEW_TASK,所以该设置没有实际意义。

5.5设置参数

 

intent.putExtra("stringType", "string");

intent.putExtra("booleanType", true);

intent.putExtra("doubleType", 1.0);

intent.putExtra("floatType", 1.0f);

intent.putExtra("longType", 1L);

intent.putExtra("intType", 1);

// 还有其他类型的参数可以设置,通过查找`putExtra`方法的重载方法即可

  可通过intent.putExtra方法设置一系列的参数。

 

 

 

 

 

5.6设置action

 

//设置action

intent.setAction("android.intent.action.oppopush");

  由于oppo sdk仅支持通过action的方式打开activity,所以若您的应用需要支持oppo推送(打开指定页面),您需要在intent中设置action,并在AndroidManifet.xml配置对应的action,如下:

 

 

 

 

<!– android:exported="true" 必须配置,否则在华为机型上无法启动–>

<activity android:name="com.getui.demo.TestActivity"

         android:exported="true">

    <intent-filter>

    <!– category 为必须设置项 设置为 android.intent.category.DEFAULT 即可–>

    <category android:name="android.intent.category.DEFAULT" />

    <action android:name="android.intent.action.oppopush" />

     </intent-filter>

 </activity>

AndroidManifet.xml配置如下:

 

 

 

 

 

 

 

 

 

5.7生成 intent uri

 

Log.d(TAG, intent.toUri(Intent.URI_INTENT_SCHEME));

 

 

 

打印结果为:intent:#Intent;action=android.intent.action.oppopush;package=com.getui.demo;component=com.getui.demo/com.getui.demo.TestActivity;f.floatType=1.0;l.longType=1;B.booleanType=true;S.stringType=string;d.doubleType=1.0;i.intType=1;end

将生成的intent uri交给服务端开发人员,在对应模板的setIntent方法中设置即可。

 

=====================三更====================================

使用jmeter测试,发现每次访问个推平台消耗时间大概是300毫秒左右,发送一次推送如果走完所有的流程,需要大概2500毫秒,很耗时间。而且,目前在生产上有用户反馈收不到推送信息,经过排查得知当日的推送消息次数超过了200万次,而多推pushListMessage有这个次数限制。所以需要优化这个推送流程。经过询问个推的开发人员得知,在交互的过程中获取鉴权码,鉴权码的有效期是24个小时,另外接口pushSingleMessage推送是没有次数限制。本次优化的流程思路就是将鉴权码保存到redis中,并设置有效期,推送接口使用单推+多推相结合的方式行优化。目前从测试结果来开个推使用还是有些问题。问题一:个推使用多推时离线发送(只有ios,所谓离线就是退出app页面,个推离线推送的时候会将消息推送给厂商,厂商将消息推送到设备,这个时间不可控,测试环境中,有时间延时,个推厂商给解释说开发环境苹果厂商推送不稳定)会有1~2分钟的时延。问题二:个推使用单推的时候,ios手机推出app,收不到推送消息,个推开发人员解释是开发环境苹果厂商aoip 推送不稳。鉴于这两种给推送结果,目前占时开发出两套优化流程 1. 单推+多推(生产上测试,测试没有问题,优先使用这个),2.多推 (1不行才采用这个方)

优化后代码流程:

1.单推:

个推使用教程-编程之家

2.多推:

个推使用教程-编程之家

优化后代码:

/***@author lxw*@date 2019/12/20*@desc  安卓群推*@param alias, message, msgSendType*@return void**/public void IGTandroidPushMsg(String alias,String message){log.info("安卓用户{}开始推送日志.....",alias);String respMsg = new String();String[] arr = alias.split(",");// 通知透传模板 消息传递NotificationTemplate nTemplate = notificationTemplateDemo(message);ListMessage messages = new ListMessage();messages.setData(nTemplate);// 设置消息离线,并设置离线时间messages.setOffline(true);// 离线有效时间,单位为毫秒,可选messages.setOfflineExpireTime(24 * 1000 * 3600);// 配置推送目标List targets = new ArrayList();// taskId用于在推送时去查找对应的messagetry{String taskId = getListAppContentId(messages,null);Map<String,Object> postData = null;for (int i = 0; i < arr.length; i++) {Target target = new Target();target.setAppId(appId);target.setAlias(arr[i]);targets.add(target);//每50个别名(CID)推送一次if (arr.length>50&&targets.size()==50){postData =pushMessageToList(taskId,targets);Map<String,Object> response = httpResponse(postData);if (!IGParams.PUSH_MSG_OK.equals(response.get("result"))){response = httpResponse(postData);respMsg = IfspFastJsonUtil.mapTOjson(response);}targets.clear();}}if (targets.size()>0) {postData = pushMessageToList(taskId, targets);Map<String, Object> response = httpResponse(postData);if (IGParams.PUSH_NO_TARGET.equals(response.get("result"))||IGParams.PUSH_MSG_OK.equals(response.get("result"))) {log.info("用户{}个推推送结果是:" + response.get("result"),alias);}else {response = httpResponse(postData);respMsg = IfspFastJsonUtil.mapTOjson(response);log.info("用户{}个推第二次推送结果是:" + respMsg,alias);}}}catch (Exception e){log.error("安卓用户{}推送失败,原因是:"+e.getMessage(),alias);}}/***@author lxw*@date 2019/12/20*@desc 苹果群推*@param alias, message, msgSendType*@return void**/public void IGTIosPushMsg(String alias,String message){log.info("ios用户{}开始推送.....",alias);String respMsg = new String();String[] arr = alias.split(",");//透传模板 消息传递TransmissionTemplate tTemplate = transmissionTemplateDemo(message);ListMessage messages = new ListMessage();messages.setData(tTemplate);// 设置消息离线,并设置离线时间messages.setOffline(true);// 离线有效时间,单位为毫秒,可选messages.setOfflineExpireTime(24 * 1000 * 3600);// 配置推送目标List targets = new ArrayList();// taskId用于在推送时去查找对应的messagetry{String taskId = getListAppContentId(messages,null);Map<String,Object> postData = null;for (int i = 0; i < arr.length; i++) {Target target = new Target();target.setAppId(appId);target.setAlias(arr[i]);targets.add(target);//每50个别名(CID)推送一次if (arr.length>50&&targets.size()==50){postData =pushMessageToList(taskId,targets);Map<String,Object> response = httpResponse(postData);if (!IGParams.PUSH_MSG_OK.equals(response.get("result"))){response = httpResponse(postData);respMsg = IfspFastJsonUtil.mapTOjson(response);}targets.clear();}}if (targets.size()>0){postData =pushMessageToList(taskId,targets);Map<String,Object> response = httpResponse(postData);if (IGParams.PUSH_NO_TARGET.equals(response.get("result"))||IGParams.PUSH_MSG_OK.equals(response.get("result"))) {log.info("用户{}个推推送结果是:" + response.get("result"),alias);}else {response = httpResponse(postData);respMsg = IfspFastJsonUtil.mapTOjson(response);log.info("用户{}再次推送结果是:" + response.get("result"),alias);}}}catch (Exception e){log.error("ios用户{}推送失败,原因是:"+e.getMessage(),alias);}}/***@author lxw*@date 2019/12/20*@desc 群推消息参数组装*@param contentId, targetList*@return java.util.Map<java.lang.String,java.lang.Object>**/public Map<String, Object> pushMessageToList(String contentId, List<Target> targetList) throws Exception{log.info("pushMessageToList组装推送参数开始,用户taskid:{}。。。。",contentId);Map<String, Object> postData = new HashMap();postData.put("authToken", getAuthTokenCache().opsForValue().get("authToken")==null?"":getAuthTokenCache().opsForValue().get("authToken"));postData.put("action", "pushMessageToListAction");postData.put("appkey", appKey);postData.put("contentId", contentId);boolean needDetails = GTConfig.isPushListNeedDetails();postData.put("needDetails", needDetails);boolean async = GTConfig.isPushListAsync();postData.put("async", async);boolean needAliasDetails = GTConfig.isPushListNeedAliasDetails();postData.put("needAliasDetails", needAliasDetails);int limit;if (async && !needDetails) {limit = GTConfig.getAsyncListLimit();} else {limit = GTConfig.getSyncListLimit();}if (targetList.size() > limit) {throw new BizException("1000","target size:" + targetList.size() + " beyond the limit:" + limit);} else {List<String> clientIdList = new ArrayList();List<String> aliasList = new ArrayList();String appId = null;Iterator var12 = targetList.iterator();while(true) {Target target;do {if (!var12.hasNext()) {postData.put("appId", appId);postData.put("clientIdList", clientIdList);postData.put("aliasList", aliasList);postData.put("type", 2);return postData;}target = (Target)var12.next();String targetCid = target.getClientId();String targetAlias = target.getAlias();if (targetCid != null && !"".equals(targetCid.trim())) {clientIdList.add(targetCid);} else if (targetAlias != null && !"".equals(targetAlias.trim())) {aliasList.add(targetAlias);}} while(appId != null && !"".equals(appId.trim()));appId = target.getAppId();}}}//通知消息public NotificationTemplate notificationTemplateDemo(String message) {NotificationTemplate template = new NotificationTemplate();// 设置APPID与APPKEYtemplate.setAppId(appId);template.setAppkey(appKey);Style0 style = new Style0();style.setTitle("黔农E付收款通知");// 设置通知栏标题与内容style.setText(message);// 配置通知栏网络图标style.setLogo("icon.png");// 设置通知是否响铃,震动,或者可清除style.setRing(true);style.setVibrate(true);style.setClearable(true);// 透传消息设置,1为强制启动应用,客户端接收到消息后就会立即启动应用;2为等待应用启动template.setTransmissionType(1);template.setTransmissionContent(message);template.setStyle(style);return template;}//透传消息public TransmissionTemplate transmissionTemplateDemo(String message) {Map<String,String> msgMap = new HashMap<>();msgMap.put("黔农商户宝",message);TransmissionTemplate template = new TransmissionTemplate();template.setAppId(appId);template.setAppkey(appKey);//透传消息设置template.setTransmissionContent(IfspFastJsonUtil.mapTOjson(msgMap));template.setTransmissionType(2);//ios 消息推送APNPayload payload = new APNPayload();payload.setAutoBadge("1");payload.setContentAvailable(0);payload.setVoicePlayType(1);payload.setSound("default");payload.setCategory("$由客户端定义");VoIPPayload voIPPayload = new VoIPPayload();Map<String,Object> vp = new HashMap<>();vp.put("titile","黔农E付收款通知");vp.put("message",message);vp.put("payload","payload");voIPPayload.setVoIPPayload(IfspFastJsonUtil.mapTOjson(vp));template.setAPNInfo(voIPPayload);return template;}//获取群推的taskidprivate String getListAppContentId(Message message, String taskGroupName) {Map<String, Object> postData = new HashMap();Map<String, Object> response = null;if (taskGroupName != null) {postData.put("taskGroupName", taskGroupName);}postData.put("action", "getContentIdAction");postData.put("appkey", appKey);postData.put("clientData", Base64Util.getBASE64(message.getData().getTransparent().toByteArray()));postData.put("transmissionContent", message.getData().getTransmissionContent());postData.put("isOffline", message.isOffline());postData.put("offlineExpireTime", message.getOfflineExpireTime());postData.put("pushType", message.getData().getPushType());postData.put("type", 2);if (message instanceof ListMessage) {postData.put("contentType", 1);} else if (message instanceof AppMessage) {postData.put("contentType", 2);AppMessage appMessage = (AppMessage) message;ParamUtils.checkAppid(message, appMessage.getAppIdList());postData.put("appIdList", appMessage.getAppIdList());List<String> phoneTypeList = null;List<String> provinceList = null;List<String> tagList = null;new ArrayList();if (appMessage.getConditions() == null) {phoneTypeList = appMessage.getPhoneTypeList();provinceList = appMessage.getProvinceList();tagList = appMessage.getTagList();postData.put("phoneTypeList", phoneTypeList);postData.put("provinceList", provinceList);postData.put("tagList", tagList);} else {List<Map<String, Object>> conditions = appMessage.getConditions().getCondition();}postData.put("speed", appMessage.getSpeed());String pushTime = appMessage.getPushTime();if (pushTime != null && !pushTime.isEmpty()) {postData.put("pushTime", pushTime);}}postData.put("pushNetWorkType", message.getPushNetWorkType());//调用个推 获取绑定的个推平台信息绑定的idresponse = httpResponse(postData);String result = LangUtil.parseString(response.get("result"));String contentId = LangUtil.parseString(response.get("contentId"));if (IGParams.PUSH_MSG_OK.equals(result) && contentId != null) {return contentId;} else {throw new RuntimeException("host:[" + host + "]获取contentId失败:" + result);}}/*** http 调用方法* @param postData* @return*/public Map<String,Object> httpResponse(Map<String,Object> postData){log.info("调用平台传参:"+IfspFastJsonUtil.mapTOjson(postData));HttpURLConnection client = null;String response = null;Map<String,Object> respData = new HashMap<>();try {postData.put("version", GTConfig.getSDKVersion());postData.put("authToken",getAuthTokenCache().opsForValue().get("authToken")==null?"":getAuthTokenCache().opsForValue().get("authToken"));client = IGtpushHttpClient.buildConnect(postData.get("action").toString());IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());response =IGtpushHttpClient.receiveMsg(client);client.disconnect();respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);if(IGParams.PUSH_SIGN_ERROR.equals(respData.get("result"))){long timeStamp = System.currentTimeMillis();String sign = SignUtil.getSign(appKey, masterSecret, timeStamp);Map<String, Object> postData1 = new HashMap();postData1.put("action", "connect");postData1.put("appkey", appKey);postData1.put("timeStamp", timeStamp);postData1.put("sign", sign);postData1.put("version", GTConfig.getSDKVersion());client = IGtpushHttpClient.buildConnect(postData1.get("action").toString());IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData1).toString());response =IGtpushHttpClient.receiveMsg(client);client.disconnect();Map<String,Object> respdata =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);//放入authToken 值postData.put("authToken",respdata.get("authtoken"));//将authToken 放入redis 并设置超时时间getAuthTokenCache().opsForValue().set("authToken",(String)respdata.get("authtoken"),TimeUnit.HOURS.toHours(24),TimeUnit.HOURS);client = IGtpushHttpClient.buildConnect(postData.get("action").toString());IGtpushHttpClient.sendMsg(client, IfspFastJsonUtil.mapTOjson(postData).toString());response =IGtpushHttpClient.receiveMsg(client);client.disconnect();respData =(Map<String,Object>)IfspFastJsonUtil.jsonTOmap(response);return respData;}return respData;} catch (Exception e) {log.error("个推接收响应信息失败,原因是:"+e.getMessage());}return respData;}//苹果消息弹出框private static APNPayload.DictionaryAlertMsg getDictionaryAlertMsg(String message){APNPayload.DictionaryAlertMsg alertMsg = new APNPayload.DictionaryAlertMsg();alertMsg.setBody(message);alertMsg.setTitle("黔农E付收款通知");return alertMsg;}/***@author lxw*@date 2019/12/20*@desc 单推消息参数组装*@param message, target, requestId*@return java.util.Map<java.lang.String,java.lang.Object>**/public Map<String, Object> pushMessageToSingle(Message message, Target target, String requestId) {HttpURLConnection client = null;String  response = new String();if (requestId == null || "".equals(requestId.trim())) {requestId = UUID.randomUUID().toString();}Map<String, Object> pushResult = new HashMap<>();ParamUtils.checkAppid(message, target);Map<String, Object> postData = this.getSingleMessagePostData(message, target, requestId);try {pushResult = httpResponse(postData);}catch (Exception e){log.error("单推失败!"+e.getMessage());}return pushResult;}/***@author lxw*@date 2019/12/20*@desc 单推上送消息组装*@param message, target, requestId*@return java.util.Map<java.lang.String,java.lang.Object>**/Map<String, Object> getSingleMessagePostData(Message message, Target target, String requestId) {Map<String, Object> postData = new HashMap();postData.put("action", "pushMessageToSingleAction");postData.put("appkey", this.appKey);if (requestId != null) {postData.put("requestId", requestId);}postData.put("clientData", Base64Util.getBASE64(message.getData().getTransparent().toByteArray()));postData.put("transmissionContent", message.getData().getTransmissionContent());postData.put("isOffline", message.isOffline());postData.put("offlineExpireTime", message.getOfflineExpireTime());postData.put("appId", target.getAppId());postData.put("clientId", target.getClientId());postData.put("alias", target.getAlias());postData.put("type", 2);postData.put("pushType", message.getData().getPushType());postData.put("pushNetWorkType", message.getPushNetWorkType());return postData;}/***@author lxw*@date 2019/12/20*@desc 安卓单推*@param alias, message, msgSendType*@return void**/public void iGSinglePust(String alias,String message) {log.info("安卓用户{}开始推送。。。",alias);NotificationTemplate template = notificationTemplateDemo(message);SingleMessage messages = new SingleMessage();messages.setOffline(true);// 离线有效时间,单位为毫秒,可选messages.setOfflineExpireTime(24 * 3600 * 1000);messages.setData(template);// 可选,1为wifi,0为不限制网络环境。根据手机处于的网络情况,决定是否下发messages.setPushNetWorkType(0);Target target = new Target();target.setAppId(appId);target.setAlias(alias);Map<String, Object> ret = null;try {ret = pushMessageToSingle(messages, target,null);} catch (RequestException e) {log.error("服务器响应异常:"+e.getMessage());ret = pushMessageToSingle(messages, target, e.getRequestId());}}/***@author lxw*@date 2019/12/20*@desc ios单推*@param alias, message, msgSendType*@return void**/public void iGSinglePustIOS(String alias,String message) {log.error("苹果用户{}开始推送",alias);TransmissionTemplate template =  transmissionTemplateDemo(message);SingleMessage messages = new SingleMessage();messages.setOffline(true);// 离线有效时间,单位为毫秒,可选messages.setOfflineExpireTime(24 * 3600 * 1000);messages.setData(template);// 可选,1为wifi,0为不限制网络环境。根据手机处于的网络情况,决定是否下发messages.setPushNetWorkType(0);Target target = new Target();target.setAppId(appId);target.setAlias(alias);Map<String, Object> ret = null;try {ret = pushMessageToSingle(messages, target,null);} catch (RequestException e) {log.error("服务器响应异常:"+e.getMessage());ret = pushMessageToSingle(messages, target, e.getRequestId());}}//获取spring中redis 注册的beanpublic IfspRedisCacheOperation<String> getPushRedisCacheOperation(){return (IfspRedisCacheOperation<String>) IfspSpringContextUtils.getInstance().getBean("pushRedisCache");}public IfspRedisCacheOperation<String> getAuthTokenCache(){return (IfspRedisCacheOperation<String>) IfspSpringContextUtils.getInstance().getBean("authTokenRedisCache");}

http 链接还是使用最上方的链接

工具类:

public Static final String PUSH_SIGN_ERROR="sign_error";
public Static final String PUSH_NO_TARGET="NOTarget";
public Static final String PUSH_MSG_OK="ok";

总结:

1.目前生产使用模式是单推+多推结合的方式。

2.个推推送分为 离线推送、在线推送,在线推送是指 个推平台将消息推送给手机,离线推送是指 个推将消息推送给手机厂商,由厂商来推送消息。区分是离线推送还是在线推送,可以查看推送成功后的响应报文中有个推送状态,那里会显示是离线推送还是在线推送。

3.手机接收不到消息问题排查

    3.1:核对配置参数是否正确(appId,appKey,masterScript…..);

    3.2:如果是使用别名推送,查看推送是否绑定了cid(个推为每个手机设备分配的识别码,每个手机只能生成一个,不会变);个推平台提供了方法查询别名下绑定的cid 个数,每个别名只能绑定10个cid。别名绑定超过10时候,新绑定的cid 会将已经绑定的cid其中一个顶掉。别名下cid 查询:

import com.gexin.rp.sdk.base.IAliasResult;
import com.gexin.rp.sdk.http.IGtPush;public class GETTUIaLIAS {private static String appId = "QFoBXS1TrJ9yc";//个推上配置的appIdprivate static String appKey = "M2FJjXxnP3Ark";//个推上配置的appKey private static String masterSecret = "aWU9lqy8CX6EP";//个推上配置的masterSecret static String host = "http://sdk.open.api.igexin.com/apiex.htm";public static void main(String[] args) {String Alias = "8201807060000001_13641064684";//要查询的别名IGtPush push = new IGtPush(host, appKey, masterSecret);IAliasResult queryClient = push.queryClientId(appId, Alias);System.out.println("根据别名获取的CID:" + queryClient.getClientIdList());}
}

,服务端是获取不到每个手机的cid ,需要客户端(app端) 来获取cid。查看cid 所属苹果或者安卓可以去个推平台个推使用教程-编程之家

中,输入别名下查询出cid ,就可以查看出手机型号和所属手机厂商。