無論是移動、聯通還是電信,都至少提供了兩種類型的的APN:WAP方式和NET方式。其中NET方式跟WIFI方式一樣,無需任何設置,可自由訪問所有類型網站,而WAP方式,需要手機先設置代理服務器和端口號等信息,並且只能訪問HTTP協議類型的網站。
1) 移動的WAP名稱是CMWAP,NET名稱是CMNET;
2) 聯通的WAP名稱是UNIWAP,NET名稱是UNINET;聯通3G的WAP名稱是3GWAP,NET名稱是3GNET;
3) 電信的WAP名稱是CTWAP,NET名稱是CTNET;
其中,移動和聯通的WAP代理服務器都是10.0.0.172,端口號是80;而電信的WAP代理服務器是10.0.0.200,端口號是80。
Android系統中,對於APN網絡的API是隱藏的,因此獲取手機的APN設置,需要通過ContentProvider來進行數據庫查詢,查詢的URI地址是:
取得全部的APN列表:content://telephony/carriers;
取得當前設置的APN:content://telephony/carriers/preferapn;
取得current=1的APN:content://telephony/carriers/current;
下面我們的代碼就是獲取當前首選的APN設置,並繼承HttpClient,實現我們自己的代理HttpClient類。首先來看下APN的管理類的實現,這個類的主要功能是獲得APN的代理服務器和端口號,查詢用的URI如下:
由這個URI使用ContentResolver獲得游標對象,之後就是查詢操作了,分別查處當前手機所設置的APN、Proxy和Port,而如果手機的Proxy沒有設置,則需要根據APN來決定當前應該連接的代理服務器地址和端口號,詳細代碼如下所示:
通過APNManager類獲取到當前手機的WAP設置的代理和端口之後,就可以構造我們自己的代理HttpClient了,這個類定義為ProxyHttpClient,在該類的構造函數中,首先獲得APNManager的實例,然後獲取代理服務器proxy和端口值port,通過這兩個參數構造HttpHost實例,並將host實例設置為ConnRouteParams.DEFAULT_PROXY的值,詳細代碼截圖如下所示:
APNManager類完整定義如下:
- package com.hust.iprai;
-
- import android.content.ContentResolver;
- import android.content.Context;
- import android.database.Cursor;
- import android.net.ConnectivityManager;
- import android.net.NetworkInfo;
- import android.net.Uri;
-
- public class APNManager {
-
- public static final Uri PREFERRED_APN_URI;
-
- private String mApn; // 接入點名稱
-
- private String mPort; // 端口號
-
- private String mProxy; // 代理服務器
-
- private boolean mUseWap; // 是否正在使用WAP
-
- static {
- PREFERRED_APN_URI = Uri.parse("content://telephony/carriers/preferapn"); // 取得當前設置的APN
- }
-
- public APNManager(Context context) {
- checkNetworkType(context);
- }
-
- /**
- * 獲得當前設置的APN相關參數
- * @param context
- */
- private void checkApn(Context context) {
- ContentResolver contentResolver = context.getContentResolver();
- Uri uri = PREFERRED_APN_URI;
- String[] apnInfo = new String[3];
- apnInfo[0] = "apn";
- apnInfo[1] = "proxy";
- apnInfo[2] = "port";
-
- Cursor cursor = contentResolver.query(uri, apnInfo, null, null, null);
- if (cursor != null) {
- while (cursor.moveToFirst()) {
- this.mApn = cursor.getString(cursor.getColumnIndex("apn"));
- this.mProxy = cursor.getString(cursor.getColumnIndex("proxy"));
- this.mPort = cursor.getString(cursor.getColumnIndex("port"));
-
- // 代理為空
- if ((this.mProxy == null) || (this.mProxy.length() <= 0)) {
- String apn = this.mApn.toUpperCase();
-
- // 中國移動WAP設置:APN:CMWAP;代理:10.0.0.172;端口:80
- // 中國聯通WAP設置:APN:UNIWAP;代理:10.0.0.172;端口:80
- // 中國聯通WAP設置(3G):APN:3GWAP;代理:10.0.0.172;端口:80
- if ((apn.equals("CMWAP")) || (apn.equals("UNIWAP")) || (apn.equals("3GWAP"))) {
- this.mUseWap = true;
- this.mProxy = "10.0.0.172";
- this.mPort = "80";
- break;
- }
-
- // 中國電信WAP設置:APN(或者接入點名稱):CTWAP;代理:10.0.0.200;端口:80
- if (apn.equals("CTWAP")) {
- this.mUseWap = true;
- this.mProxy = "10.0.0.200";
- this.mPort = "80";
- break;
- }
-
- }
- this.mPort = "80";
- this.mUseWap = true;
- break;
- }
-
- }
-
- this.mUseWap = false;
- cursor.close();
- }
-
- /**
- * 檢測當前使用的網絡類型是WIFI還是WAP
- * @param context
- */
- private void checkNetworkType(Context context) {
- NetworkInfo networkInfo = ((ConnectivityManager) context
- .getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
- if (networkInfo != null) {
- if (!"wifi".equals(networkInfo.getTypeName().toLowerCase())) {
- checkApn(context);
- return;
- }
- this.mUseWap = false;
- }
- }
-
- /**
- * 判斷當前網絡連接狀態
- * @param context
- * @return
- */
- public static boolean isNetworkConnected(Context context) {
- NetworkInfo networkInfo = ((ConnectivityManager) context
- .getApplicationContext().getSystemService("connectivity"))
- .getActiveNetworkInfo();
- if (networkInfo != null) {
- return networkInfo.isConnectedOrConnecting();
- }
- return false;
- }
-
- public String getApn() {
- return this.mApn;
- }
-
- public String getProxy() {
- return this.mProxy;
- }
-
- public String getProxyPort() {
- return this.mPort;
- }
-
- public boolean isWapNetwork() {
- return this.mUseWap;
- }
- }
ProxyHttpClient類完整定義如下:
- package com.hust.iprai;
-
- import android.content.Context;
- import android.text.TextUtils;
- import android.util.Log;
-
- import org.apache.http.HttpHost;
- import org.apache.http.conn.params.ConnRouteParams;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.params.HttpConnectionParams;
- import org.apache.http.params.HttpParams;
- import org.apache.http.params.HttpProtocolParams;
-
- public class ProxyHttpClient extends DefaultHttpClient {
-
- private static final int HTTP_TIMEOUT_MS = 30 * 1000;
-
- private static final int BUFFER_SIZE = 1024 * 8;
-
- private static final String TAG = ProxyHttpClient.class.getSimpleName();
-
- private RuntimeException mLeakedException = new IllegalStateException("ProxyHttpClient created and never closed");
-
- private String mPort;
-
- private String mProxy;
-
- private boolean mUseWap;
-
- public ProxyHttpClient(Context context) {
- this(context, null, null);
- }
-
- public ProxyHttpClient(Context context, APNManager manager) {
- this(context, null, manager);
- }
-
- public ProxyHttpClient(Context context, String userAgent) {
- this(context, userAgent, null);
- }
-
- public ProxyHttpClient(Context context, String userAgent, APNManager manager) {
- if (manager == null) {
- manager = new APNManager(context);
- }
-
- this.mUseWap = manager.isWapNetwork();
- this.mProxy = manager.getProxy();
- this.mPort = manager.getProxyPort();
- if (this.mUseWap) {
- HttpHost host = new HttpHost(this.mProxy, Integer.valueOf(this.mPort).intValue());
- getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, host); // 設置代理
- }
- HttpConnectionParams.setConnectionTimeout(getParams(), HTTP_TIMEOUT_MS);
- HttpConnectionParams.setSoTimeout(getParams(), HTTP_TIMEOUT_MS);
- HttpConnectionParams.setSocketBufferSize(getParams(), BUFFER_SIZE);
- if (!TextUtils.isEmpty(userAgent)) {
- HttpProtocolParams.setUserAgent(getParams(), userAgent);
- }
- }
-
- public void close() {
- if (this.mLeakedException != null) {
- getConnectionManager().shutdown();
- this.mLeakedException = null;
- }
- }
-
- protected HttpParams createHttpParams() {
- HttpParams params = super.createHttpParams();
- HttpProtocolParams.setUseExpectContinue(params, false);
- return params;
- }
-
- protected void finalize() throws Throwable {
- super.finalize();
- if (this.mLeakedException != null) {
- Log.e(TAG, "Leak found", this.mLeakedException);
- }
- }
- }