[转载]Android 网络连接工具类封装,支持wifi以及3G网络

[转载]Android 网络连接工具类封装,支持wifi以及3G网络 | 麦洛工作室.

市场上几乎每款APP都具有网络连接的功能。而对于开发项目来说,连接网络也是经常会用到的。现在麦洛将网络连接的代码封装成工具类,
这些代码在写与服务器交互的应用时,是非常有用的。开发的同学可以直接拿来使用。而对于麦洛自己也是一个知识积累的过程,何乐而不为呢?

在写网络连接代码之前,先了解一下HTTP协议。HTTP协议概念不用多解释了,无非就是基于TCP协议的一个应用协议。客户端对服务端发送请求,
服务端对客户端的请求作出响应。
Android中对网络连接的支持是非常优秀的。除了java.net.*包和apache包中的API,Android本身也对网络连接进行了封装,体现在android.net.*包中。
所以在Android中实现网络连接是非常容易的。

本文的实现涉及到三个类,Utility.java,RequestParameters.java,RequestException.java。Utility类就是封装网络连接的最主要接口,而RequestParameters封装了请求
数据,而RequestException是封装了请求error时的数据。
其实,这几个类是麦洛在写新浪微博时,从新浪微博中抽取出来的。麦洛觉得好的东西应该不断积累,然后在实际项目中熟悉和运用,最后形成自己独特的知识。
而现在就是积累的第一步。

首先看Utility类的实现,这个类的封装其实也不难,看看新浪微博中的实现,学习一下吧

/**
* Utility class for http request.
*
*/

public class Utility {

private static RequestParameters mRequestHeader = new RequestParameters();

public static final String BOUNDARY = "7cd4a6d158c";
public static final String MP_BOUNDARY = "--" + BOUNDARY;
public static final String END_MP_BOUNDARY = "--" + BOUNDARY + "--";
public static final String MULTIPART_FORM_DATA = "multipart/form-data";

public static final String HTTPMETHOD_POST = "POST";
public static final String HTTPMETHOD_GET = "GET";
public static final String HTTPMETHOD_DELETE = "DELETE";

private static final int SET_CONNECTION_TIMEOUT = 50000;
private static final int SET_SOCKET_TIMEOUT = 200000;

// 设置http头,如果authParam不为空,则表示当前有token认证信息需要加入到头中
public static void setHeader(String httpMethod, HttpUriRequest request,
RequestParameters authParam, String url) throws RequestException {
if (!isBundleEmpty(mRequestHeader)) {
for (int loc = 0; loc < mRequestHeader.size(); loc++) {
String key = mRequestHeader.getKey(loc);
request.setHeader(key, mRequestHeader.getValue(key));
}
}
if (!isBundleEmpty(authParam)) {
String authHeader = "";
if (authHeader != null) {
request.setHeader("Authorization", authHeader);
}
}
request.setHeader("User-Agent", System.getProperties().getProperty("http.agent")
+ " WeiboAndroidSDK");
}

public static boolean isBundleEmpty(RequestParameters bundle) {
if (bundle == null || bundle.size() == 0) {
return true;
}
return false;
}

// 填充request bundle
public static void setRequestHeader(String key, String value) {
// mRequestHeader.clear();
mRequestHeader.add(key, value);
}

public static void setRequestHeader(RequestParameters params) {
mRequestHeader.addAll(params);
}

public static void clearRequestHeader() {
mRequestHeader.clear();

}

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();
}

public static String encodeUrl(RequestParameters parameters) {
if (parameters == null) {
return "";
}

StringBuilder sb = new StringBuilder();
boolean first = true;
for (int loc = 0; loc < parameters.size(); loc++) {
if (first)
first = false;
else
sb.append("&");
sb.append(URLEncoder.encode(parameters.getKey(loc)) + "="
+ URLEncoder.encode(parameters.getValue(loc)));
}
return sb.toString();
}

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("=");
params.putString(URLDecoder.decode(v[0]), URLDecoder.decode(v[1]));
}
}
return params;
}

/**
* Parse a URL query and fragment parameters into a key-value bundle.
*
* @param url
* the URL to parse
* @return a dictionary bundle of keys and values
*/
public static Bundle parseUrl(String url) {
// hack to prevent MalformedURLException
url = url.replace("weiboconnect", "http");
try {
URL u = new URL(url);
Bundle b = decodeUrl(u.getQuery());
b.putAll(decodeUrl(u.getRef()));
return b;
} catch (MalformedURLException e) {
return new Bundle();
}
}

/**
* Construct a url encoded entity by parameters .
*
* @param bundle
* :parameters key pairs
* @return UrlEncodedFormEntity: encoed entity
*/
public static UrlEncodedFormEntity getPostParamters(Bundle bundle) throws RequestException {
if (bundle == null || bundle.isEmpty()) {
return null;
}
try {
List form = new ArrayList();
for (String key : bundle.keySet()) {
form.add(new BasicNameValuePair(key, bundle.getString(key)));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(form, "UTF-8");
return entity;
} catch (UnsupportedEncodingException e) {
throw new RequestException(e);
}
}

/**
* Implement a weibo http request and return results .
*
* @param context
* : context of activity
* @param url
* : request url of open api
* @param method
* : HTTP METHOD.GET, POST, DELETE
* @param params
* : Http params , query or postparameters
* @return UrlEncodedFormEntity: encoed entity
*/

public static String openUrl(Context context, String url, String method,
RequestParameters params) throws RequestException {
String rlt = "";
String file = "";
if(params!=null){
for (int loc = 0; loc < params.size(); loc++) { String key = params.getKey(loc); if (key.equals("pic")) { file = params.getValue(key); params.remove(key); } } } if (TextUtils.isEmpty(file)) { rlt = openUrl(context, url, method, params, null); } else { rlt = openUrl(context, url, method, params, file); } return rlt; } public static String openUrl(Context context, String url, String method, RequestParameters params, String file) throws RequestException { String result = ""; try { HttpClient client = getNewHttpClient(context); HttpUriRequest request = null; ByteArrayOutputStream bos = null; if (method.equals("GET")) { url = url + "?" + encodeUrl(params); HttpGet get = new HttpGet(url); request = get; } else if (method.equals("POST")) { HttpPost post = new HttpPost(url); byte[] data = null; bos = new ByteArrayOutputStream(1024 * 50); if (!TextUtils.isEmpty(file)) { Utility.paramToUpload(bos, params); post.setHeader("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY); Bitmap bf = BitmapFactory.decodeFile(file); Utility.imageContentToUpload(bos, bf); } else { post.setHeader("Content-Type", "application/x-www-form-urlencoded"); String postParam = encodeParameters(params); data = postParam.getBytes("UTF-8"); bos.write(data); } data = bos.toByteArray(); bos.close(); // UrlEncodedFormEntity entity = getPostParamters(params); ByteArrayEntity formEntity = new ByteArrayEntity(data); post.setEntity(formEntity); request = post; } else if (method.equals("DELETE")) { request = new HttpDelete(url); } setHeader(method, request, params, url); HttpResponse response = client.execute(request); StatusLine status = response.getStatusLine(); int statusCode = status.getStatusCode(); if (statusCode != 200) { result = read(response); throw new RequestException(String.format(status.toString()), statusCode); } // parse content stream from response result = read(response); return result; } catch (IOException e) { throw new RequestException(e); } } public static HttpClient getNewHttpClient(Context context) { try { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); SSLSocketFactory sf = new MySSLSocketFactory(trustStore); sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); HttpParams params = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(params, 10000); HttpConnectionParams.setSoTimeout(params, 10000); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register(new Scheme("https", sf, 443)); ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); // Set the default socket timeout (SO_TIMEOUT) // in // milliseconds which is the timeout for waiting for data. HttpConnectionParams.setConnectionTimeout(params, Utility.SET_CONNECTION_TIMEOUT); HttpConnectionParams.setSoTimeout(params, Utility.SET_SOCKET_TIMEOUT); HttpClient client = new DefaultHttpClient(ccm, params); WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (!wifiManager.isWifiEnabled()) { // 获取当前正在使用的APN接入点 Uri uri = Uri.parse("content://telephony/carriers/preferapn"); Cursor mCursor = context.getContentResolver().query(uri, null, null, null, null); if (mCursor != null && mCursor.moveToFirst()) { // 游标移至第一条记录,当然也只有一条 String proxyStr = mCursor.getString(mCursor.getColumnIndex("proxy")); if (proxyStr != null && proxyStr.trim().length() > 0) {
HttpHost proxy = new HttpHost(proxyStr, 80);
client.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
}
mCursor.close();
}
}
return client;
} catch (Exception e) {
return new DefaultHttpClient();
}
}

public static class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");

public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException,
KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);

TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}

public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}

public X509Certificate[] getAcceptedIssuers() {
return null;
}
};

sslContext.init(null, new TrustManager[] { tm }, null);
}

@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}

@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}

/**
* Get a HttpClient object which is setting correctly .
*
* @param context
* : context of activity
* @return HttpClient: HttpClient object
*/
public static HttpClient getHttpClient(Context context) {
BasicHttpParams httpParameters = new BasicHttpParams();
// Set the default socket timeout (SO_TIMEOUT) // in
// milliseconds which is the timeout for waiting for data.
HttpConnectionParams.setConnectionTimeout(httpParameters, Utility.SET_CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParameters, Utility.SET_SOCKET_TIMEOUT);
HttpClient client = new DefaultHttpClient(httpParameters);
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) {
// 获取当前正在使用的APN接入点
Uri uri = Uri.parse("content://telephony/carriers/preferapn");
Cursor mCursor = context.getContentResolver().query(uri, null, null, null, null);
if (mCursor != null && mCursor.moveToFirst()) {
// 游标移至第一条记录,当然也只有一条
String proxyStr = mCursor.getString(mCursor.getColumnIndex("proxy"));
if (proxyStr != null && proxyStr.trim().length() > 0) {
HttpHost proxy = new HttpHost(proxyStr, 80);
client.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
}
mCursor.close();
}
}
return client;
}

/**
* Upload image into output stream .
*
* @param out
* : output stream for uploading weibo
* @param imgpath
* : bitmap for uploading
* @return void
*/
private static void imageContentToUpload(OutputStream out, Bitmap imgpath)
throws RequestException {
StringBuilder temp = new StringBuilder();

temp.append(MP_BOUNDARY).append("\r\n");
temp.append("Content-Disposition: form-data; name=\"pic\"; filename=\"")
.append("news_image").append("\"\r\n");
String filetype = "image/png";
temp.append("Content-Type: ").append(filetype).append("\r\n\r\n");
byte[] res = temp.toString().getBytes();
BufferedInputStream bis = null;
try {
out.write(res);
imgpath.compress(CompressFormat.PNG, 75, out);
out.write("\r\n".getBytes());
out.write(("\r\n" + END_MP_BOUNDARY).getBytes());
} catch (IOException e) {
throw new RequestException(e);
} finally {
if (null != bis) {
try {
bis.close();
} catch (IOException e) {
throw new RequestException(e);
}
}
}
}

/**
* Upload weibo contents into output stream .
*
* @param baos
* : output stream for uploading weibo
* @param params
* : post parameters for uploading
* @return void
*/
private static void paramToUpload(OutputStream baos, RequestParameters params)
throws RequestException {
String key = "";
for (int loc = 0; loc < params.size(); loc++) { key = params.getKey(loc); StringBuilder temp = new StringBuilder(10); temp.setLength(0); temp.append(MP_BOUNDARY).append("\r\n"); temp.append("content-disposition: form-data; name=\"").append(key).append("\"\r\n\r\n"); temp.append(params.getValue(key)).append("\r\n"); byte[] res = temp.toString().getBytes(); try { baos.write(res); } catch (IOException e) { throw new RequestException(e); } } } /** * Read http requests result from response . * * @param response * : http response by executing httpclient * * @return String : http response content */ private static String read(HttpResponse response) throws RequestException { String result = ""; HttpEntity entity = response.getEntity(); InputStream inputStream; try { inputStream = entity.getContent(); ByteArrayOutputStream content = new ByteArrayOutputStream(); Header header = response.getFirstHeader("Content-Encoding"); if (header != null && header.getValue().toLowerCase().indexOf("gzip") > -1) {
inputStream = new GZIPInputStream(inputStream);
}

// Read response into a buffered stream
int readBytes = 0;
byte[] sBuffer = new byte[512];
while ((readBytes = inputStream.read(sBuffer)) != -1) {
content.write(sBuffer, 0, readBytes);
}
// Return result from buffered stream
result = new String(content.toByteArray());
return result;
} catch (IllegalStateException e) {
throw new RequestException(e);
} catch (IOException e) {
throw new RequestException(e);
}
}

/**
* Read http requests result from inputstream .
*
* @param inputstream
* : http inputstream from HttpConnection
*
* @return String : http response content
*/
private 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();
}

/**
* Clear current context cookies .
*
* @param context
* : current activity context.
*
* @return void
*/
public static void clearCookies(Context context) {
@SuppressWarnings("unused")
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
}

/**
* Display a simple alert dialog with the given text and title.
*
* @param context
* Android context in which the dialog should be displayed
* @param title
* Alert dialog title
* @param text
* Alert dialog message
*/
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 encodeParameters(RequestParameters httpParams) {
if (null == httpParams || Utility.isBundleEmpty(httpParams)) {
return "";
}
StringBuilder buf = new StringBuilder();
int j = 0;
for (int loc = 0; loc < httpParams.size(); loc++) {
String key = httpParams.getKey(loc);
if (j != 0) {
buf.append("&");
}
try {
buf.append(URLEncoder.encode(key, "UTF-8")).append("=")
.append(URLEncoder.encode(httpParams.getValue(key), "UTF-8"));
} catch (java.io.UnsupportedEncodingException neverHappen) {
}
j++;
}
return buf.toString();

}

/**
* Base64 encode mehtod for weibo request.Refer to weibo development
* document.
*
*/
public static char[] base64Encode(byte[] data) {
final char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
.toCharArray();
char[] out = new char[((data.length + 2) / 3) * 4];
for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
boolean quad = false;
boolean trip = false;
int val = (0xFF & (int) data[i]);
val <>= 6;
out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
val >>= 6;
out[index + 1] = alphabet[val & 0x3F];
val >>= 6;
out[index + 0] = alphabet[val & 0x3F];
}
return out;
}

}

另外两个类比较简单,可以到googlecode中下载完整的项目来查看

http://code.google.com/p/http-wrap/

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏