手機上網分為wap和net兩種方式,使用net手機就會直接連入互連網,而使用wap則會中間多了一個代理網關,移動聯通均是10.0.0.172,連接埠80。而寫與連網有關的代碼,wap和net是不一樣的:
wap一般是這樣:
[java]
view plaincopyprint?
- URL url = new URL("http://10.0.0.172:80/index.htm");
-
- HttpURLConnection hc = (HttpURLConnection) url.openConnection();
-
- hc.setRequestProperty("X-Online-Host", "www.csdn.net");
URL url = new URL("http://10.0.0.172:80/index.htm");</p><p>HttpURLConnection hc = (HttpURLConnection) url.openConnection();</p><p>hc.setRequestProperty("X-Online-Host", "www.csdn.net");</p><p>
net一般是這樣:
[java]
view plaincopyprint?
- URL url = new URL("http://www.csdn.net/index.htm");
- HttpURLConnection hc = (HttpURLConnection) url.openConnection();
URL url = new URL("http://www.csdn.net/index.htm");<br />HttpURLConnection hc = (HttpURLConnection) url.openConnection();
因此,編寫程式時就要檢測當前的APN類型,判斷是wap還是net方式,有時候可能還要修改當前的APN,都是要解決的問題。
檢查當前APN:
擷取所有的APN,方法是通過ContentResolver,uri地址為"content://telephony/carriers"。代碼如下:
[java]
view plaincopyprint?
- Uri uri = Uri.parse("content://telephony/carriers");
- Cursor cr = getContentResolver().query(uri, null, null, null, null);
- while(cr!=null && cr.moveToNext()){
- // APN id
- String id = cr.getString(cr.getColumnIndex("_id"));
- // APN name
- String apn = cr.getString(cr.getColumnIndex("apn"));
- // do other things...
- }
Uri uri = Uri.parse("content://telephony/carriers");<br />Cursor cr = getContentResolver().query(uri, null, null, null, null);<br />while(cr!=null && cr.moveToNext()){<br /> // APN id<br /> String id = cr.getString(cr.getColumnIndex("_id"));<br /> // APN name<br /> String apn = cr.getString(cr.getColumnIndex("apn"));<br /> // do other things...<br />}
裡面的 _id 和 apn 是什嗎?這個是系統儲存apn的資料庫中的欄位。系統把所有的apn都儲存在資料庫中,資料庫在:/data/data/com.android.providers.telephony/databases/telephony.db。把你的G3連上電腦,使用adb命令:
adb pull /data/data/com.android.providers.telephony/databases/telephony.db f:/
把它弄出來看看。(同目錄下還有個mmssms.db,是儲存簡訊的資料庫)
裡面有200多個apn,只有current為1的才會在手機的apn設定裡面顯示出來。資料庫的各個欄位對應了系統設定裡面的各項。上面代碼裡面cr.getString(cr.getColumnIndex("_id"))就是取一個apn的_id了,同理可以取出其他需要的欄位。
但是我們這些還沒什麼用,我們要的是當前所用的apn。
擷取當前所使用的apn的uri地址為:"content://telephony/carriers/preferapn"。代碼同上,替換uri後再取,發現取出來的只有一個,這個就是當前所使用的apn了,就是系統設定裡面apn列表中後面那個小圓圈被選中的那個apn。
這個apn系統儲存在一個xml檔案裡,地址為:/data/data/com.android.providers.telephony/shared_prefs/preferred-apn.xml 。同樣可以取出這個檔案開啟看看,裡面內容很簡單:
<?xml version="1.0" encoding="utf-8" standalone="yes"
?>
<map>
<long
name="
apn_id" value="
218"
/>
</map>
就是說當前apn設定為資料庫中_id為218的那個apn了。 要判斷這個apn是wap還是net,最好是看proxy是不是10.0.0.172,因為apn欄位是可以任意修改的,有可能使用者把apn欄位隨便填寫。 對了,關於apn的操作相關代碼在android原始碼的packages/providers/TelephonyProvider/src/com/android/providers/telephony/TelephonyProvider.java中,有興趣可以看看。
修改當前APN:
接著就是修改它了。為什麼要修改?有可能使用者的卡只能wap上網,但是他卻設定了net。程式中檢測到net但無法連網,就把系統設定改為wap再試試。
[java]
view plaincopyprint?
- Uri uri = Uri.parse("content://telephony/carriers/preferapn");
- ContentResolver resolver = getContentResolver();
- ContentValues values = new ContentValues();
- values.put("apn_id", id);
- resolver.update(uri, values, null, null);
Uri uri = Uri.parse("content://telephony/carriers/preferapn");<br />ContentResolver resolver = getContentResolver();<br />ContentValues values = new ContentValues();<br />values.put("apn_id", id);<br />resolver.update(uri, values, null, null); 這裡面的id就是對應資料庫裡面的_id欄位了。至於如何取到net的APN,我看擷取所有的APN裡面current為1的然後自己判斷了,要不自己建立一個apn也行。 至於哪些apn的current為1,應該是系統判斷國家碼和網路碼,也就是MCC和MNC,和當前網路符合的才讓它顯示出來。(原始碼懶的看,太多了)