package com.mailssenger.push;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Map;
import com.mailssenger.util.L;
public class BaiduPush {
public final static String mUrl = "http://channel.api.duapp.com/rest/2.0/channel/";// 基础url
public final static String HTTP_METHOD_POST = "POST";
public final static String HTTP_METHOD_GET = "GET";
public static final String SEND_MSG_ERROR = "send_msg_error";
private final static int HTTP_CONNECT_TIMEOUT = 10000;// 连接超时时间,10s
private final static int HTTP_READ_TIMEOUT = 10000;// 读消息超时时间,10s
public String mHttpMethod;// 请求方式,Post or Get
public String mSecretKey;// 安全key
/**
* 构造函数
*
* @param http_mehtod
* 请求方式
* @param secret_key
* 安全key
* @param api_key
* 应用key
*/
public BaiduPush(String http_mehtod, String secret_key, String api_key) {
mHttpMethod = http_mehtod;
mSecretKey = secret_key;
RestApi.mApiKey = api_key;
}
/**
* url编码方式
*
* @param str
* 指定编码方式,未指定默认为utf-8
* @return
* @throws UnsupportedEncodingException
*/
private String urlencode(String str) throws UnsupportedEncodingException {
String rc = URLEncoder.encode(str, "utf-8");
return rc.replace("*", "%2A");
}
/**
* 将字符串转换称json格式
*
* @param str
* @return
*/
public String jsonencode(String str) {
String rc = str.replace("\\", "\\\\");
rc = rc.replace("\"", "\\\"");
rc = rc.replace("\'", "\\\'");
return rc;
}
/**
* 执行Post请求前数据处理,加密之类
*
* @param data
* 请求的数据
* @return
*/
public String PostHttpRequest(RestApi data) {
StringBuilder sb = new StringBuilder();
//获得ChannelID
String channel = data.remove(RestApi._CHANNEL_ID);
if (channel == null)
channel = "channel";
try {
data.put(RestApi._TIMESTAMP,
Long.toString(System.currentTimeMillis() / 1000));
//删除签名?? why
data.remove(RestApi._SIGN);
sb.append(mHttpMethod);
sb.append(mUrl);
sb.append(channel);
//构造请求
for (Map.Entry<String, String> i : data.entrySet()) {
sb.append(i.getKey());
sb.append('=');
sb.append(i.getValue());
}
//添加密钥
sb.append(mSecretKey);
// System.out.println( "PRE: " + sb.toString() );
// System.out.println( "UEC: " + URLEncoder.encode(sb.toString(),
// "utf-8") );
//获得md5加密实例
MessageDigest md = MessageDigest.getInstance("MD5");
md.reset();
// md.update( URLEncoder.encode(sb.toString(), "utf-8").getBytes()
// );
//md5加密
md.update(urlencode(sb.toString()).getBytes());
byte[] md5 = md.digest();
//重置string
sb.setLength(0);
for (byte b : md5)
sb.append(String.format("%02x", b & 0xff));
//将签名附加到请求中
data.put(RestApi._SIGN, sb.toString());
// System.out.println( "MD5: " + sb.toString());
//重新生成REST请求(包含签名)
sb.setLength(0);
for (Map.Entry<String, String> i : data.entrySet()) {
sb.append(i.getKey());
sb.append('=');
// sb.append(i.getValue());
// sb.append(URLEncoder.encode(i.getValue(), "utf-8"));
sb.append(urlencode(i.getValue()));
sb.append('&');
}
//去除最后一个&号
sb.setLength(sb.length() - 1);
// System.out.println( "PST: " + sb.toString() );
// System.out.println( mUrl + "?" + sb.toString() );
} catch (Exception e) {
e.printStackTrace();
L.i("PostHttpRequest Exception:" + e.getMessage());
return SEND_MSG_ERROR;//消息发送失败,返回错误,执行重发
}
StringBuilder response = new StringBuilder();
//发出请求,对某一个设备发出请求,如果channe为channelID
//的话,那儿么
HttpRequest(mUrl + channel, sb.toString(), response);
return response.toString();
}
/**
* 执行Post请求
*
* @param url
* 基础url
* @param query
* 提交的数据
* @param out
* 服务器回复的字符串
* @return
*/
private int HttpRequest(String url, String query, StringBuilder out) {
URL urlobj;
HttpURLConnection connection = null;
try {
urlobj = new URL(url);
connection = (HttpURLConnection) urlobj.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection
.setRequestProperty("Content-Length", "" + query.length());
connection.setRequestProperty("charset", "utf-8");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setConnectTimeout(HTTP_CONNECT_TIMEOUT);
connection.setReadTimeout(HTTP_READ_TIMEOUT);
// Send request
DataOutputStream wr = new DataOutputStream(
connection.getOutputStream());
wr.writeBytes(query.toString());
wr.flush();
wr.close();
// Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = rd.readLine()) != null) {
out.append(line);
out.append('\r');
}
rd.close();
} catch (Exception e) {
e.printStackTrace();
L.i("HttpRequest Exception:" + e.getMessage());
out.append(SEND_MSG_ERROR);//消息发送失败,返回错误,执行重发
}
if (connection != null)
connection.disconnect();
return 0;
}
//
// REST APIs
//
/**
* 查询设备信息、应用、用户与百度Channel的绑定关系。
*
* @param userid
* 用户id
* @param channelid
* @return json形式的服务器恢复
*/
public String QueryBindlist(String userid, String channelid) {
RestApi ra = new RestApi(RestApi.METHOD_QUERY_BIND_LIST);
ra.put(RestApi._USER_ID, userid);
// ra.put(RestApi._DEVICE_TYPE, RestApi.DEVICE_TYPE_ANDROID);
ra.put(RestApi._CHANNEL_ID, channelid);
// ra.put(RestApi._START, "0");
// ra.put(RestApi._LIMIT, "10");
return PostHttpRequest(ra);
}
/**
* 判断设备、应用、用户与Channel的绑定关系是否存在。
*
* @param userid
* 用户id
* @param channelid
* @return
*/
public String VerifyBind(String userid, String channelid) {
RestApi ra = new RestApi(RestApi.METHOD_VERIFY_BIND);
ra.put(RestApi._USER_ID, userid);
// ra.put(RestApi._DEVICE_TYPE, RestApi.DEVICE_TYPE_ANDROID);
ra.put(RestApi._CHANNEL_ID, channelid);
return PostHttpRequest(ra);
}
/**
* 给指定用户设置标签
*
* @param tag
* @param userid
* @return
*/
public String SetTag(String tag, String userid) {
RestApi ra = new RestApi(RestApi.METHOD_SET_TAG);
ra.put(RestApi._USER_ID, userid);
ra.put(RestApi._TAG, tag);
return PostHttpRequest(ra);
}
/**
* 查询应用的所有标签
*
* @return
*/
public String FetchTag() {
RestApi ra = new RestApi(RestApi.METHOD_FETCH_TAG);
// ra.put(RestApi._NAME, "0");
// ra.put(RestApi._START, "0");
// ra.put(RestApi._LIMIT, "10");
return PostHttpRequest(ra);
}
/**
* 删除指定用户的指定标签
*
* @param tag
* @param userid
* @return
*/
public String DeleteTag(String tag, String userid) {
RestApi ra = new RestApi(RestApi.METHOD_DELETE_TAG);
ra.put(RestApi._USER_ID, userid);
ra.put(RestApi._TAG, tag);
return PostHttpRequest(ra);
}
/**
* 查询指定用户的标签
*
* @param userid
* @return
*/
public String QueryUserTag(String userid) {
RestApi ra = new RestApi(RestApi.METHOD_QUERY_USER_TAG);
ra.put(RestApi._USER_ID, userid);
return PostHttpRequest(ra);
}
/**
* 根据channel_id查询设备类型: 1:浏览器设备; 2:pc设备; 3:Andriod设备; 4:iOS设备; 5:wp设备;
*
* @param channelid
* @return
*/
public String QueryDeviceType(String channelid) {
RestApi ra = new RestApi(RestApi.METHOD_QUERY_DEVICE_TYPE);
ra.put(RestApi._CHANNEL_ID, channelid);
return PostHttpRequest(ra);
}
// Message Push
private final static String MSGKEY = "msgkey";
/**
* 给指定用户推送消息
*
* @param message
* @param userid
* @return
*/
public String PushMessage(String message, String userid) {
RestApi ra = new RestApi(RestApi.METHOD_PUSH_MESSAGE);
ra.put(RestApi._MESSAGE_TYPE, RestApi.MESSAGE_TYPE_MESSAGE);
ra.put(RestApi._MESSAGES, message);
ra.put(RestApi._MESSAGE_KEYS, MSGKEY);
// ra.put(RestApi._MESSAGE_EXPIRES, "86400");
// ra.put(RestApi._CHANNEL_ID, "");
ra.put(RestApi._PUSH_TYPE, RestApi.PUSH_TYPE_USER);
// ra.put(RestApi._DEVICE_TYPE, RestApi.DEVICE_TYPE_ANDROID);
ra.put(RestApi._USER_ID, userid);
return PostHttpRequest(ra);
}
/**
* 给指定标签用户推送消息
*
* @param message
* @param tag
* @return
*/
public String PushTagMessage(String message, String tag) {
RestApi ra = new RestApi(RestApi.METHOD_PUSH_MESSAGE);
ra.put(RestApi._MESSAGE_TYPE, RestApi.MESSAGE_TYPE_MESSAGE);
ra.put(RestApi._MESSAGES, message);
ra.put(RestApi._MESSAGE_KEYS, MSGKEY);
// ra.put(RestApi._MESSAGE_EXPIRES, "86400");
ra.put(RestApi._PUSH_TYPE, RestApi.PUSH_TYPE_TAG);
// ra.put(RestApi._DEVICE_TYPE, RestApi.DEVICE_TYPE_ANDROID);
ra.put(RestApi._TAG, tag);
return PostHttpRequest(ra);
}
/**
* 给所有用户推送消息
*
* @param message
* @return
*/
public String PushMessage(String message) {
RestApi ra = new RestApi(RestApi.METHOD_PUSH_MESSAGE);
ra.put(RestApi._MESSAGE_TYPE, RestApi.MESSAGE_TYPE_MESSAGE);
ra.put(RestApi._MESSAGES, message);
ra.put(RestApi._MESSAGE_KEYS, MSGKEY);
// ra.put(RestApi._MESSAGE_EXPIRES, "86400");
ra.put(RestApi._PUSH_TYPE, RestApi.PUSH_TYPE_ALL);
// ra.put(RestApi._DEVICE_TYPE, RestApi.DEVICE_TYPE_ANDROID);
return PostHttpRequest(ra);
}
/**
* 给指定用户推送通知
*
* @param title
* @param message
* @param userid
* @return
*/
public String PushNotify(String title, String message, String userid) {
RestApi ra = new RestApi(RestApi.METHOD_PUSH_MESSAGE);
ra.put(RestApi._MESSAGE_TYPE, RestApi.MESSAGE_TYPE_NOTIFY);
// notification_builder_id : default 0
// String msg =
// String.format("{'title':'%s','description':'%s','notification_basic_style':7}",
// title, jsonencode(message));
// String msg =
// String.format("{'title':'%s','description':'%s','notification_builder_id':0,'notification_basic_style':5,'open_type':2}",
// title, jsonencode(message));
// String msg =
// String.format("{'title':'%s','description':'%s','notification_builder_id':2,'notification_basic_style':7}",
// title, jsonencode(message));
String msg = String
.format("{'title':'%s','description':'%s','notification_builder_id':0,'notification_basic_style':7,'open_type':2,'custom_content':{'test':'test'}}",
title, jsonencode(message));
// String msg =
// String.format("{\"title\":\"%s\",\"description\":\"%s\",\"notification_basic_style\":\"7\"}",
// title, jsonencode(message));
// String msg =
// String.format("{\"title\":\"%s\",\"description\":\"%s\",\"notification_builder_id\":0,\"notification_basic_style\":1,\"open_type\":2}",
// title, jsonencode(message));
System.out.println(msg);
ra.put(RestApi._MESSAGES, msg);
ra.put(RestApi._MESSAGE_KEYS, MSGKEY);
ra.put(RestApi._PUSH_TYPE, RestApi.PUSH_TYPE_USER);
// ra.put(RestApi._PUSH_TYPE, RestApi.PUSH_TYPE_ALL);
ra.put(RestApi._USER_ID, userid);
return PostHttpRequest(ra);
}
/**
* 给所有用户推送通知
*
* @param title
* @param message
* @return
*/
public String PushNotifyAll(String title, String message) {
RestApi ra = new RestApi(RestApi.METHOD_PUSH_MESSAGE);
ra.put(RestApi._MESSAGE_TYPE, RestApi.MESSAGE_TYPE_NOTIFY);
String msg = String
.format("{'title':'%s','description':'%s','notification_builder_id':0,'notification_basic_style':7,'open_type':2,'custom_content':{'test':'test'}}",
title, jsonencode(message));
System.out.println(msg);
ra.put(RestApi._MESSAGES, msg);
ra.put(RestApi._MESSAGE_KEYS, MSGKEY);
ra.put(RestApi._PUSH_TYPE, RestApi.PUSH_TYPE_ALL);
return PostHttpRequest(ra);
}
/**
* 查询指定用户离线消息。
*
* @param userid
* @return
*/
public String FetchMessage(String userid) {
RestApi ra = new RestApi(RestApi.METHOD_FETCH_MESSAGE);
ra.put(RestApi._USER_ID, userid);
// ra.put(RestApi._START, "0");
// ra.put(RestApi._LIMIT, "10");
return PostHttpRequest(ra);
}
/**
* 查询指定用户的离线消息数
*
* @param userid
* @return
*/
public String FetchMessageCount(String userid) {
RestApi ra = new RestApi(RestApi.METHOD_FETCH_MSG_COUNT);
ra.put(RestApi._USER_ID, userid);
return PostHttpRequest(ra);
}
/**
* 删除离线消息
*
* @param userid
* @param msgids
* @return
*/
public String DeleteMessage(String userid, String msgids) {
RestApi ra = new RestApi(RestApi.METHOD_DELETE_MESSAGE);
ra.put(RestApi._USER_ID, userid);
ra.put(RestApi._MESSAGE_IDS, msgids);
return PostHttpRequest(ra);
}
}