- 浏览: 363876 次
- 性别:
- 来自: 南京
-
文章分类
最新评论
-
nglxl:
点赞啊,必须点赞!!深度好文,解决了困扰我多年的疑惑。
tcp 长连接与短连接 -
cofftech:
opengl源码http://www.eyesourcecod ...
OPenGL ES 关键API小结 -
mail_j:
不是很好用,很多情况都不能处理 1、没有区分关键字的大小写2、 ...
Java解析sql语句,分析出调用到的所有表 -
a455642158:
就算监听到变成了cmwap还不行,还得监听网络连接状态Stat ...
android APN切换cmwap实现 -
xuhl1022:
看了您的android 4篇 浏览器二次开发,感触颇深,写的很 ...
Android浏览器Browser二次开发(四)浏览器中的APN切换
有的中国移动的业务需要走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中貌似不行。
这个跟具体的业务有关, 与接入点切入无关, 可忽略。
应用需要使用的网络是cmwap, 那就必须等到切换成cmwap之后才去连接, 发起http请求。 这是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中貌似不行。
评论
9 楼
a455642158
2012-12-03
就算监听到变成了cmwap还不行,还得监听网络连接状态State,不过就算state已经connected了也还是有时候连接失败……不过比不监听这个状态好一点。
8 楼
hacer9791
2011-07-31
xt800 切换不了网络
7 楼
imain
2011-07-04
楼主,mNChangeReceiver 这个变量是在什么地方定义的?起到什么作用?
forceCMWapConnection()这个函数在哪里调用?
forceCMWapConnection()这个函数在哪里调用?
6 楼
seya
2011-04-07
we_42011 写道
updateDcdContent(mManRequest);\
兄弟,这句什么意思啊?
兄弟,这句什么意思啊?
这个跟具体的业务有关, 与接入点切入无关, 可忽略。
5 楼
we_42011
2011-04-05
updateDcdContent(mManRequest);\
兄弟,这句什么意思啊?
兄弟,这句什么意思啊?
4 楼
seya
2011-03-17
sht2130 写道
if (mNChangeReceiver != null) {
updateDcdContent(mManRequest);
HwDcdCmService.this.unregisterReceiver(mNChangeReceiver);
mNChangeReceiver = null;
}
你好,上面代码在调试的时候不通,这个地方有些疑惑,监控到apn的切换之后具体需要做什么样的操作呢,劳烦楼主帮忙解释一下,谢谢
updateDcdContent(mManRequest);
HwDcdCmService.this.unregisterReceiver(mNChangeReceiver);
mNChangeReceiver = null;
}
你好,上面代码在调试的时候不通,这个地方有些疑惑,监控到apn的切换之后具体需要做什么样的操作呢,劳烦楼主帮忙解释一下,谢谢
应用需要使用的网络是cmwap, 那就必须等到切换成cmwap之后才去连接, 发起http请求。 这是apn切换之后要做的。
3 楼
sht2130
2011-03-15
if (mNChangeReceiver != null) {
updateDcdContent(mManRequest);
HwDcdCmService.this.unregisterReceiver(mNChangeReceiver);
mNChangeReceiver = null;
}
你好,上面代码在调试的时候不通,这个地方有些疑惑,监控到apn的切换之后具体需要做什么样的操作呢,劳烦楼主帮忙解释一下,谢谢
updateDcdContent(mManRequest);
HwDcdCmService.this.unregisterReceiver(mNChangeReceiver);
mNChangeReceiver = null;
}
你好,上面代码在调试的时候不通,这个地方有些疑惑,监控到apn的切换之后具体需要做什么样的操作呢,劳烦楼主帮忙解释一下,谢谢
2 楼
seya
2011-03-09
startUsingNetworkFeature
直接修改当前网络数据连接类型, 和通过设置当前APN的方式效果一样。不同的是设置里面选中的APN不会发生变化。 APN可能还是cmnet, 可是通过使用startUsingNetworkFeature(type,value), 使当前实际使用的网络切换为cmwap.
Wesley.S 写道
兄弟,知道 startUsingNetworkFeature(type,value)的意义吗??
直接修改当前网络数据连接类型, 和通过设置当前APN的方式效果一样。不同的是设置里面选中的APN不会发生变化。 APN可能还是cmnet, 可是通过使用startUsingNetworkFeature(type,value), 使当前实际使用的网络切换为cmwap.
1 楼
Wesley.S
2011-03-04
兄弟,知道 startUsingNetworkFeature(type,value)的意义吗??
发表评论
-
基于Java NIO的手机答题游戏开发
2014-03-31 17:59 1812先上个游戏截图: 豌豆荚地址: http://apps.w ... -
enable android deviceconnection under linux
2013-04-24 15:45 1020开发环境搭建完毕,Eclipse,Java,ADT都已经折腾 ... -
set CCache for building android source code
2013-04-24 15:14 1209Setting up ccache You can opti ... -
android 源码下载403 forbidden, 406 not acceptable 错误
2013-04-24 08:46 2466解决方法 1. 浏览器登录https://android.g ... -
ubuntu11.10 编译android4.0 错处
2013-04-08 21:45 1239今天使用ubuntu11.10编译android4.0出现以下 ... -
常用WebService列表
2013-01-31 23:22 2652快递查询接口 http://webservice.36wu.c ... -
startActivityForResult 无响应问题
2013-01-24 13:57 3886今天开发遇到了个问题, 就是从一个Activity中使用sta ... -
Android中仿新浪微博刷新列表
2012-11-22 17:35 7356大家看到新浪微博中的列表往下拉的时候, 头部出现正在刷新,然后 ... -
Grid调整间距
2012-09-29 08:52 1775今天使用GridView, 发现点中某一Item时选中部分的背 ... -
android gallery和Animation组合使用, 看美女美图
2012-09-11 21:01 4475今天主要探究Gallery和Animation的使用。 制作一 ... -
Android执行 shell command
2012-03-24 17:00 7287Android执行shell命令 一、方法 1. /* ... -
BBBBBB111
2012-03-23 11:42 10陈波: 本周:代码review,解决findbugs中bug以 ... -
MonkeyTestError
2012-03-21 10:15 903-20 21:36:42.439 W/dalvikvm( ... -
INSTALL_FAILED_OLDER_SDK ERROR
2012-03-12 15:52 4498Install APK with adb: $ platfo ... -
4.0源码编译问题
2012-03-07 17:12 31751、fatal error: GL/glx.h: No suc ... -
4.0 编译apk中无classes.dex
2012-03-07 17:11 3993下载完android 4.0代码,模拟器里面的gallery不 ... -
Android 4.0源码编译错误
2012-03-05 10:19 2602UNEXPECTED TOP-LEVEL EXCEPTION: ... -
AndroidLockScreenDemo
2012-02-18 15:54 1017锁屏解锁的成功案例。 -
G14 root权限获取
2012-02-13 23:36 2885HTC G14 ROOT权限获取后就能删除系统自带的程序,相信 ... -
锁屏d ds
2011-12-15 00:49 929private final IDevicePolicyMana ...
相关推荐
4. **切换APN**:在Android应用中,如果需要在`cmnet`和`cmwap`之间切换,可以通过修改当前激活的APN实现。`cmnet`通常用于高速互联网访问,而`cmwap`通常用于WAP浏览,它们的APN设置是不同的。通过调用`...
本教程将详细探讨如何在Android系统中进行CMWAP网络的切换和配置。 一、CMWAP网络简介 CMWAP是GPRS(General Packet Radio Service)网络下的一种接入点名称(Access Point Name,简称APN),它是中国移动为用户...
给出的代码片段展示了如何在Android中实现自动判断和切换APN的方法。以下是一些关键知识点: 1. **ConnectivityManager**: 这是Android系统中用来管理网络连接的服务,可以通过`getSystemService(Context....
总的来说,Android开发中的GPRS连接管理涉及到对当前活动网络的判断、APN的设置和切换。开发者需要考虑到不同网络环境下的兼容性和用户便捷性,通过合理的编程策略确保应用程序在网络方面的稳定性和可靠性。
- 添加新的APN,名称任意,接入点设置为cmwap,代理服务器设为10.0.0.172,端口设为80。 - 如需将cmwap设为默认接入点,添加default关键字。 - 删除cmnet配置文件中的default项,以防止默认使用cmnet上网。 5. *...
例如,中国移动的APN可能是“cmnet”或“cmwap”。设置完成后,还需要输入相应的用户名和密码,但并非所有运营商都需要这些信息。 4. **选择网络模式**:根据运营商的网络覆盖情况,用户可能需要在2G、3G或自动模式...
针对文中提到的网络设置部分,特别是设置移动数据和互联网接入点(APN)的相关参数,确保以下信息正确配置是实现稳定网络连接的关键: 1. **接入点名称**:应根据运营商提供的具体名称设置。 2. **APN类型**:一般...