編輯:關於Android編程
什麼是CMNET,什麼是CMWAP?
答:CMWAP和CMNET只是中國移動為其劃分的兩個GPRS接入方式。中國移動對CMWAP作了一定的限制,主要表現在CMWAP接入時只能訪問GPRS網絡內的IP(10.*.*.*),而無法通過路由訪問Internet,我們用CMWAP浏覽Internet上的網頁就是通過WAP網關協議或它提供的HTTP代理服務實現的。 因此,只有滿足以下兩個條件的應用才能在中國移動的CMWAP接入方式下正常工作:
1.應用程序的網絡請求基於HTTP協議。
2.應用程序支持HTTP代理協議或WAP網關協議。
這也就是為什麼我們的G1無法正常用CMWAP的原因。
一句話:CMWAP是移動限制的,理論上只能上WAP網,而CMNET可以用GPRS浏覽WWW。
首先判斷是Wifi還是Mobile,如果是Mobile 有兩種,一種是cmwap,另一種是cmnet。如果是cmwap ,則需要設置代理才能連接。
ConnectivityManager conManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
//mobile 3G Data NetworkState
mobile =conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
//wifi State
wifi =conManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
ConnectivityManager conManager =(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
//mobile 3G Data NetworkState
mobile = conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
//wifi State
wifi = conManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
取得網絡鏈接
ConnectivityManager conManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
//mobile 3G Data NetworkState
mobile = conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
//wifi State
wifi = conManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
ConnectivityManager conManager= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
//mobile 3G Data NetworkState
mobile = conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
//wifi State
wifi = conManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
有時候需要實現cmwap和cmnet兩種接入方式轉換,我自己就遇到過這個問題,經過在網上及查找資料,可以通過程序修改apn表,就可以改變接入方式,但是轉換結束後,我測試了一下,大概需要6-8秒的時間,網上說是4秒,不知道他們怎樣測試的,
修改原理,android將apn保存到數據庫表,具體位置,進入android
root目錄,/data/data/com.android.providers.telephony/datebase/telephony.db/carriers 打開後就可以看到裡邊的值了,這個表中保存著所有手機支持的網絡接入方式,不同的生產商,及同一個生產商的不同手機型號,裡邊的值不一樣,不過最基本的幾個還是從在的,比如移動,聯通等。
表中有個字段為current的,這個值如果為1,說明是當前的鏈接方式,但是感覺不對,因為我自己的機子老是有三到四個值為1的,通過分析感覺更像是當前網絡可以選擇的鏈接方式,比如我用的是移動的,所有移動的聯網方式都為1.,如果有知道的可以分享一下,
我們修改apn接入方式時,其實並不是修改這個表,這也是這表為什麼不保存當前網絡連接方式的原因,而真真保存當前網絡連接方式的是在xml文件中,位置是:/com.android.providers.telephony/shared_prefs/preferred-apn.xml中,文件的內容大概是,apn_id是標簽名,values值為上面提到的表的_id。表示當前正在使用這個方式接入網絡
ok,那我們就明白要怎樣做了吧?首先從表中查找到cmwap對應的id,查詢方式一般為like '%cmwap%',找到以後將上面提到的xml文件的values值修改為查找到的就ok了,
下面是具體實現,(寫的時候有幾個字段名折騰了好久,感覺不安常規出牌)
public class UpdateAPN{
public String current;
public String name;
private Uri uriApn;
private Uri uriNowApn;
public UpdateAPN() {
this.uriApn = Uri.parse("content://telephony/carriers");
this.uriNowApn = Uri.parse("content://telephony/carriers/preferapn");
this.name = "cmnet";
this.current = "1";
}
private String getAPN(){
String str1 = null;
ContentResolver localContentResolver = AppInfo.globalAppContext.getContentResolver();
Cursor localCursor = localContentResolver.query(this.uriApn, null, "apn LIKE'%cmnet%' ", null, null);
if (localCursor == null){
return null;
}
for (localCursor.moveToFirst();!localCursor.isAfterLast(); localCursor.moveToNext()){
String apnName = localCursor.getString(localCursor.getColumnIndex("apn")).toLowerCase();
if (name.equals(apnName)){
int m =localCursor.getColumnIndex("_id");
str1 =localCursor.getString(m);
return str1;
}
}
localCursor.close();
return null;
}
private String getNowApn() {
String str1 = null;
ContentResolver localContentResolver = AppInfo.globalAppContext.getContentResolver();
Uri localUri = this.uriNowApn;
Cursor localCursor = localContentResolver.query(localUri, null, null, null, null);
while (true) {
if ((localCursor == null) ||(!localCursor.moveToNext())) {
localCursor.close();
return str1;
}
int i = localCursor.getColumnIndex("_id");
str1 = localCursor.getString(i);
Constant.debug("getNowApn --> str1=" + str1);
return str1;
}
}
public boolean updateApn(){
try {
String str1 = getAPN();//列表id cmnet
String str2 = getNowApn();//當前連接id cmwap
Constant.debug("apn---> " + str1 +" & nowApn ---> " + str2);
if (str1.equals(str2))
return false;
ContentResolver localContentResolver = AppInfo.globalAppContext.getContentResolver();
ContentValues localContentValues = new ContentValues();
String str3 = getAPN();//列表id cmnet
localContentValues.put("apn_id", str3);
Uri localUri = this.uriNowApn;
int i = localContentResolver.update(localUri,
localContentValues, null, null);
return true;
} catch (Exception localException) {
String str4 = String.valueOf(localException);
int j = Log.v("pleaseset cmwap's apn", str4);
return false;
}
}
}
下面大概測試,public class NetworkUtils{
//cmwap轉換cmnet
public static boolean cmwap2Cmnet(Contextcontext){
return new UpdateAPN().updateApn();
}
//是否是cmwap網絡連接
public static boolean isCmwap(Contextcontext) {
if (context== null) {
return false;
}
ConnectivityManager cm =(ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm == null) {
return false;
}
NetworkInfo info =cm.getActiveNetworkInfo();
if (info ==null) {
return false;
}
String extraInfo =info.getExtraInfo();
// Constant.debug("extraInfo---> " + extraInfo);
//工具類,判斷是否為空及null
if (TextUtils.isEmpty(extraInfo)|| (extraInfo.length() < 3)) {
return false;
}
if(extraInfo.toLowerCase().indexOf("wap") > 0){
return true;
}
//return extraInfo.regionMatches(true, extraInfo.length() - 3, "wap",
// 0,3);
return false;
}
/**
* 是否是cmnet鏈接網絡
* @return ture是,false否
*/
public static boolean isCmnet(Context context) {
ConnectivityManager cm =(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm == null) {
return false;
}
NetworkInfo info =cm.getActiveNetworkInfo();
if (info ==null) {
return false;
}
String extraInfo = info.getExtraInfo();
if (TextUtils.isEmpty(extraInfo)|| (extraInfo.length() < 3)) {
return false;
}
if(extraInfo.toLowerCase().indexOf("net") > 0){
return true;
}
return false;
}
}
public void cmwap2Cmnet(){
// 如果為cmpwap,啟動networkutils是我自己的網絡連接工具類,你可以定義為自己的,也可以用方法替換,
if(NetworkUtils.isCmwap(this)) {
boolean s =NetworkUtils.cmwap2Cmnet(this);
if(NetworkUtils.isNetworkAvailable(this)){
Constant.debug("切換結束,網絡可以連接");
}
longstartTime = System.currentTimeMillis();
int count =0;
while(!NetworkUtils.isCmnet(this)) {
// cmwap切換到cmnet需要大概4秒的時間,只有切換過去,才結束
if (count>= 10) {
break;
}
try{
Thread.sleep(1000);
}catch(Exception e) {
}
count++;
}
long endTime= System.currentTimeMillis();
Constant.debug("切換結束,切換花費時間為:" + ((endTime -startTime) / 1000.0) + ";切換循環次數(如果大於10可能沒有切換成功):" + count);
if(NetworkUtils.isCmnet(this)) {
Constant.debug("切換結束,網絡連接方式為cmnet");
}
}
效果圖如圖所示:注解:此方法類 是本人在網上找的。並非本人的,拿來自己修改就直接用了import me.imid.movablecheckbox.R;import and
ContentProvider為存儲和獲取數據提供統一的接口,它可以在不同的應用程序之間共享數據,本身就是適合進程間通信的。ContentProvider底層實現也是Bi
Android與服務器之間的通訊方式主要有兩種。一種是Http通訊 , 一種是Socket通訊。兩者最大的差異在於,Http連接使用的是“請求---響應方式&
時隔5個月時間,即6月14日,紅米3S作為紅米3的升級版,配備了高通骁龍430八核處理器,配備4100毫安時電池,定價699元起。紅米3S相對於紅米3的售價