最近被Android系统的APN自动切换网络问题折腾死了,软件使用CMNET网络,而系统自带的一些软件必须使用CMWAP,或者手机厂家搞的一些后台服务或者流氓软件总是在切换网络。没办法,只好想个解决之道了。
我的解决方案是:
1、在程序启动时,注册 Receiver 监视网络状态,当网络发生变化判断不是CMNET时则切换网络;
2、为了保险起见,在每个HTTP链接请求前加上网络判断。
本软件主要实现了功能如下:
拍照、定位、表单文件上传、查询、短信拦截(用于通过短信指令获得手机当前位置)、拨打电话、定时自动上传定位数据、版本更新等。
如下粘贴APN网络判断网站代码:
1、NetworkChangeReceiver 网络状态监视
package com.wiz.receiver;
02
03
import com.wiz.tools.NetCheck;
04
import com.wiz.tools.StringUtils;
05
06
import android.content.BroadcastReceiver;
07
import android.content.Context;
08
import android.content.Intent;
09
import android.net.ConnectivityManager;
10
import android.net.NetworkInfo;
11
import android.util.Log;
12
13
public class NetworkChangeReceiver extends BroadcastReceiver {
14
NetCheck netCheck=new NetCheck();
15
public void onReceive(Context context, Intent intent) {
16
Log.e("NetworkChangeReceiver", "onReceive");
17
ConnectivityManager conManager= (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
18
19
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
20
NetworkInfo info = conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
21
String apn = StringUtils.null2String(info.getExtraInfo());
22
if (!"cmnet".equals(apn.toLowerCase())) {
23
netCheck.checkNetworkInfo(context);
24
}
25
}
26
}
27
}
2、Activity 中注册 NetworkChangeReceiver
NetworkChangeReceiver ncr = new NetworkChangeReceiver();
2
IntentFilter upIntentFilter = new IntentFilter( ConnectivityManager.CONNECTIVITY_ACTION);
3
this.registerReceiver(ncr, upIntentFilter);// 网络状态监控
3、APN判断及网络切换
package com.wiz.tools;
002
import android.content.ContentResolver;
003
import android.content.ContentValues;
004
import android.content.Context;
005
import android.database.Cursor;
006
import android.database.SQLException;
007
import android.net.ConnectivityManager;
008
import android.net.NetworkInfo;
009
import android.net.Uri;
010
import android.util.Log;
011
012
public class NetCheck {
013
public static final Uri APN_URI = Uri.parse("content://telephony/carriers");
014
public static final Uri CURRENT_APN_URI = Uri
015
.parse("content://telephony/carriers/preferapn");
016
public static String getCurrentAPNFromSetting(ContentResolver resolver) {
017
Cursor cursor = null;
018
try {
019
cursor = resolver.query(CURRENT_APN_URI, null, null, null, null);
020
String curApnId = null;
021
String apnName1=null;
022
if (cursor != null && cursor.moveToFirst()) {
023
curApnId = cursor.getString(cursor.getColumnIndex("_id"));
024
apnName1 = cursor.getString(cursor.getColumnIndex("apn"));
025
}
026
cursor.close();
027
Log.e("NetCheck getCurrentAPNFromSetting","curApnId:"+curApnId+" apnName1:"+apnName1);
028
//find apn name from apn list
029
if (curApnId != null) {
030
cursor = resolver.query(APN_URI, null, " _id = ?", new String[]{curApnId}, null);
031
if (cursor != null && cursor.moveToFirst()) {
032
String apnName = cursor.getString(cursor.getColumnIndex("apn"));
033
return apnName;
034
}
035
}
036
037
} catch (SQLException e) {
038
Log.e("NetCheck getCurrentAPNFromSetting",e.getMessage());
039
} finally {
040
if (cursor != null) {
041
cursor.close();
042
}4、HTTP请求前的判断
043
}
044
045
return null;
046
}
047
public static int updateCurrentAPN(ContentResolver resolver, String newAPN) {
048
Cursor cursor = null;
049
try {
050
//get new apn id from list
051
cursor = resolver.query(APN_URI, null, " apn = ? and current = 1", new String[]{newAPN.toLowerCase()}, null);
052
String apnId = null;
053
if (cursor != null && cursor.moveToFirst()) {
054
apnId = cursor.getString(cursor.getColumnIndex("_id"));
055
}
056
cursor.close();
057
Log.e("NetCheck updateCurrentAPN","apnId:"+apnId);
058
//set new apn id as chosen one
059
if (apnId != null) {
060
ContentValues values = new ContentValues();
061
values.put("apn_id", apnId);
062
resolver.update(CURRENT_APN_URI, values, null, null);
063
} else {
064
//apn id not found, return 0.
065
return 0;
066
}
067
} catch (SQLException e) {
068
Log.e("NetCheck updateCurrentAPN",e.getMessage());
069
} finally {
070
if (cursor != null) {
071
cursor.close();
072
}
073
}
074
075
//update success
076
return 1;
077
}
078
079
public boolean checkNetworkInfo(Context c) {
080
boolean ret=false;
081
ConnectivityManager conManager= (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
082
NetworkInfo info = conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
083
boolean internet=conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnectedOrConnecting();
084
String oldAPN = StringUtils.null2String(info.getExtraInfo());
085
String oldSQLAPN=StringUtils.null2String(getCurrentAPNFromSetting(c.getContentResolver()));
086
087
Log.e("NetCheck checkNetworkInfo","oldAPN:"+oldAPN+" oldSQLAPN:"+oldSQLAPN);
088
if (internet==false||!"cmnet".equals(oldAPN.toLowerCase())||!"cmnet".equals(oldSQLAPN.toLowerCase())) {
089
if("cmwap".equals(oldAPN.toLowerCase())&&"cmnet".equals(oldSQLAPN.toLowerCase())){
090
updateCurrentAPN(c.getContentResolver(), "cmwap");
091
try {
092
Thread.sleep(200);
093
} catch (InterruptedException e) {
094
e.printStackTrace();
095
}
096
}
097
updateCurrentAPN(c.getContentResolver(), "cmnet");
098
try {
099
Thread.sleep(200);
100
} catch (InterruptedException e) {
101
e.printStackTrace();
102
}
103
ret=true;
104
}
105
return ret;
106
107
}
108
}
4、HTTP请求前的判断
if (nc.checkNetworkInfo(LoginActivity.this)) {
2
Thread.sleep(5000);// 设置cmnet网络
3
}