Android開發之APN網絡切換

Android開發之APN網絡切換

本文介紹Android平臺中關於APN網絡切換的相關知識。

APN(Access Point Name),即“接入點名稱”,用來標識GPRS的業務種類,目前分爲兩大類:CMWAP(通過GPRS訪問WAP業務)、CMNET(除了WAP以外的服務目前都用CMNET,比如連接因特網等)。

APN的英文全稱是Access Point Name,中文全稱叫接入點,是您在通過手機上網時必須配置的一個參數,它決定了您的手機通過哪種接入方式來訪問網絡。

移動手機的默認上網配置有兩種:CMWAP和CMNET。一些使用移動辦公的大客戶,通常會使用專用APN,其接入點隨意定義,只要和該省運營商其他APN不衝突即可。

CMWAP也叫移動夢網,通過該接入點可接入一個比較大的移動私網,網內有大量的手機應用下載及資源訪問。因爲CMWAP不接入互聯網,只接入移動運營商的私網,所以流量費用比較低廉。

CMNET也叫GPRS連接互聯網,通常每個省的運營商會提供若干個Internet出口以供CMNET撥號用戶使用。其流量費用較CMWAP要高一些。

目前國內銷售的手機,如果是非智能機,通常已配置好CMWAP連接,智能機通常會配置CMWAP和CMNET連接。如需手動添加這些配置,請參考手機說明書。

專有APN在功能上可以和Internet的VPN做類比,實際上他就是基於GPRS的VPN網絡。

專有APN常見組網方式
1,運營商部署一條專線接入到企業的網絡中,局端和企業端路由器之間採用私有IP進行連接。

2,局端互連路由器與GGSN採用GRE隧道連接。

專有APN的幾個重要特點:
1,除非運營商分配一個Internet IP地址,否則計算機沒有任何辦法通過Internet訪問該APN中的主機。

2,只有手機卡號在APN中的白名單之列,該手機纔可以接入該APN。

3,企業客戶可以建立一套RADIUS和DHCP服務器,GGSN向RADIUS服務器提供用戶主叫號碼,採用主叫號碼和用戶賬號相結合的認證方式;用戶通過認證後由DHCP服務器分配企業內部的靜態IP地址。補充:該認證方式不一定適合於每個省的運營商,這取決於該省運營商的APN管理平臺。

GPRS專網系統終端上網登錄服務器平臺的流程爲:
  
1)用戶發出GPRS登錄請求,請求中包括由運營商爲GPRS專網系統專門分配的專網APN;

  
2)根據請求中的APN,SGSN向DNS服務器發出查詢請求,找到與企業服務器平臺連接的GGSN,並將用戶請求通過GTP隧道封裝送給GGSN;

  
3)GGSN將用戶認證信息(包括手機號碼、用戶賬號、密碼等)通過專線送至Radius進行認證;

  
4)Radius認證服務器看到手機號等認證信息,確認是合法用戶發來的請求,向DHCP服務器請求分配用戶地址;

  
5)Radius認證通過後,由Radius向GGSN發送攜帶用戶地址的確認信息;

  
6)用戶得到了IP地址,就可以攜帶數據包,對GPRS專網系統信息查詢和業務處理平臺進行訪問。

下面是相關代碼:

public void openAPN(){
List list = getAPNList();
for (APN apn : list) {
ContentValues cv = new ContentValues();
cv.put("apn", APNMatchTools.matchAPN(apn.apn));
cv.put("type", APNMatchTools.matchAPN(apn.type));
getContentResolver().update(uri, cv, "_id=?", new String[]{apn.id});
}
}

public void closeAPN(){
List list = getAPNList();

for (APN apn : list) {
ContentValues cv = new ContentValues();
cv.put("apn", APNMatchTools.matchAPN(apn.apn)+"mdev");
cv.put("type", APNMatchTools.matchAPN(apn.type)+"mdev");
getContentResolver().update(uri, cv, "_id=?", new String[]{apn.id});
}
}

private List getAPNList(){
String tag = "Main.getAPNList()";
//current不爲空表示可以使用的APN
String projection[] = {"_id,apn,type,current"};
Cursor cr = this.getContentResolver().query(uri, projection, null, null, null);
List list = new ArrayList();

while(cr!=null && cr.moveToNext()){
Log.d(tag, cr.getString(cr.getColumnIndex("_id")) + " " + cr.getString(cr.getColumnIndex("apn")) + " " + cr.getString(cr.getColumnIndex("type"))+ " " + cr.getString(cr.getColumnIndex("current")));
APN a = new APN();
a.id = cr.getString(cr.getColumnIndex("_id"));
a.apn = cr.getString(cr.getColumnIndex("apn"));
a.type = cr.getString(cr.getColumnIndex("type"));
list.add(a);
}

if(cr!=null)
cr.close();
return list;
}

public static class APN{
String id;
String apn;
String type;
}


/**
* @Name: setDefaultApn
* @Description: 設置默認APN
* @param apnId
* @return boolean 返回類型
* @throws
*/
public boolean setDefaultApn(int apnId) {
boolean res = false;
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put("apn_id", apnId);

try {
resolver.update(PREFERRED_APN_URI, values, null, null);
Cursor c = resolver.query(PREFERRED_APN_URI, new String[] { "name",
"apn" }, "_id=" + apnId, null, null);
if (c != null) {
res = true;
c.close();
}
} catch (SQLException e) {

}
return res;
}


/**
* 得到當前使用的APN
* @return
*/
public ApnNode getDefaultAPN() {
String id = "";
String apn = "";
String name = "";
String type = "";
ApnNode apnNode = new ApnNode();
Cursor mCursor = context.getContentResolver().query(PREFERRED_APN_URI,
null, null, null, null);
if (mCursor == null) {
return null;
}
while (mCursor != null && mCursor.moveToNext()) {
id = mCursor.getString(mCursor.getColumnIndex("_id"));
name = mCursor.getString(mCursor.getColumnIndex("name"));
apn = mCursor.getString(mCursor.getColumnIndex("apn"))
.toLowerCase();
type = mCursor.getString(mCursor.getColumnIndex("type"))
.toLowerCase();
}
OLD_APN_ID = Integer.valueOf(id);
apnNode.setName(name);
apnNode.setApn(apn);
apnNode.setType(type);

System.out.println("old_name:" + name + "--old_apn:" + apn + "--old_type:" + type);

return apnNode;
}


/**
* @Name: SwitchApn
* @Description: 轉換APN狀態
* @param 設定文件
* @return void 返回類型
* @throws
*/
public void SwitchApn() {
switch (GetCurrentNetType()) {
case NET_3G:
if (!IsCurrentEmergencyApn()) {
EM_APN_ID = IsEmergencyApnExisted(EMERGENCY_APN);
System.out.println(EM_APN_ID);

if (EM_APN_ID == -1) {
setDefaultApn(AddEmergencyApn());
} else {
setDefaultApn(EM_APN_ID);
}
}

break;
case NET_WIFI:
break;
case NET_OTHER:
break;
default:
break;
}
}


public final class APNMatchTools {
public static class APNNet{
/*
* 中國移動cmwap
*/
public static String CMWAP = "cmwap";
/*
* 中國移動cmnet
*/
public static String CMNET = "cmnet";
//中國聯通3GWAP設置 中國聯通3G因特網設置 中國聯通WAP設置 中國聯通因特網設置
//3gwap 3gnet uniwap uninet
/*
* 3G wap 中國聯通3gwap APN
*/
public static String GWAP_3 = "3gwap";
/*
* 3G net 中國聯通3gnet APN
*/
public static String GNET_3="3gnet";
/**
* uni wap 中國聯通uni wap APN
*/
public static String UNIWAP="uniwap";
/**
* uni net 中國聯通uni net APN
*/
public static String UNINET="uninet";

}

public static String matchAPN(String currentName) {
if("".equals(currentName) || null==currentName){
return "";
}

currentName = currentName.toLowerCase();

if(currentName.startsWith(APNNet.CMNET))
return APNNet.CMNET;
else if(currentName.startsWith(APNNet.CMWAP))
return APNNet.CMWAP;
else if(currentName.startsWith(APNNet.GNET_3))
return APNNet.GNET_3;
else if(currentName.startsWith(APNNet.GWAP_3))
return APNNet.GWAP_3;
else if(currentName.startsWith(APNNet.UNINET))
return APNNet.UNINET;
else if(currentName.startsWith(APNNet.UNIWAP))
return APNNet.UNIWAP;
else if(currentName.startsWith("default"))
return "default";
else return "";
// return currentName.substring(0, currentName.length() - SUFFIX.length());
}
}


<!-- 開關APN的權限 -->
<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />


對於Android APN接入點相關的開發,有一個不錯的開源項目APNDroid的源代碼本地下載,裏面包含了一個不錯的Widget框架,大家可以通過APNDroid源碼學習到有關接入點的相關問題,可以解決GPRS,尤其是國內的CMNET、CMWAP的切換和管理。工程API Level爲3,可以運行在Android 1.5或更高的版本上。

下載地址:點擊下載http://www.2cto.com/uploadfile/2012/0330/20120330114042736.zip


完畢。^_^

摘自 HarHar
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章