业务需求:公司内部做了一款APP供用户使用,后期公司会定期给使用该APP的用户推送及时消息,开发中借助“友盟”推送完成了该功能,先将集成的代码提供如下,仅供参考。参考文档: https://developer.umeng.com/docs/67966/detail/68343
import com.alibaba.fastjson.JSON;
import com.ymkj.ymzs.utils.friendsUtil.android.AndroidBroadcast;
import com.ymkj.ymzs.utils.friendsUtil.ios.IOSBroadcast;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author wyc
* @Description: 友盟--给安卓手机/苹果手机用户 推送及时消息工具类
* @date 2020/10/26 15:31
* @return
*/
@Component
public class SendFriendsMsgUtil {
/*
* 正式环境配置地址
*/
private static String ANDROID_APPKEY = "5dc3e4394ca357ef92000b92";
private static String ANDROID_MASTERSECRET = "9vihjetlrejjfuc4dndgwr2jhrqiwuxm";
private static String IOS_APPKEY = "5f2132ddb99afd56c26e7983";
private static String IOS_MASTERSECRET = "abphm7ce1r9kailv5cz6tulnzskk3juf";
/*
*测试环境配置地址
private static String ANDROID_APPKEY = "5f9015a42065791705f45568";
private static String ANDROID_MASTERSECRET = "pgexaw1qq0tfuvxfp4lpgrnvpz5mvw7n";
private static String IOS_APPKEY = "5f901518c1122b44acfc9c40";
private static String IOS_MASTERSECRET = "gmuolqh6i1ooapdy4xwahalb64jhnrop";
*
*/
//苹果推送环境选择 1-正式环境 2-测试环境
// private static Integer PRODUCTION_MODE = 2;
private static Integer PRODUCTION_MODE = 1;
private static String USER_AGENT = "Mozilla/5.0";
// The host
private static String host = "http://msg.umeng.com";
// The post path
private static String postPath = "/api/send";
public static void main(String[] args) throws Exception {
// SendFriendsMsgUtil.androidSendMsg(5506, "--5506--", "测试:推送", "订单审核消息测试收到货时代开始的思考达克赛德", "customizedcast", "", null, 19);
SendFriendsMsgUtil.androidSendMsg(3567, "--8888883567安卓测试--", "测试:推送", "时代开始的思考达克赛德", "customizedcast", "", null, 19);
// SendFriendsMsgUtil.iosSendMsg(4447, "---IOS---消息标题测试环境---", "测试:PRODUCTION_MODE", "测试环境------", "customizedcast", "", null, 19);
}
/**
* 友盟 推送android及时消息 《单推》
*
* @param userId 推送对象的住建id
* @param title 消息标题
* @param text 消息内容
* @param type 消息类型--单发信息:customizedcast
* @param toUrl 附加参数:要跳转的链接地址
* @param curriculumId 消息内容:课程主键id
* @param messageType // 推送链接类型:1,首页 2、发现 3、精选 4,咨询(带链接)5,会员 6,会员-图库 7,会员-视频 8,开通会员页面
* //9,我的钱包 10,我的上传 11,水印设置12,一美课堂 13、一美课堂-单个课程 14,活动h5(带链接)
* //15,订单审核 16,水印审核 17,水印申请通过 18,水印申请驳回
* @throws Exception
*/
public static int androidSendMsg(Integer userId, String title, String ticker, String text, String type, String toUrl, Integer curriculumId, Integer messageType) throws Exception {
// 可选,发送消息描述,建议填写。
String description = "给部分android用户推送消息";
//时间戳
long timestamp = System.currentTimeMillis();
//友盟接口请求url
String url = host + postPath;
/****---------Android推送-json数据组装----------------------------------*****/
StringBuffer str = new StringBuffer();
str.append("{ ");
//消息描述
str.append(" \"description\":\"" + description + "\", ");
// 可选,正式/测试模式。默认为true
str.append(" \"production_mode\":\"true\", ");
str.append(" \"appkey\":\"" + ANDROID_APPKEY + "\", ");
//请求参数的主题
str.append(" \"payload\":{ ");
//android推送的信息内容 参数主要部分
str.append(" \"body\": { ");
str.append(" \"title\":\"" + title + "\", ");
str.append(" \"ticker\":\"" + ticker + "\", ");
str.append(" \"text\":\"" + text + "\", ");
// 可选,收到通知是否震动,默认为"true"
str.append(" \"play_vibrate\":\"true\", ");
// 可选,收到通知是否闪灯,默认为"true"
str.append(" \"play_lights\":\"true\", ");
// 可选,收到通知是否发出声音,默认为"true"
str.append(" \"play_sound\":\"true\", ");
if (messageType != null && !messageType.equals(0)) {
// 可选,默认为"go_url"
str.append(" \"after_open\":\"go_custom\", ");
// 自定义参数
str.append(" \"custom\":\"" + messageType + "\" ");
} else {
// 可选,默认为"go_app",值可以为:"go_app": 打开应用,"go_url": 跳转到URL,"go_activity": 打开特定的activity,"go_custom": 用户自定义内容。
str.append(" \"after_open\":\"go_app\" ");
}
str.append(" }, ");
// 必填,消息类型: notification(通知)、message(消息)
str.append(" \"display_type\":\"notification\",");
str.append(" \"extra\": { ");
if (messageType != null) {
if (messageType == 4 || messageType == 14) {
//发送链接地址给用户
str.append(" \"toUrl\":\"" + toUrl + "\"");
} else if (messageType == 13) {
//发送课程给用户
str.append(" \"curriculumId\":\"" + curriculumId + "\"");
} else {
//
str.append(" \"messageType\":\"" + messageType + "\"");
}
}
str.append(" }");
str.append(" } ,");
//当type=customizedcast时, 必填alias的类型, alias_type可由开发者自定义,开发者在SDK中调用setAlias(alias, alias_type)时所设置的alias_type
str.append(" \"alias\":\"" + userId + "\", ");
//跟android协商后自定义的key。例如约定为‘userId’
str.append(" \"alias_type\":\"userId\", ");
// broadcast-广播
str.append(" \"type\":\"" + type + "\", ");
str.append(" \"timestamp\":\"" + timestamp + "\" ");
str.append("}");
System.out.println(str);
//对请求的所有参数加密
String sign = DigestUtils.md5Hex(("POST" + url + str + ANDROID_MASTERSECRET).getBytes("utf8"));
url = url + "?sign=" + sign;
int status = friendsMsgPost(url, str.toString());
return status;
}
/**
* 像所有Android的用户推送消息
*
* @param title 消息标题
* @param ticker 消息描述
* @param text 消息内容
* @param messageType 推送的链接类型
* @param toUrl 推送的链接地址
* @param curriculumId 要推送的课程主键id
* @return
* @throws Exception 群发
*/
public static int sendAndroidAllBroadcast(String title, String ticker, String text, String toUrl, Integer curriculumId, Integer messageType) throws Exception {
String url = host + postPath;
String description = "给所有android用户推送及时消息";
AndroidBroadcast broadcast = new AndroidBroadcast(ANDROID_APPKEY, ANDROID_MASTERSECRET);
broadcast.setTicker(ticker);
broadcast.setTitle(title);
broadcast.setText(text);
broadcast.setCustomField(messageType.toString());
if (messageType == 4 || messageType == 14) {
//发送链接地址给用户
broadcast.setExtraField("toUrl", toUrl);
} else if (messageType == 13) {
//发送课程给用户
broadcast.setExtraField("curriculumId", curriculumId.toString());
}
long timestamp = System.currentTimeMillis();
broadcast.setTimestamp(String.valueOf(timestamp));
broadcast.setDescription(description);
broadcast.setProductionMode();// 可选,正式/测试模式。默认为true
broadcast.goAppAfterOpen();
broadcast.setDisplayType(AndroidNotification.DisplayType.NOTIFICATION);
String postBody = broadcast.getPostBody();
System.out.println("postBody:" + postBody);
//加密
String sign = DigestUtils.md5Hex(("POST" + url + postBody + ANDROID_MASTERSECRET).getBytes("utf8"));
url = url + "?sign=" + sign;
int status = friendsMsgPost(url, postBody);
return status;
}
/****---------IOS推送-----------------------------------*****/
/**
* 单推:选择性的给某个/某些用户推送友盟及时消息
*
* @param userId : 推送的用户的id
* @param title :消息标题
* @param ticker :消息体描述
* @param text :消息内容
* @param messageType // 推送链接类型:1,首页 2、发现 3、精选 4,咨询(带链接)5,会员 6,会员-图库 7,会员-视频 8,开通会员页面
* //9,我的钱包 10,我的上传 11,水印设置12,一美课堂 13、一美课堂-单个课程 14,活动h5(带链接)
* //15,订单审核 16,水印审核 17,水印申请通过 18,水印申请驳回
* @return
* @throws Exception
*/
public static int iosSendMsg(Integer userId, String title, String ticker, String text, String type, String toUrl, Integer curriculumId, Integer messageType) throws Exception {
// 可选,发送消息描述,建议填写。
String description = "给部分ios用户推送及时消息";
//请求url
String url = host + postPath;
/****---------IOS推送-----------------------------------*****/
StringBuffer str = new StringBuffer();
str.append("{ ");
str.append(" \"appkey\":\"" + IOS_APPKEY + "\", ");
long timestamp = System.currentTimeMillis();
str.append(" \"timestamp\":\"" + timestamp + "\", ");
//customizedcast,通过alias进行推送,包括以下两种case: - alias: 对单个或者多个alias进行推送 - file_id: 将alias存放到文件后,根据file_id来推送
str.append(" \"type\":\"" + type + "\", ");
str.append(" \"alias_type\":\"userId\", ");
//当type=customizedcast时, 必填alias的类型, alias_type可由开发者自定义,开发者在SDK中调用setAlias(alias, alias_type)时所设置的alias_type
str.append(" \"alias\":\"" + userId + "\", ");
//参数主题部分
str.append(" \"payload\":{ ");
//ios推送的信息内容
// 必填,严格按照APNs定义来填写
str.append(" \"aps\": { ");
//当content-available=1时(静默推送),可选; 否则必填。 可为JSON类型和字符串类型
str.append(" \"alert\": { ");
str.append(" \"title\":\"" + title + "\", ");
str.append(" \"subtitle\":\"" + ticker + "\", ");
str.append(" \"body\":\"" + text + "\" ");
str.append(" }, ");
// 可选,代表静默推送
str.append(" \"sound\":\"default\",");
// 附加参数
str.append(" \"category\":\"" + messageType + "\"");
str.append(" } ,");
if (messageType != null) {
//传递附加参数
if (messageType == 4 || messageType == 14) {
//发送链接地址给用户
str.append(" \"toUrl\":\"" + toUrl + "\"");
} else if (messageType == 13) {
//发送课程给用户
str.append(" \"curriculumId\":\"" + curriculumId + "\"");
} else {
//订单审核:给订单审核的员工推送消息
str.append(" \"messageType\":\"" + messageType + "\"");
}
}
str.append(" }, ");
if (PRODUCTION_MODE == 1) {
// 可选,正式/测试模式。默认为true
str.append(" \"production_mode\":\"true\", ");
} else {
// 可选,正式/测试模式。默认为true
str.append(" \"production_mode\":\"false\", ");
}
//消息描述
str.append(" \"description\":\"" + description + "\" ");
str.append("}");
System.out.println("ios友盟请求参数json:\n" + JSON.parse(String.valueOf(str)));
//将请求的参数加密
String sign = DigestUtils.md5Hex(("POST" + url + str + IOS_MASTERSECRET).getBytes("utf8"));
//请求的url
url = url + "?sign=" + sign;
int status = friendsMsgPost(url, str.toString());
// System.out.println(("单发--IOS友盟消息 返回状态status:" + status));
return status;
}
/**
* 像所有ios的用户推送消息
*
* @param title 消息标题
* @param ticker 消息体描述
* @param text 消息内容
* @return
* @throws Exception 群发
*/
public static int sendIosAllBroadcast(String title, String ticker, String text, String toUrl, Integer curriculumId, Integer messageType) throws Exception {
// 可选,发送消息描述,建议填写。
String description = "给全部ios用户推送及时消息";
String url = host + postPath;
IOSBroadcast broadcast = new IOSBroadcast(IOS_APPKEY, IOS_MASTERSECRET);
JSONObject alert = new JSONObject();
alert.put("title", ticker);
alert.put("subtitle", title);
alert.put("body", text);
broadcast.setAlert(alert);
broadcast.setBadge(0);
broadcast.setSound("default");
broadcast.setCategory(messageType + "");
if (messageType == 4 || messageType == 14) {
//发送链接地址给用户
broadcast.setCustomizedField("toUrl", toUrl);
} else if (messageType == 13) {
//发送课程给用户
broadcast.setCustomizedField("curriculumId", curriculumId.toString());
}
broadcast.setDescription(description);
long timestamp = System.currentTimeMillis();
broadcast.setTimestamp(String.valueOf(timestamp));
if (PRODUCTION_MODE == 1) {
// 可选,正式/测试模式。默认为true
broadcast.setProductionMode(true);
} else {
// 可选,正式/测试模式。默认为true
broadcast.setProductionMode(false);
}
String postBody = broadcast.getPostBody();
System.out.println("ios返回数据:" + postBody);
//加密
String sign = DigestUtils.md5Hex(("POST" + url + postBody + IOS_MASTERSECRET).getBytes("utf8"));
url = url + "?sign=" + sign;
int status = friendsMsgPost(url, postBody);
return status;
}
/**
* 友盟post请求封装
*
* @param url : 请求地址
* @param str : 请求的参数
* @return
* @throws IOException
*/
private static int friendsMsgPost(String url, String str) throws IOException {
//发送post请求
HttpPost post = new HttpPost(url);
post.setHeader("User-Agent", USER_AGENT);
StringEntity se = new StringEntity(str, "UTF-8");
post.setEntity(se);
HttpClient client = new DefaultHttpClient();
// 发送post请求
HttpResponse response = client.execute(post);
int status = response.getStatusLine().getStatusCode();
System.out.println("发送友盟请求,返回状态:" + status);
//解析返回后的数据 方便快捷的定位请求的异常
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
if (status == 200) {
System.out.println("Notification sent successfully.");
} else {
System.out.println("Failed to send the notification!");
}
return status;
}