Android 網路請求及網路狀態判斷
文章轉載:
網址:http://blog.csdn.net/anye_anye/article/details/50569114
Android 中判斷網路連線是否可用
一、判斷網路連線是否可用
public static boolean isNetworkAvailable(Context context) { ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); if (cm == null) { } else { //如果僅僅是用來判斷網路連線 //則可以使用 cm.getActiveNetworkInfo().isAvailable(); NetworkInfo[] info = cm.getAllNetworkInfo(); if (info != null) { for (int i = 0; i < info.length; i++) { if (info[i].getState() == NetworkInfo.State.CONNECTED) { return true; } } } } return false; }
二、判斷GPS是否開啟
public static boolean isGpsEnabled(Context context) { LocationManager lm = ((LocationManager) context .getSystemService(Context.LOCATION_SERVICE)); List<String> accessibleProviders = lm.getProviders(true); return accessibleProviders != null && accessibleProviders.size() > 0; }
三、判斷WIFI是否開啟
public static boolean isWifiEnabled(Context context) { ConnectivityManager mgrConn = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); TelephonyManager mgrTel = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); return ((mgrConn.getActiveNetworkInfo() != null && mgrConn .getActiveNetworkInfo().getState() == NetworkInfo.State.CONNECTED) || mgrTel .getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS); }
四、判斷是否是3G網路
public static boolean is3rd(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkINfo = cm.getActiveNetworkInfo();
if (networkINfo != null
&& networkINfo.getType() == ConnectivityManager.TYPE_MOBILE) {
return true;
}
return false;
}
五、判斷是wifi還是3g網路,使用者的體現性在這裡了,wifi就可以建議下載或者線上播放。
public static boolean isWifi(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkINfo = cm.getActiveNetworkInfo();
if (networkINfo != null
&& networkINfo.getType() == ConnectivityManager.TYPE_WIFI) {
return true;
}
return false;
}
Android開發請求網路方式詳解
現在就簡單的介紹一下Android常用的聯網方式,包括JDK支援的HttpUrlConnection,Apache支援的HttpClient,以及開源的一些聯網框架(譬如AsyncHttpClient)的介紹。本篇部落格只講實現過程和方式,不講解原理,否則原理用文字很難以講清,其實我們知道怎麼去用,就可以解決一些基本開發需要了。
絕大多數的Android應用聯網都是基於Http協議的,也有很少是基於Socket的,我們這裡主要講解基於Http協議的聯網方式。講解例項是建立在一個模擬的登入小模組中進行,登入請求資料僅僅只有username和password兩個簡單欄位。
HttpUrlConnection
HttpUrlConnection是JDK裡提供的聯網API,我們知道Android SDK是基於Java的,所以當然優先考慮HttpUrlConnection這種最原始最基本的API,其實大多數開源的聯網框架基本上也是基於JDK的HttpUrlConnection進行的封裝罷了,掌握HttpUrlConnection需要以下幾個步驟:
1、將訪問的路徑轉換成URL。
URL url = new URL(path);
2、通過URL獲取連線。
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
3、設定請求方式。
conn.setRequestMethod(GET);
4、設定連線超時時間。
conn.setConnectTimeout(5000);
5、設定請求頭的資訊。
conn.setRequestProperty(User-Agent, Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0));
6、獲取響應碼
int code = conn.getResponseCode();
7、針對不同的響應碼,做不同的操作
7.1、請求碼200,表明請求成功,獲取返回內容的輸入流
InputStream is = conn.getInputStream();
7.2、將輸入流轉換成字串資訊
public class StreamTools {
/**
* 將輸入流轉換成字串
*
* @param is
* 從網路獲取的輸入流
* @return
*/
public static String streamToString(InputStream is) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
baos.close();
is.close();
byte[] byteArray = baos.toByteArray();
return new String(byteArray);
} catch (Exception e) {
Log.e(tag, e.toString());
return null;
}
}
}
7.3、若返回值400,則是返回網路異常,做出響應的處理。
HttpUrlConnection傳送GET請求
/**
* 通過HttpUrlConnection傳送GET請求
*
* @param username
* @param password
* @return
*/
public static String loginByGet(String username, String password) {
String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username= + username + &password= + password;
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod(GET);
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream(); // 位元組流轉換成字串
return StreamTools.streamToString(is);
} else {
return 網路訪問失敗;
}
} catch (Exception e) {
e.printStackTrace();
return 網路訪問失敗;
}
}
HttpUrlConnection傳送POST請求
/**
* 通過HttpUrlConnection傳送POST請求
*
* @param username
* @param password
* @return
*/
public static String loginByPost(String username, String password) {
String path = http://192.168.0.107:8080/WebTest/LoginServerlet;
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod(POST);
conn.setRequestProperty(Content-Type, application/x-www-form-urlencoded);
String data = username= + username + &password= + password;
conn.setRequestProperty(Content-Length, data.length() + );
// POST方式,其實就是瀏覽器把資料寫給伺服器
conn.setDoOutput(true); // 設定可輸出流
OutputStream os = conn.getOutputStream(); // 獲取輸出流
os.write(data.getBytes()); // 將資料寫給伺服器
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream();
return StreamTools.streamToString(is);
} else {
return 網路訪問失敗;
}
} catch (Exception e) {
e.printStackTrace();
return 網路訪問失敗;
}
}
HttpClient
HttpClient是開源組織Apache提供的Java請求網路框架,其最早是為了方便Java伺服器開發而誕生的,是對JDK中的HttpUrlConnection各API進行了封裝和簡化,提高了效能並且降低了呼叫API的繁瑣。
Android因此也引進了這個聯網框架,我們再不需要匯入任何jar或者類庫就可以直接使用,值得注意的是Android官方已經宣佈不建議使用HttpClient了,我們再開發的時候儘量少用吧,但是用了也無妨!
HttpClient傳送GET請求
1, 建立HttpClient物件
2,建立HttpGet物件,指定請求地址(帶引數)
3,使用HttpClient的execute(),方法執行HttpGet請求,得到HttpResponse物件
4,呼叫HttpResponse的getStatusLine().getStatusCode()方法得到響應碼
5,呼叫的HttpResponse的getEntity().getContent()得到輸入流,獲取服務端寫回的資料
/**
* 通過HttpClient傳送GET請求
*
* @param username
* @param password
* @return
*/
public static String loginByHttpClientGet(String username, String password) {
String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=
+ username + &password= + password;
HttpClient client = new DefaultHttpClient(); // 開啟網路訪問客戶端
HttpGet httpGet = new HttpGet(path); // 包裝一個GET請求
try {
HttpResponse response = client.execute(httpGet); // 客戶端執行請求
int code = response.getStatusLine().getStatusCode(); // 獲取響應碼
if (code == 200) {
InputStream is = response.getEntity().getContent(); // 獲取實體內容
String result = StreamTools.streamToString(is); // 位元組流轉字串
return result;
} else {
return 網路訪問失敗;
}
} catch (Exception e) {
e.printStackTrace();
return 網路訪問失敗;
}
}
HttpClient傳送POST請求
1,建立HttpClient物件
2,建立HttpPost物件,指定請求地址
3,建立List,用來裝載引數
4,呼叫HttpPost物件的setEntity()方法,裝入一個UrlEncodedFormEntity物件,攜帶之前封裝好的引數
5,使用HttpClient的execute()方法執行HttpPost請求,得到HttpResponse物件
6, 呼叫HttpResponse的getStatusLine().getStatusCode()方法得到響應碼
7, 呼叫的HttpResponse的getEntity().getContent()得到輸入流,獲取服務端寫回的資料
/**
* 通過HttpClient傳送POST請求
*
* @param username
* @param password
* @return
*/
public static String loginByHttpClientPOST(String username, String password) {
String path = http://192.168.0.107:8080/WebTest/LoginServerlet;
try {
HttpClient client = new DefaultHttpClient(); // 建立一個客戶端
HttpPost httpPost = new HttpPost(path); // 包裝POST請求
// 設定傳送的實體引數
List<namevaluepair> parameters = new ArrayList<namevaluepair>();
parameters.add(new BasicNameValuePair(username, username));
parameters.add(new BasicNameValuePair(password, password));
httpPost.setEntity(new UrlEncodedFormEntity(parameters, UTF-8));
HttpResponse response = client.execute(httpPost); // 執行POST請求
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream is = response.getEntity().getContent();
String result = StreamTools.streamToString(is);
return result;
} else {
return 網路訪問失敗;
}
} catch (Exception e) {
e.printStackTrace();
return 訪問網路失敗;
}
}
開源聯網框架
1、AsyncHttpClient
除了上述Android官方推薦的聯網框架以外,在開源世界裡關於聯網框架真是太多太多了,例如afinal,xutils等等,都是一些開源大牛自己封裝的聯網框架,並且在GitHub開源社群中可以下載到,其實類似的開源聯網框架基本上也是基於HttpUrlConnection的進一步封裝,大大提高了效能,同時更加簡化了使用方法,這裡先介紹AsyncHttpClient的一些使用方法。 AsyncHttpClient是一個非常優秀的聯網框架,不僅支援所有Http請求的方式,而且還支援檔案的上傳和下載,要知道用HttpUrlConnection寫一個檔案上傳和下載健全功能是很需要花費一定時間和精力的,因為請求頭實在是太多了,稍有不慎就會寫錯。但是AsyncHttpClient已經封裝好了這些“麻煩”,我們只需要下載到AsyncHttpClient的jar包或者原始碼匯入專案中,Http,上傳,下載等等,只需要幾個簡單的api即可搞定。 AsyncHttpClient的GitHub主頁:https://github.com/AsyncHttpClient/async-http-client/
AsyncHttpClient傳送GET請求
1,將下載好的原始碼拷貝到src目錄下
2,建立一個AsyncHttpClient的物件
3,呼叫該類的get方法傳送GET請求,傳入請求資源地址URL,建立AsyncHttpResponseHandler物件
4,重寫AsyncHttpResponseHandler下的兩個方法,onSuccess和onFailure方法
/**
* 通過AsyncHttpClient傳送GET請求
*/
public void loginByAsyncHttpGet() {
String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=zhangsan&password=123;
AsyncHttpClient client = new AsyncHttpClient();
client.get(path, new AsyncHttpResponseHandler() {
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2,
Throwable arg3) {
// TODO Auto-generated method stub
Log.i(TAG, 請求失敗: + new String(arg2));
}
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
// TODO Auto-generated method stub
Log.i(TAG, 請求成功: + new String(arg2));
}
});
}
AsyncHttpClient傳送POST請求
1,將下載好的原始碼拷貝到src目錄下
2,建立一個AsyncHttpClient的物件
3,建立請求引數,RequestParams物件
4,呼叫該類的post方法發POST,傳入請求資源地址URL,請求引數RequestParams,建立AsyncHttpResponseHandler物件
5,重寫AsyncHttpResponseHandler下的兩個方法,onSuccess和onFailure方法
/**
* 通過AsyncHttpClient傳送POST請求
*/
public void loginByAsyncHttpPost() {
String path = http://192.168.0.107:8080/WebTest/LoginServerlet;
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put(username, zhangsan);
params.put(password, 123);
client.post(path, params, new AsyncHttpResponseHandler() {
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2,
Throwable arg3) {
// TODO Auto-generated method stub
Log.i(TAG, 請求失敗: + new String(arg2));
}
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
// TODO Auto-generated method stub
Log.i(TAG, 請求成功: + new String(arg2));
}
});
AsyncHttpClient上傳檔案
1,將下載好的原始碼拷貝到src目錄下
2,建立一個AsyncHttpClient的物件
3,建立請求引數,RequestParams物件,請求引數僅僅包含檔案物件即可,例如:
params.put(profile_picture, new File(/sdcard/pictures/pic.jpg));
4,呼叫該類的post方法發POST,傳入請求資源地址URL,請求引數RequestParams,建立AsyncHttpResponseHandler物件
5,重寫AsyncHttpResponseHandler下的兩個方法,onSuccess和onFailure方法
2、Android Volley框架使用詳解
Volley是一個由Google官方推出的網路通訊庫,它使得Android進行網路請求時更加方便、快速、健壯,同時對網路圖片載入也提供了良好的支援。
1、獲取volley原始碼
2、使用例項
使用Volley必須在AndroidManifest.xml中新增 android.permission.INTERNET許可權,使用Volley時Google建議建立volley單例工具類
public class VolleySingleton {
private static VolleySingleton volleySingleton;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private Context mContext;
public VolleySingleton(Context context) {
this.mContext = context;
mRequestQueue = getRequestQueue();
mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache(){
private final LruCache<String,Bitmap> cache = new LruCache<String ,Bitmap>(20);
@Override
public Bitmap getBitmap(String url){
return cache.get(url);
}
@Override
public void putBitmap(String url,Bitmap bitmap){
cache.put(url,bitmap);
}
});
}
public static synchronized VolleySingleton getVolleySingleton(Context context){
if(volleySingleton == null){
volleySingleton = new VolleySingleton(context);
}
return volleySingleton;
}
public RequestQueue getRequestQueue(){
if(mRequestQueue == null){
mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req){
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
}
首先使用 Volley.newRequestQueue獲取 RequestQueue物件
RequestQueue mRequestQueue = VolleySingleton.getVolleySingleton(this.getApplicationContext()).getRequestQueue();
RequestQueue是請求佇列物件,它可以快取所有的HTTP網路請求,然後按照其內部演算法併發的傳送這些網路請求,它能夠很好的支撐高併發請求,不要每個請求都建立RequestQueue物件,建立多個RequestQueue會耗費資源
傳送StringRequest請求
StringRequest stringRequest = new StringRequest(Request.Method.GET,"https://www.baidu.com",new Listener<String>(){
@Override
public void onResponse(String s) {
//列印請求返回結果
Log.e("volley",s);
}
},new ErrorListener(){
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("volleyerror","erro2");
}
});
//將StringRequest物件新增進RequestQueue請求佇列中
VolleySingleton.getVolleySingleton(this.getApplicationContext()).addToRequestQueue(stringRequest);
到此已經完成了StringRequest請求。StringRequest提供了兩個構造方法
public StringRequest(java.lang.String url, com.android.volley.Response.Listener<java.lang.String> listener, com.android.volley.Response.ErrorListener errorListener);
public StringRequest(int method, java.lang.String url, com.android.volley.Response.Listener<java.lang.String> listener, com.android.volley.Response.ErrorListener errorListener);
引數method是HTTP的請求型別,通常有GET和POST兩種;引數url是請求地址;引數listener是伺服器響應成功的回撥,引數errorListener是伺服器響應失敗的回撥。如果想通過POST方式請求並攜帶引數,遺憾的是StringRequest並沒有提供帶引數請求,但是當傳送POST請求時,Volley會呼叫StringRequest的父類Request的getParams()方法來獲取POST引數,所以我們只要使用StringRequest匿名類重寫getParams()方法將引數傳遞進去就可以實現帶引數的StringRequest請求。
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("params1", "value1");
map.put("params2", "value2");
return map;
}
};
傳送JsonObjectRequest請求
JsonObjectRequest jr = new JsonObjectRequest(Request.Method.GET,url,null,new Response.Listener<JSONObject>(){
@Override
public void onResponse(JSONObject jsonObject) {
Log.e("volley",jsonObject.toString());
}
},new ErrorListener(){
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("volleyerror","erro");
}
});
VolleySingleton.getVolleySingleton(this.getApplicationContext()).addToRequestQueue(jr);
JsonObjectRequest的構造方法引數和StringRequest一致,不在此累贅。
使用ImageRequest載入圖片
ImageView mImageView;
String url = "http://i.imgur.com/7spzG.png";
mImageView = (ImageView) findViewById(R.id.myImage);
ImageRequest request = new ImageRequest(url,
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
mImageView.setImageBitmap(bitmap);
}
}, 0, 0, Config.RGB_565,
new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
mImageView.setImageResource(R.drawable.image_load_error);
}
});
VolleySingleton.getVolleySingleton(this.getApplicationContext()).addToRequestQueue(request);
ImageRequest的建構函式
public ImageRequest(java.lang.String url, com.android.volley.Response.Listener<android.graphics.Bitmap> listener, int maxWidth, int maxHeight, android.graphics.Bitmap.Config decodeConfig, com.android.volley.Response.ErrorListener errorListener) { /* compiled code */ }
引數url是圖片地址,引數listener是請求響應成功回撥,引數maxWidth是圖片最大寬度,引數maxHeight是圖片最大高度,如果指定的網路圖片的寬度或高度大於這裡的最大值,則會對圖片進行壓縮,指定成0的話就表示不管圖片有多大,都不會進行壓縮。引數decodeConfig是圖片的顏色屬性,其值是Bitmap.Config類的幾個常量,引數errorListener是請求響應失敗回撥
使用 ImageLoader 載入圖片
ImageLoader mImageLoader;
ImageView mImageView;
private static final String IMAGE_URL =
"http://developer.android.com/images/training/system-ui.png";
mImageView = (ImageView) findViewById(R.id.regularImageView);
mImageLoader = VolleySingleton.getVolleySingleton(this.getApplicationContext()).getImageLoader();
//IMAGE_URL是圖片網路地址
//mImageView是ImageView例項
//R.drawable.def_image預設圖片id
//R.drawable.err_image載入圖片錯誤時的圖片
mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,
R.drawable.def_image, R.drawable.err_image));
使用NetworkImageView載入圖片
XML佈局檔案
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/networkImageView"
android:layout_width="150dp"
android:layout_height="170dp"
android:layout_centerHorizontal="true" />
程式碼
ImageLoader mImageLoader;
NetworkImageView mNetworkImageView;
private static final String IMAGE_URL =
"http://developer.android.com/images/training/system-ui.png";
mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
mImageLoader = VolleySingleton.getVolleySingleton(this.getApplicationContext()).getImageLoader();
mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);
我們可以呼叫它的setDefaultImageResId()方法、setErrorImageResId()方法和setImageUrl()方法來分別設定載入中顯示的圖片,載入失敗時顯示的圖片
取消網路請求
Volley還提供了取消網路請求的方法並且可以聯動Activity的生命週期,比如在Activity的onStop()方法中呼叫cance()方法取消網路請求。
public static final String TAG = "MyTag";
StringRequest stringRequest; // Assume this exists.
RequestQueue mRequestQueue; // Assume this exists.
// Set the tag on the request.
stringRequest.setTag(TAG);
// Add the request to the RequestQueue.
mRequestQueue.add(stringRequest);
Activity的onStop()方法
@Override
protected void onStop () {
super.onStop();
if (mRequestQueue != null) {
mRequestQueue.cancelAll(TAG);
}
}