/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cn.bidaround.ytcore.kaixin; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Map; import javax.net.ssl.HttpsURLConnection; import org.json.JSONException; import org.json.JSONObject; import android.app.AlertDialog.Builder; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.util.Log; import android.webkit.CookieManager; import android.webkit.CookieSyncManager; /** * 封装一些实用方法的帮助器类 */ public class KaixinUtil { /** * log标签 */ public static final String LOG_TAG = "KAIXIN_ANDROID_SDK"; /** * 对于InputStream类型的上传数据,上传缓冲区大小 */ private static final int UPLOAD_BUFFER_SIZE = 1024; /** * 将用&号链接的URL参数转换成key-value形式的参数集 * * @param s * 将用&号链接的URL参数 * @return key-value形式的参数集 */ @SuppressWarnings("deprecation") public static Bundle decodeUrl(String s) { Bundle params = new Bundle(); if (s != null) { String array[] = s.split("&"); for (String parameter : array) { String v[] = parameter.split("="); if (v.length > 1) { params.putString(v[0], URLDecoder.decode(v[1])); } } } return params; } /** * 将URL中的查询串转换成key-value形式的参数集 * * @param url * 待解析的url * @return key-value形式的参数集 */ public static Bundle parseUrl(String url) { url = url.replace("#", "?"); try { URL u = new URL(url); Bundle b = decodeUrl(u.getQuery()); Bundle ref = decodeUrl(u.getRef()); if (ref != null) b.putAll(ref); return b; } catch (MalformedURLException e) { return new Bundle(); } } /** * 将key-value形式的参数集转换成用&号链接的URL查询参数形式。 * * @param parameters * key-value形式的参数集 * @return 用&号链接的URL查询参数 */ @SuppressWarnings("deprecation") public static String encodeUrl(Bundle parameters) { if (parameters == null) { return ""; } StringBuilder sb = new StringBuilder(); boolean first = true; for (String key : parameters.keySet()) { if (first) first = false; else sb.append("&"); if(parameters.getString(key)!=null){ sb.append(URLEncoder.encode(key) + "=" + URLEncoder.encode(parameters.getString(key))); } } return sb.toString(); } /** * 发送http请求 * * @param context * 应用环境 * @param requestURL * 接口地址 * @param httpMethod * GET 或 POST * @param params * key-value形式的参数集,key为参数名,value为参数值,数据类型可以是String或byte[] * @param photos * key-value形式的图像数据集, key为filename, * value为图像数据,参数类型可以是InputStream或byte[] * 如果参数类型为InputStream,会在openUrl函数中将此流关闭 * @return 服务器返回的JSON串 * @throws IOException */ public static String openUrl(Context context, String requestURL, String httpMethod, Bundle params, Map<String, Object> photos) throws IOException { OutputStream os; if (httpMethod.equals("GET")) { requestURL = requestURL + "?" + encodeUrl(params); } URL url = new URL(requestURL); HttpsURLConnection conn = (HttpsURLConnection) getConnection(context, url); conn.setRequestProperty("User-Agent", System.getProperties() .getProperty("http.agent") + " KaixinAndroidSDK"); conn.setDoInput(true); conn.setUseCaches(false); conn.setRequestProperty("Connection", "close"); conn.setRequestProperty("Charsert", "UTF-8"); if (!httpMethod.equals("GET")) { Bundle dataparams = new Bundle(); // for (String key : params.keySet()) { // if (params.getByteArray(key) != null) { // dataparams.putByteArray(key, params.getByteArray(key)); // } // } String BOUNDARY = KaixinUtil.md5(String.valueOf(System .currentTimeMillis())); // 数据分隔线 String endLine = "\r\n"; conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY); conn.connect(); os = new BufferedOutputStream(conn.getOutputStream()); os.write(("--" + BOUNDARY + endLine).getBytes()); os.write((encodePostBody(params, BOUNDARY)).getBytes()); os.write((endLine + "--" + BOUNDARY + endLine).getBytes()); if (!dataparams.isEmpty()) { for (String key : dataparams.keySet()) { os.write(("Content-Disposition: form-data; name=\"" + key + "\"" + endLine).getBytes()); os .write(("Content-Type: content/unknown" + endLine + endLine) .getBytes()); os.write(dataparams.getByteArray(key)); os.write((endLine + "--" + BOUNDARY + endLine).getBytes()); } } if (photos != null && !photos.isEmpty()) { for (String key : photos.keySet()) { Object obj = photos.get(key); if (obj instanceof InputStream) { InputStream is = (InputStream) obj; try { os .write(("Content-Disposition: form-data; name=\"pic\";filename=\"" + key + "\"" + endLine).getBytes()); os .write(("Content-Type:application/octet-stream\r\n\r\n") .getBytes()); byte[] data = new byte[UPLOAD_BUFFER_SIZE]; int nReadLength = 0; while ((nReadLength = is.read(data)) != -1) { os.write(data, 0, nReadLength); } os.write((endLine + "--" + BOUNDARY + endLine) .getBytes()); } finally { try { if (null != is) { is.close(); } } catch (Exception e) { Log.e(LOG_TAG, "Exception on closing input stream", e); } } } else if (obj instanceof byte[]) { byte[] byteArray = (byte[]) obj; os .write(("Content-Disposition: form-data; name=\"pic\";filename=\"" + key + "\"" + endLine).getBytes()); os .write(("Content-Type:application/octet-stream\r\n\r\n") .getBytes()); os.write(byteArray); os.write((endLine + "--" + BOUNDARY + endLine) .getBytes()); } else { Log.e(LOG_TAG, "无效的参数类型"); } } } os.flush(); } String response = ""; try { response = read(conn.getInputStream()); } catch (FileNotFoundException e) { response = read(conn.getErrorStream()); } return response; } /** * 封装multi-part方式上传的数据段 * * @param parameters * key-value形式的参数集 * @param boundary * 数据分割线 * @return 用于multi-part方式上传的数据 */ public static String encodePostBody(Bundle parameters, String boundary) { if (parameters == null) return ""; StringBuilder sb = new StringBuilder(); for (String key : parameters.keySet()) { // if (parameters.getByteArray(key) != null) { // continue; // } sb.append("Content-Disposition: form-data; name=\"" + key + "\"\r\n\r\n" + parameters.getString(key)); sb.append("\r\n" + "--" + boundary + "\r\n"); } return sb.toString(); } /** * 读取http请求的网络数据流 * * @param in * 网络数据流 * @return 读取的网络数据流 * @throws IOException */ public static String read(InputStream in) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000); for (String line = r.readLine(); line != null; line = r.readLine()) { sb.append(line); } in.close(); return sb.toString(); } /** * 清除cookie * * @param context */ public static void clearCookies(Context context) { @SuppressWarnings("unused") CookieSyncManager cookieSyncMngr = CookieSyncManager .createInstance(context); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.removeAllCookie(); } /** * 将服务器返回带有错误信息的JSON串,转化成KaixinError对象 * * @param response * 服务器返回带有错误信息的JSON串 * @return KaixinError对象 */ public static KaixinError parseRequestError(String response) { if (response.indexOf("error_code") < 0) return null; return parseJson(response); } private static KaixinError parseJson(String response) { try { JSONObject json = new JSONObject(response); return new KaixinError(json.getInt("error_code"), json.optString( "error", ""), json.optString("request", ""), response); } catch (JSONException e) { return null; } } /** * 显示信息提示框 */ public static void showAlert(Context context, String title, String text) { Builder alertBuilder = new Builder(context); alertBuilder.setTitle(title); alertBuilder.setMessage(text); alertBuilder.create().show(); } public static String md5(String input) { String result = input; if (input != null) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(input.getBytes()); BigInteger hash = new BigInteger(1, md.digest()); result = hash.toString(16); if ((result.length() % 2) != 0) { result = "0" + result; } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } return result; } /** * 建立Http连接,如果apn的设置中配置了代理服务器,那么建立连接时也需要做相关的处理 * * @throws IOException */ @SuppressWarnings("deprecation") public static HttpURLConnection getConnection(Context context, URL url) throws IOException { // 说明:联网时优先选择WIFI联网,如果WIFI没开或不可用,则使用移动网络 HttpsURLConnection httpsURLConn = null; // 获取当前可用网络信息 ConnectivityManager connMgr = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = connMgr.getActiveNetworkInfo(); // 如果当前是WIFI连接 if (null != netInfo && ConnectivityManager.TYPE_WIFI == netInfo.getType()) { httpsURLConn = (HttpsURLConnection) url.openConnection(); } else {// 非WIFI联网 String proxyHost = android.net.Proxy.getDefaultHost(); if (null == proxyHost) { // 直连模式 httpsURLConn = (HttpsURLConnection) url.openConnection(); } else { // 代理模式 java.net.Proxy p = new java.net.Proxy(java.net.Proxy.Type.HTTP, new InetSocketAddress(android.net.Proxy .getDefaultHost(), android.net.Proxy .getDefaultPort())); httpsURLConn = (HttpsURLConnection) url.openConnection(p); } } return httpsURLConn; } /** * 判断字符串中是否有中文字符 * * @param str * 字符串 * @return boolean */ public static boolean isContainChinese(String str) { if (str == null || str.trim().length() <= 0) { return false; } int len = str.length(); for (int i = 0; i < len; i++) { char word = str.charAt(i); if ((word >= 0x4e00) && (word <= 0x9fbb)) { return true; } } return false; } }