NO IMAGE

無論是移動、聯通還是電信,都至少提供了兩種型別的的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類完整定義如下:

 

 
  1. package com.hust.iprai;

  2.  
  3. import android.content.ContentResolver;

  4. import android.content.Context;

  5. import android.database.Cursor;

  6. import android.net.ConnectivityManager;

  7. import android.net.NetworkInfo;

  8. import android.net.Uri;

  9.  
  10. public class APNManager {

  11.  
  12. public static final Uri PREFERRED_APN_URI;

  13.  
  14. private String mApn; // 接入點名稱

  15.  
  16. private String mPort; // 埠號

  17.  
  18. private String mProxy; // 代理伺服器

  19.  
  20. private boolean mUseWap; // 是否正在使用WAP

  21.  
  22. static {

  23. PREFERRED_APN_URI = Uri.parse("content://telephony/carriers/preferapn"); // 取得當前設定的APN

  24. }

  25.  
  26. public APNManager(Context context) {

  27. checkNetworkType(context);

  28. }

  29.  
  30. /**

  31. * 獲得當前設定的APN相關引數

  32. * @param context

  33. */

  34. private void checkApn(Context context) {

  35. ContentResolver contentResolver = context.getContentResolver();

  36. Uri uri = PREFERRED_APN_URI;

  37. String[] apnInfo = new String[3];

  38. apnInfo[0] = "apn";

  39. apnInfo[1] = "proxy";

  40. apnInfo[2] = "port";

  41.  
  42. Cursor cursor = contentResolver.query(uri, apnInfo, null, null, null);

  43. if (cursor != null) {

  44. while (cursor.moveToFirst()) {

  45. this.mApn = cursor.getString(cursor.getColumnIndex("apn"));

  46. this.mProxy = cursor.getString(cursor.getColumnIndex("proxy"));

  47. this.mPort = cursor.getString(cursor.getColumnIndex("port"));

  48.  
  49. // 代理為空

  50. if ((this.mProxy == null) || (this.mProxy.length() <= 0)) {

  51. String apn = this.mApn.toUpperCase();

  52.  
  53. // 中國移動WAP設定:APN:CMWAP;代理:10.0.0.172;埠:80

  54. // 中國聯通WAP設定:APN:UNIWAP;代理:10.0.0.172;埠:80

  55. // 中國聯通WAP設定(3G):APN:3GWAP;代理:10.0.0.172;埠:80

  56. if ((apn.equals("CMWAP")) || (apn.equals("UNIWAP")) || (apn.equals("3GWAP"))) {

  57. this.mUseWap = true;

  58. this.mProxy = "10.0.0.172";

  59. this.mPort = "80";

  60. break;

  61. }

  62.  
  63. // 中國電信WAP設定:APN(或者接入點名稱):CTWAP;代理:10.0.0.200;埠:80

  64. if (apn.equals("CTWAP")) {

  65. this.mUseWap = true;

  66. this.mProxy = "10.0.0.200";

  67. this.mPort = "80";

  68. break;

  69. }

  70.  
  71. }

  72. this.mPort = "80";

  73. this.mUseWap = true;

  74. break;

  75. }

  76.  
  77. }

  78.  
  79. this.mUseWap = false;

  80. cursor.close();

  81. }

  82.  
  83. /**

  84. * 檢測當前使用的網路型別是WIFI還是WAP

  85. * @param context

  86. */

  87. private void checkNetworkType(Context context) {

  88. NetworkInfo networkInfo = ((ConnectivityManager) context

  89. .getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();

  90. if (networkInfo != null) {

  91. if (!"wifi".equals(networkInfo.getTypeName().toLowerCase())) {

  92. checkApn(context);

  93. return;

  94. }

  95. this.mUseWap = false;

  96. }

  97. }

  98.  
  99. /**

  100. * 判斷當前網路連線狀態

  101. * @param context

  102. * @return

  103. */

  104. public static boolean isNetworkConnected(Context context) {

  105. NetworkInfo networkInfo = ((ConnectivityManager) context

  106. .getApplicationContext().getSystemService("connectivity"))

  107. .getActiveNetworkInfo();

  108. if (networkInfo != null) {

  109. return networkInfo.isConnectedOrConnecting();

  110. }

  111. return false;

  112. }

  113.  
  114. public String getApn() {

  115. return this.mApn;

  116. }

  117.  
  118. public String getProxy() {

  119. return this.mProxy;

  120. }

  121.  
  122. public String getProxyPort() {

  123. return this.mPort;

  124. }

  125.  
  126. public boolean isWapNetwork() {

  127. return this.mUseWap;

  128. }

  129. }

ProxyHttpClient類完整定義如下:

 

 
  1. package com.hust.iprai;

  2.  
  3. import android.content.Context;

  4. import android.text.TextUtils;

  5. import android.util.Log;

  6.  
  7. import org.apache.http.HttpHost;

  8. import org.apache.http.conn.params.ConnRouteParams;

  9. import org.apache.http.impl.client.DefaultHttpClient;

  10. import org.apache.http.params.HttpConnectionParams;

  11. import org.apache.http.params.HttpParams;

  12. import org.apache.http.params.HttpProtocolParams;

  13.  
  14. public class ProxyHttpClient extends DefaultHttpClient {

  15.  
  16. private static final int HTTP_TIMEOUT_MS = 30 * 1000;

  17.  
  18. private static final int BUFFER_SIZE = 1024 * 8;

  19.  
  20. private static final String TAG = ProxyHttpClient.class.getSimpleName();

  21.  
  22. private RuntimeException mLeakedException = new IllegalStateException("ProxyHttpClient created and never closed");

  23.  
  24. private String mPort;

  25.  
  26. private String mProxy;

  27.  
  28. private boolean mUseWap;

  29.  
  30. public ProxyHttpClient(Context context) {

  31. this(context, null, null);

  32. }

  33.  
  34. public ProxyHttpClient(Context context, APNManager manager) {

  35. this(context, null, manager);

  36. }

  37.  
  38. public ProxyHttpClient(Context context, String userAgent) {

  39. this(context, userAgent, null);

  40. }

  41.  
  42. public ProxyHttpClient(Context context, String userAgent, APNManager manager) {

  43. if (manager == null) {

  44. manager = new APNManager(context);

  45. }

  46.  
  47. this.mUseWap = manager.isWapNetwork();

  48. this.mProxy = manager.getProxy();

  49. this.mPort = manager.getProxyPort();

  50. if (this.mUseWap) {

  51. HttpHost host = new HttpHost(this.mProxy, Integer.valueOf(this.mPort).intValue());

  52. getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, host); // 設定代理

  53. }

  54. HttpConnectionParams.setConnectionTimeout(getParams(), HTTP_TIMEOUT_MS);

  55. HttpConnectionParams.setSoTimeout(getParams(), HTTP_TIMEOUT_MS);

  56. HttpConnectionParams.setSocketBufferSize(getParams(), BUFFER_SIZE);

  57. if (!TextUtils.isEmpty(userAgent)) {

  58. HttpProtocolParams.setUserAgent(getParams(), userAgent);

  59. }

  60. }

  61.  
  62. public void close() {

  63. if (this.mLeakedException != null) {

  64. getConnectionManager().shutdown();

  65. this.mLeakedException = null;

  66. }

  67. }

  68.  
  69. protected HttpParams createHttpParams() {

  70. HttpParams params = super.createHttpParams();

  71. HttpProtocolParams.setUseExpectContinue(params, false);

  72. return params;

  73. }

  74.  
  75. protected void finalize() throws Throwable {

  76. super.finalize();

  77. if (this.mLeakedException != null) {

  78. Log.e(TAG, "Leak found", this.mLeakedException);

  79. }

  80. }

  81. }

如有什麼建議和疑問,歡迎留言討論。

歡迎大家加群技術交流:367685933