我想很多 Android 程序开发者都曾碰到过这样的问题,那就是如何让自己的程序在国内如此复杂的网络环境下顺利的接上网络,给我们的用户一个更好的体验。
从网络上一些已有的数据来看,Android 手机用户群体的联网率普遍比较高,联网的方式非常多样,最多的还是使用 WIFI,当然 WIFI 速度和资费上的优势让她成为了每一个玩机者的首选网络接入方式,但是很多的时候我们的条件并不是那么的尽如人意。例如在公车或地铁上,我们这些诸多支付不起 3G 资费的人士,首选的接入方式依然是 CMWAP/CMNET, 而由于国内网络的一些个问题,选择这两个或者其他的 APN 会有一些问题,问题就是我们可能需要设置代理才可以顺利登录网络。
以下是我自己在网络上寻找解决方案的时候,收集的一些信息,记录如下:
WAP 是一中手机上网的协议。CTWAP 是中国电信的 WAP 接入名称(China Telecom WAP),CMWAP 是中国移动的 WAP 接入名称(China Mobile WAP), UNIWAP 是联通的 WAP 接入名称(china Unicom WAP), 另外 CTNET/CMNET/UNINET 同上。CTWAP 的上网网关:10.0.0.200:80CMWAP 的上网网关:10.0.0.172:80UNIWAP 使用的网关与 CMWAP 一致
我们可以通过 MCC+MNC 码的方式来进行简单的判断,但是实际上这种方式并不是完全正确的方法(自己在项目上碰到了该问题, 因为实际情况中我们总是需要面对多种网络的情况)。这个时候其实我们可以稍微 Hack 一下,虽然 Android 并没有提供非常好的 API,不过我们可以通过一些方法绕过去这里有一篇非常不错的文章 http://www.javaeye.com/topic/565662 ,讲解得还算全面。
下面给出我自己的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE); HttpClient httpClient = new DefaultHttpClient(); if(!wifiManager.isWifiEnabled()){ Uri uri = Uri.parse("content://telephony/carriers/preferapn"); //获取当前正在使用的APN接入点 Cursor mCursor = this.getContentResolver().query(uri, null, null, null, null); if(mCursor != null){ mCursor.moveToNext(); //游标移至第一条记录,当然也只有一条 String proxyStr = mCursor.getString(mCursor.getColumnIndex("proxy")); if(proxyStr != null && proxyStr.trim().length() > 0){ HttpHost proxy = new HttpHost(proxyStr, 80); httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy); } } } HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 20 * 1000); HttpConnectionParams.setSoTimeout(httpClient.getParams(), 20 * 1000); HttpGet httpGet = new HttpGet(wrapGetUrl()); try { HttpResponse response =httpClient.execute(httpGet); if(response.getStatusLine().getStatusCode() == 200){ HttpEntity entity = response.getEntity(); InputStream content = entity.getContent(); BufferedInputStream bis = new BufferedInputStream(content); StringBuilder builder = new StringBuilder(); int b; while((b=bis.read()) != -1){ builder.append((char)b); } String resultStr = builder.toString(); Log.v("result", resultStr); }catch(Exception e){ }finally{ httpClient.getConnectionManager().shutdown(); } |
该方案在打开 WIFI/CMWAP/CMNET 的情况下均单独测试成功。
同理 HttpPost 也可以如法炮制,下面附上一段代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
int version = 3; Class versionClass = VERSION.class; TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE); String manufacturer = ""; String device = ""; String networkOperatorName = tm.getNetworkOperatorName(); String IMEI = tm.getDeviceId(); try { Field field = versionClass.getField("SDK_INT"); version = (Integer) field.get(new VERSION()); Class buildClass = Build.class; Field manu_field = buildClass.getField("MANUFACTURER"); manufacturer = (String) manu_field.get(new android.os.Build()) + " "; Field deviceField = buildClass.getField("DEVICE"); device = (String) deviceField.get(new Build()); } catch (Exception e) { } HttpClient httpclient = new DefaultHttpClient(); try { if(!wifiManager.isWifiEnabled()){ Uri uri = Uri.parse("content://telephony/carriers/preferapn"); Cursor mCursor = this.getContentResolver().query(uri, null, null, null, null); if(mCursor != null){ mCursor.moveToNext(); String proxyStr = mCursor.getString(mCursor.getColumnIndex("proxy")); if(proxyStr != null && proxyStr.trim().length() > 0){ HttpHost proxy = new HttpHost(proxyStr, 80); httpclient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy); } } } HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 20 * 1000); HttpConnectionParams.setSoTimeout(httpclient.getParams(), 20 * 1000); HttpPost httppost = new HttpPost("YOUR_POST_URL"); List nameValuePairs = new ArrayList(); nameValuePairs.add(new BasicNameValuePair("os", "Android")); nameValuePairs.add(new BasicNameValuePair("os_version",String.valueOf(version))); nameValuePairs.add(new BasicNameValuePair("device", manufacturer+device)); nameValuePairs.add(new BasicNameValuePair("uuid", md5(IMEI))); nameValuePairs.add(new BasicNameValuePair("network", networkOperatorName)); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8)); HttpResponse response; response = httpclient.execute(httppost); httpclient.execute(httppost); StatusLine statusLine = response.getStatusLine(); if(statusLine.getStatusCode() == 200){ Toast.makeText(this, R.string.updatesucceed, Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this, R.string.updatefailed, Toast.LENGTH_SHORT).show(); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ updateFlag = true; httpclient.getConnectionManager().shutdown(); } |