Android AppWidget控制手机上网APN接入点
来源:互联网 发布:光纤网络测速 编辑:程序博客网 时间:2024/06/06 07:52
首先很有必要讲一下需求,由于搞IT的加班比较多,每天回家基本上都是8点之后,电信网络又贵,无奈我屌丝一个用网时间又少,索性在淘宝上花重金购置了一张1元5小时的上网卡,貌似是广东电信的绝版卡,在广东省内上网5小时一分钱,但是接入点要是CTWAP,否则上网就是1小时3块钱了。用久了发现了一个弊端:网络不好的时候手机会自动切换APN接入点,刚开始的时候我是下载一个了HIAPN的软件,这个软件提供一个桌面插件,很方便看到当前APN接入点是什么。可惜好景不长,随着系统升级,这个软件停止了更新,只能在固件2.3的系统上使用。于是我就琢磨这自己来开发一个插件,而且最好在手机切换APN的时候能够有报警机制(震动)。
扯完了需求,马上就上干货了。
1.切换WIFI开关
如果开着WIFI就关掉,如果关掉就打开。这个是最简单的了,普通应用就OK
/** * 切换wifi开关 * @param context */public static void changeWifi(Context context) {WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);if (wifiManager.isWifiEnabled()) {wifiManager.setWifiEnabled(false);} else {wifiManager.setWifiEnabled(true);}}对应权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
2.切换手机数据流量
2.1 获取手机流量数据开关
public static boolean getMobileDataState(Context cxt) {TelephonyManager telephonyService = (TelephonyManager) cxt.getSystemService(Context.TELEPHONY_SERVICE);try {Method getMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("getDataEnabled");if (null != getMobileDataEnabledMethod) {boolean mobileDataEnabled = (Boolean) getMobileDataEnabledMethod.invoke(telephonyService);return mobileDataEnabled;}} catch (Exception e) {Log.v(TAG,"Error getting"+ ((InvocationTargetException) e).getTargetException() + telephonyService);}return false;}
2.2 设置手机流量数据(android5.0以下)
/** * 当开启移动网络时调用setMobileDataStatus(context,true), * 关闭调用setMobileDataStatus(context,false) * 移动数据开启和关闭 * @param context * @param enabled */ public static void setMobileDataStatus(Context context,boolean enabled) { ConnectivityManager conMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); //ConnectivityManager类 Class<?> conMgrClass = null; //ConnectivityManager类中的字段 Field iConMgrField = null; //IConnectivityManager类的引用 Object iConMgr = null; //IConnectivityManager类 Class<?> iConMgrClass = null; //setMobileDataEnabled方法 Method setMobileDataEnabledMethod = null; try { //取得ConnectivityManager类 conMgrClass = Class.forName(conMgr.getClass().getName()); //取得ConnectivityManager类中的对象Mservice iConMgrField = conMgrClass.getDeclaredField("mService"); //设置mService可访问 iConMgrField.setAccessible(true); //取得mService的实例化类IConnectivityManager iConMgr = iConMgrField.get(conMgr); //取得IConnectivityManager类 iConMgrClass = Class.forName(iConMgr.getClass().getName()); //取得IConnectivityManager类中的setMobileDataEnabled(boolean)方法 setMobileDataEnabledMethod = iConMgrClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE); //设置setMobileDataEnabled方法是否可访问 setMobileDataEnabledMethod.setAccessible(true); //调用setMobileDataEnabled方法 setMobileDataEnabledMethod.invoke(iConMgr, enabled); } catch(Exception e) { e.printStackTrace(); } }
对应的权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
2.3 设置手机流量数据开关(android5.0及以上)
public static void setMobileDataState(Context cxt, boolean mobileDataEnabled) {TelephonyManager telephonyService = (TelephonyManager) cxt.getSystemService(Context.TELEPHONY_SERVICE);try {Method setMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("setDataEnabled", boolean.class);if (null != setMobileDataEnabledMethod) {setMobileDataEnabledMethod.invoke(telephonyService,mobileDataEnabled);}} catch (Exception e) {Log.v(TAG,"Error setting"+ ((InvocationTargetException) e).getTargetException() + telephonyService);}}
对应的权限
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
注意:android5.0的这个隐藏接口的调用,把apk移动到system/priva-app 这个目录下面才能调用成功(我没有试验过,网上有网友说可行),或者你要是有手机的plaform签名,因为上面的权限只能赋予给系统应用,最好直接用系统权限打包后签名。这个接口的改动所以会导致我们用WIFI万能钥匙的时候如果你的手机是android5.0以上,能够直接打开WIFI但不能直接开启手机数据流量,而是提示你手动开启数据流量。
3.切换APN接入点
3.1获取当前APN接入点
public static final Uri PRE_APN_URI = Uri.parse("content://telephony/carriers/preferapn"); // 获取当前APNpublic static String getCurApnName(Context context) {ContentResolver resoler = context.getContentResolver();// String[] projection = new String[] { "_id" };Cursor cur = resoler.query(PRE_APN_URI, projection, null, null, null);String apnName = "";// cur为空则表示默认情况下一个都没有选中if (cur != null && cur.moveToFirst()) {// apnId = cur.getString(cur.getColumnIndex("_id"));apnName = cur.getString(cur.getColumnIndex("apn"));}Log.i("xml", "getCurApnId:" + apnName);return apnName;}
3.2更新APN接入点
// 所有的APN配配置信息位置 public static final Uri APN_LIST_URI = Uri.parse("content://telephony/carriers"); public static boolean updateCurrentAPN(ContentResolver resolver, String newAPN) { boolean changeResult = false; 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(PRE_APN_URI, values, null, null); changeResult = true; } else { //apn id not found, return 0. } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); } } return changeResult; } }
需要的权限
<!-- Permission is only granted to system apps --> <uses-permission android:name="android.permission.WRITE_APN_SETTINGS"/>
这个也是系统权限啊,由此可以看出实现的难度 切换WIFI<切换手机流量<切换APN
本Demo代码已经上传GitHub,点击下载,注意切换手机流量和APN都要有系统权限,如果没有对应手机的platform签名,会无法安装。
- Android AppWidget控制手机上网APN接入点
- Android学习之网络APN接入点控制
- 手机无法上网时添加/修改apn(接入网络)设置
- Android APN管理 (接入点管理)
- Android手机上网、彩信APN设置
- Android手机上网、彩信APN设置 .
- Android手机上网、彩信APN设置
- Android手机上网、彩信APN设置
- 常用APN接入点
- apn接入点切换
- apn接入点切换
- APN symbian手机上的接入点编程
- APN symbian手机上的接入点编程
- Android中如何获取当前apn接入点并切换?
- Android中如何获取当前apn接入点并切换?
- Android手机通过APN设置上网的方法
- 三大运营商手机上网接入点设置
- Android手机APN简介
- 瀑布流
- 汉语输入法无选择列表
- Xcode开发技巧之Code Snippets Library(代码片段库)
- 七牛关于Android SDK jar包依赖情况总结
- SWD与JTAG的区别
- Android AppWidget控制手机上网APN接入点
- 几种数据保存方式
- Oracle学习总结(10)——45 个非常有用的 Oracle 查询语句
- Java类、方法与接口
- 一、WebGL入门的开始
- 开通博客
- Raspberry pi 2网络配置
- uva572 Oil Deposits
- Linux下MySQL慢查询分析mysqlsla安装使用