当前位置: 代码迷 >> Android >> android APN切换cmwap兑现
  详细解决方案

android APN切换cmwap兑现

热度:63   发布时间:2016-05-01 17:29:15.0
android APN切换cmwap实现

有的中国移动的业务需要走CMWAP接入点才能够连接网络的,在做这类应用的时候,不可避免地需要判断当前APN, 切换APN,以及成功连接到网络后连接到服务器。?
首先,获取当前的APN有两种方式,一种是从当前系统的网络连接服务获取,即通过?
ConnectivityManager conManager= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);?
NetworkInfo info = conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);?
String currentAPN = info.getExtraInfo();?
CurrentAPN为‘cmnet’或者’cmwap’。。。?
还有一种是通过查询数据库的方式,因为我们设置的APN是存放在本地的xml中的?
首先申明APN_URI:?
public static final Uri CURRENT_APN_URI = Uri.parse("content://telephony/carriers/preferapn");?
public static final Uri APN_LIST_URI = Uri.parse("content://telephony/carriers");?
当前选中的APN记录在CURRENT_APN_URI中,而APN_LIST_URI里面是所以的APN列表。通过以下方法获取到选中的apn名字,?
public static String getCurrentAPNFromSetting(ContentResolver resolver) {?
??????? Cursor cursor = null;?
??????? try {?
??????????? cursor = resolver.query(CURRENT_APN_URI, null, null, null, null);?
??????????? String curApnId = null;?
??????????? if (cursor != null && cursor.moveToFirst()) {?
??????????????? curApnId = cursor.getString(cursor.getColumnIndex("apn_id"));?
??????????????? String apnName1 = cursor.getString(cursor.getColumnIndex("apn"));?
??????????? }?
??????????? cursor.close();?
??????????? //find apn name from apn list?
??????????? if (curApnId != null) {?
??????????????? cursor = resolver.query(APN_LIST_URI, null, " _id = ?", new String[]{curApnId}, null);?
??????????????? if (cursor != null && cursor.moveToFirst()) {?
??????????????????? String apnName = cursor.getString(cursor.getColumnIndex("apn"));?
??????????????????? return apnName;?
??????????????? }?
??????????? }?
????????????
??????? } catch (SQLException e) {?
??????????? Debug.error(e.getMessage());?
??????? } finally {?
??????????? if (cursor != null) {?
??????????????? cursor.close();?
??????????? }?
??????? }?
????????
??????? return null;?
}?
获取到APN之后,需要判断是否是cmwap, 如果不是需要更改当前APN为cmwap. 可以通过改数据库的方式:?
public static int updateCurrentAPN(ContentResolver resolver, String newAPN) {?
??????? Cursor cursor = null;?
??????? try {?
??????????? //get new apn id from list?
??????????? cursor = resolver.query(APN_LIST_URI, null, " apn = ? and current = 1", new String[]{newAPN.toLowerCase()}, null);?
??????????? String apnId = null;?
??????????? if (cursor != null && cursor.moveToFirst()) {?
??????????????? apnId = cursor.getString(cursor.getColumnIndex("_id"));?
??????????? }?
??????????? cursor.close();?
????????????
??????????? //set new apn id as chosen one?
??????????? if (apnId != null) {?
??????????????? ContentValues values = new ContentValues();?
??????????????? values.put("apn_id", apnId);?
??????????????? resolver.update(CURRENT_APN_URI, values, null, null);?
??????????? } else {?
??????????????? //apn id not found, return 0.?
??????????????? return 0;?
??????????? }?
??????? } catch (SQLException e) {?
??????????? Debug.error(e.getMessage());?
??????? } finally {?
??????????? if (cursor != null) {?
??????????????? cursor.close();?
??????????? }?
??????? }?
????????
??????? //update success?
??????? return 1;?
}?
在更改数据库之后,网络并不是立刻就能连接上的,我们需要加一个网络连接的消息监听器,发现切换成cmwap之后才开始连接服务器。NetworkChangeReceiver如下:?
/*?
???? * receiver for observing network connection change?
???? */?
??? public class NetworkChangeReceiver extends BroadcastReceiver {?
??????? public void onReceive(Context context, Intent intent) {?
??????????? if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {?
??????????????? NetworkInfo info = conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);?
??????????????? String apn = info.getExtraInfo();?
??????????????? if ("cmwap".equals(apn)) {?
??????????????????? /*?
???????????????????? * apn change message is sent out more than once during a second, but it?
???????????????????? * only happens once practically.?
???????????????????? */?
??????????????????? if (mNChangeReceiver != null) {?
??????????????????????? updateDcdContent(mManRequest);?
??????????????????????? HwDcdCmService.this.unregisterReceiver(mNChangeReceiver);?
??????????????????????? mNChangeReceiver = null;?
??????????????????? }?
??????????????? }?
??????????? }?
??????? }?
??? }?
切换apn总入口如下,包括了检测当前apn, 切换,注册网络监听器:?
/*?
???? * change current network connection to cmwap if it's not.?
???? */?
??? public int forceCMWapConnection() {?
????????
??????? NetworkInfo info = conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);?
??????? oldAPN = info.getExtraInfo();?
????????
??????? //if current apn is not cmwap, we have to switch to cmwap.?
??????? if (!"cmwap".equals(oldAPN)) {?
??????????? mNChangeReceiver = new NetworkChangeReceiver();?
??????????? //register receiver for wap network connection.?
??????????? IntentFilter upIntentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);?
??????????? registerReceiver(mNChangeReceiver, upIntentFilter);??
??????????? MyUtil.updateCurrentAPN(getContentResolver(), "cmwap");?
??????????? return 1;?
??????? }?
??????? return 0;?
??? }?
顺便值得一提的是,使用cmwap来连接网络的时候,仅仅切换接入点还不够,需要在请求头上加上http-route.default-proxy: 10.0.172:80. 代码如下:?
HttpParams baseParams = new BasicHttpParams();?
??????? baseParams.setParameter("http.route.default-proxy",?
??????????????? new HttpHost(“10.0.0.172”, 80));?
??????? HttpConnectionParams.setConnectionTimeout(baseParams, 30 * 1000);?
??????? HttpConnectionParams.setSoTimeout(baseParams, 45 * 1000);?
??????? // establish HttpClient?
??????? DefaultHttpClient client = new DefaultHttpClient(baseParams);?

备注:笔者发现ConnectionManager提供了一个conManager.startUsingNetworkFeature(type, value),第一个设置为ConnectivityManager.TYPE_MOBILE, 第二个为”mms”的时候,也可以进行网络的切换,不涉及到setting里面的APN值的改变。第二个参数为APN接入点中的APN类型。但是这需要framework层的支持。中移动的Ophone sdk中可以使用这种方式来切换到cmwap或internet. 但是原版的android sdk中貌似不行。

  相关解决方案