我想很多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:80
CMWAP的上网网关:10.0.0.172:80
UNIWAP使用的网关与CMWAP一致
我们可以通过MCC+MNC码的方式来进行简单的判断,但是实际上这种方式并不是完全正确的方法(自己在项目上碰到了该问题,因为实际情况中我们总是需要面对多种网络的情况)。这个时候其实我们可以稍微Hack一下,虽然Android并没有提供非常好的API,不过我们可以通过一些方法绕过去这里有一篇非常不错的文章
http://www.javaeye.com/topic/565662 ,讲解得还算全面。
下面给出我自己的解决方案:
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也可以如法炮制,下面附上一段代码:
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();
}