实现开启和关闭Android移动网络(做AppWidget开发的收获)
之前在做Android AppWidget这方面的开发,本人菜鸟一个,刚接触android不久。所以在开发的过程中不免遇到诸多难处,不过在解决问题中收获知识是一种非常刺激的体验。接下来是本人在开发开关android系统移动网络的过程所收获的知识,希望能够帮助有需要的爱好编程者(呵呵..本人是Java语言的忠实粉丝)。
其实开启和关闭移动数据网络有两种方法:一种是通过操作系统的数据库改变APN(网络接入点),从而实现开启和关闭移动数据网络,另一种是通过反射调用系统(ConnectivityManager)的setMoblieDataEnabled方法,通过操作该方法开启和关闭系统移动数据,同时也可以通过反射调用getMoblieDataEnabled方法获取当前的开启和关闭状态。
第一种方式:
通过APN的方式开启和关闭很威猛啊,为什么这么说呢,废话不多说,先看代码:
1. 匹配类:
//创建一个匹配类,用于匹配移动、电信、联通的APN
public final class APNMatchTools
{
public final class APNMatchTools
{
//中国移动cmwap
public static String CMWAP = "cmwap";
//中国移动cmnet
public static String CMNET = "cmnet";
//中国联通3gwap APN
public static String GWAP_3 = "3gwap";
//中国联通3gnet APN
public static String GNET_3 = "3gnet";
//中国联通uni wap APN
public static String UNIWAP = "uniwap";
//中国联通uni net APN
public static String UNINET = "uninet";
//中国电信 ct wap APN
public static String CTWAP = "ctwap";
//中国电信ct net APN
public static String CTNET = "ctnet";
}
public static String matchAPN(String currentName)
{
if("".equals(currentName)|| null == currentName)
{
return "";
}
//参数转为小写
currentName = currentName.toLowerCase();
//检查参数是否与各APN匹配,返回匹配值
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(APNNet.CTWAP))
return APNNet.CTWAP;
else if(currentName.startsWith(APNNet.CTNET))
return APNNet.CTNET;
else if(currentName.startsWith("default"))
return "default";
else return "";
}
}
2. 开启和关闭APN的方法
注: uri = Uri.parse("content://telephony/carriers/preferapn");
//开启APN
public void openAPN()
{
List<APN> list = getAPNList();
for(APN apn : list)
{
ContentValues cv = new ContentValues();
//获取及保存移动或联通手机卡的APN网络匹配
cv.put("apn", APNMatchTools.matchAPN(apn.apn));
cv.put("type", APNMatchTools.matchAPN(apn.type));
//更新系统数据库,改变移动网络状态
getContentResolver().update(uri, cv, "_id=?", new String[]{apn.id});
}
}
//关闭APN
public void closeAPN()
{
List<APN> list = getAPNList();
for(APN apn : list)
{
//创建ContentValues保存数据
ContentValues cv = new ContentValues();
//添加"close"匹配一个错误的APN,关闭网络
cv.put("apn", APNMatchTools.matchAPN(apn.apn) + "close");
cv.put("type", APNMatchTools.matchAPN(apn.type) +"close");
//更新系统数据库,改变移动网络状态
getContentResolver().update(uri, cv, "_id=?", new String[]{apn.id});
}
}
private List<APN> getAPNList()
{
String tag = "FXAppWidgetUI02.getAPNList()";
//current不为空表示可以使用的APN
String projection[] = {"_id, apn, type, current"};
//查询获取系统数据库的内容
Cursor cr = getContentResolver().query(uri,projection, null,null, null);
//创建一个List集合
List<APN> list = new ArrayList<APN>();
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.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;
}
最后,别忘了在AndroidManifext.xml文件中添加访问权限<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
亲们,从上面的代码中看出什么来了么,没错,通过APN的方式就是修改数据库,关闭APN其实就是给它随便匹配一个错误的APN。为什么说这种方法很生猛呢,当你通过这个方式关闭APN后,你在通过手机上的快捷开关开启移动数据网络时,是没效果的,也就是说开启不了,除非你再用同样的方法开启APN。
这就奇怪了,关闭APN后,为什么再通过手机上的快捷开关(AppWidget)开启不了呢,这个问题就值得思考了,说明快捷开关其实并不是通过这个方式来开启和关闭移动网络的。道理很简单,想想那些快捷开关是怎么样根据开启和关闭移动网络,然后更换亮和暗的图标的呢(更新UI)。这里肯定会涉及到一个获取系统当前开启和关闭移动数据状态的问题。那到底是怎样获取的,是通过什么样的形式的?其实道理很简单,就是通过调用系统的getMoblieDataEnabled和setMoblieDataEnabled(我是这么知道它是调用到这个方法的呢?亲们,如果你有android手机,把它插到电脑上,然后开启已经搭建好的android开发环境的eclpise,打开logcat面板,相应地在你手机的快捷开关上开启和关闭移动网络,然后看看在logcat面板上出现什么了)。
既然知道是调用上面这两个方法了,我们是不是就可以直接调用这个两个方法实现了?NO,没这么简单,这个两个方法不能直接调用,必须通过反射机制调用(呵呵,没接触过java有关反射的知识的,或者是忘了的,可以去学习和温习一下)。
第二种方式:
废话不多说,看下面的代码:
// 移动数据开启和关闭
public boolean setMobileDataStatus(Context context,boolean enabled)
{
ConnectivityManager conMgr = (ConnectivityManager)this.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(ClassNotFoundException e)
{
e.printStackTrace();
}
catch(NoSuchFieldException e)
{
e.printStackTrace();
}
catch(SecurityException e)
{
e.printStackTrace();
}
catch(NoSuchMethodException e)
{
e.printStackTrace();
}
catch(IllegalArgumentException e)
{
e.printStackTrace();
}
catch(IllegalAccessException e)
{
e.printStackTrace();
}
catch(InvocationTargetException e)
{
e.printStackTrace();
}
}
//获取移动数据开关状态
public boolean getMobileDataStatus(String getMobileDataEnabled)
{
ConnectivityManager cm;
cm = (ConnectivityManager)this.getSystemService(Context.CONNECTIVITY_SERVICE);
Class cmClass = cm.getClass();
Class[] argClasses = null;
Object[] argObject = null;
Boolean isOpen = false;
try
{
Method method = cmClass.getMethod(getMobileDataEnabled, argClasses);
isOpen = (Boolean)method.invoke(cm, argObject);
}catch(Exception e)
{
e.printStackTrace();
}
return isOpen;
}
最后,别忘了在AndroidMannifest.xml文件里添加访问权限 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />, <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
通过上面的代码可以知道,当开启移动网络时调用setMobileDataStatus(context,true),关闭调用setMobileDataStatus(context,false),通过getMobileDataStatus(String getMobileDataEnabled)方法返回的布尔值判断当移动数据网络前状态的开启和关闭。
原文地址:点击打开链接
实现开启和关闭Android移动网络(做AppWidget开发的收获)相关推荐
- 实现开启和关闭android移动网络(转)
开启和关闭移动数据网络有两种方法:一种是通过操作系统的数据库改变APN(网络接入点),从而实现开启和关闭移动数据网络,另一种是通过反射调用系统(ConnectivityManager)的setMobl ...
- 原生Android也能做Web开发了
大家好,今天跟大家介绍一个让原生Android也可以做Web开发的开源项目--AndServer. 开源地址:github.com/yanzhenjie/- AndServer是一个Android端的 ...
- android调用关闭移动数据,android开启和关闭移动网络
转自:http://blog.csdn.net/stevenhu_223/article/details/7860964 /** * 移动数据开启和关闭 * * @param context * @p ...
- Android AlertDialog 对话框开启和关闭输入法问题
Android AlertDialog 对话框开启和关闭输入法问题 AlertDialog 对话框是android jar包自带的对话框,说实话 真的很丑,黑白相间,不是很推荐使用.大多时候 特别是项 ...
- 正确姿势临时和永久开启关闭Android的SELinux
正确姿势临时和永久关闭Android的SELinux Android SELinux开发多场景实战指南目录: Android SELinux开发入门指南之SELinux基础知识 Andro ...
- android去掉便携式wifi热点,Android 获取便携式wifi热点开关状态、热点开启与关闭...
最近做了这两个功能: 1.获取便携式wifi热点开关状态: 2.热点的开启与关闭. 第二个功能就不用说了,百度一搜一大把:第一个功能,在百度基本找不到,最后我是在google找到的,getWifiAp ...
- Android 获取便携式热点开关状态、热点开启与关闭
最近做了这两个功能: 1.获取便携式热点开关状态: 2.热点的开启与关闭. 第二个功能就不用说了,百度一搜一大把:第一个功能,在百度基本找不到,最后我是在google找到的,getWifiApStat ...
- Android手动控制软键盘的开启和关闭,判断软键盘是否显示;
工具类,拿走就能用: import android.annotation.TargetApi; import android.app.Activity; import android.content. ...
- Android 10.0 开启和关闭护眼模式
1.概述 在10.0系统的产品定制化中,由于一些定制化开发设备中,需要护眼模式,而护眼模式功能开启和关闭 也需要提供接口供app调用,这就需要在系统api中自定义的服务中,提供开启关闭护眼模式的接口, ...
最新文章
- JS-匀速运动-运动停止
- 使用LINQ更新集合中的所有对象
- 为什么要使用EJB?
- filter2D函数
- HTTPS 原理详解
- C++ primer第六章6.4函数的学习 之函数的重载
- 如何通过jQuery动态设置元素CSS的样式,以及HTML中CSS “内联式”、“嵌套式”、“外联式”使用方法
- 极域电子教室卸载或安装软件后windows7无法启用触摸板、键盘
- matlab飞机高度控制,基础知识 | 飞行中的各种高度(三)
- Java项目经验相关常见面试题
- [ERROR] [FATAL] InnoDB: Over 95 percent of the buffer pool is occupied by lock heaps or the adaptive
- init cloudchannel failerr:10102 - message:参数无效
- JavaFX 过时了吗?你怎么看,闲暇之余实现一版贪吃蛇小游戏,放松一下!
- 奶酪和奶酪碎的区别_与奶酪三星银河芽战斗大逃杀直播vs airpods
- 通过nginx实现线上页面访问本地接口
- python代码设计测试用例_《带你装B,带你飞》pytest成神之路2- 执行用例规则和pycharm运行的三种姿态...
- bat批处理与adb命令的配合
- idea中用rest风格发送delete,put请求报405(tomcat8)
- 这样充满青春活力的微信公众号图文排版,你见过吗?
- 设计模式学习(汇总版)