实现开启和关闭android移动网络(转)
开启和关闭移动数据网络有两种方法:一种是通过操作系统的数据库改变APN(网络接入点),从而实现开启和关闭移动数据网络,另一种是通过反射调用系统(ConnectivityManager)的setMoblieDataEnabled方法,通过操作该方法开启和关闭系统移动数据,同时也可以通过反射调用getMoblieDataEnabled方法获取当前的开启和关闭状态。
第一种方式:
通过APN的方式开启和关闭很威猛啊,为什么这么说呢,废话不多说,先看代码:
1. 匹配类:
- //创建一个匹配类,用于匹配移动、电信、联通的APN
- 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(CMNET))
- return CMNET;
- else if (currentName.startsWith(CMWAP))
- return CMWAP;
- else if (currentName.startsWith(GNET_3))
- return GNET_3;
- else if (currentName.startsWith(GWAP_3))
- return GWAP_3;
- else if (currentName.startsWith(UNINET))
- return UNINET;
- else if (currentName.startsWith(UNIWAP))
- return UNIWAP;
- else if (currentName.startsWith(CTWAP))
- return CTWAP;
- else if (currentName.startsWith(CTNET))
- return CTNET;
- else if (currentName.startsWith("default"))
- return "default";
- else
- return "";
- }
- }
2. 开启和关闭APN的方法在ApnSwitchTest类中实现,如下:
- import java.util.ArrayList;
- import java.util.List;
- import android.app.Activity;
- import android.content.ContentValues;
- import android.database.Cursor;
- import android.net.Uri;
- import android.util.Log;
- public class ApnSwitchTest extends Activity
- {
- Uri 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
- });
- }
- }
- public static class APN
- {
- String id;
- String apn;
- String type;
- }
- private List<APN> 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("ApnSwitch", "id" + cr.getString(cr.getColumnIndex("_id")) + " \n" + "apn"
- + cr.getString(cr.getColumnIndex("apn")) + "\n" + "type"
- + cr.getString(cr.getColumnIndex("type")) + "\n" + "current"
- + cr.getString(cr.getColumnIndex("current")));
- APN a = new APN();
- a.id = cr.getString(cr.getColumnIndex("_id"));
- a.apn = cr.getString(cr.getColumnIndex("apn"));
- a.type = cr.getString(cr.getColumnIndex("type"));
- list.add(a);
- }
- if (cr != null)
- cr.close();
- return list;
- }
- }<span style="font-family: 'Comic Sans MS'; "> </span>
最后,别忘了在AndroidManifext.xml文件中添加访问权限<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
亲们,从上面的代码中看出什么来了么,没错,通过APN的方式就是修改数据库,关闭APN其实就是给它随便匹配一个错误的APN。为什么说这种方法很生猛呢,当你通过这个方式关闭APN后,你在通过手机上的快捷开关开启移动数据网络时,是没效果的,也就是说开启不了,除非你再用同样的方法开启APN。
第二种方式:
这就奇怪了,关闭APN后,为什么再通过手机上的快捷开关(AppWidget)开启不了呢,这个问题就值得思考了,说明快捷开关其实并不是通过这个方式来开启和关闭移动网络的。道理很简单,想想那些快捷开关是怎么样根据开启和关闭移动网络,然后更换亮和暗的图标的呢(更新UI)。这里肯定会涉及到一个获取系统当前开启和关闭移动数据状态的问题。那到底是怎样获取的,是通过什么样的形式的?其实道理很简单,就是通过调用系统的getMobileDataState和setMobileData(我是这么知道它是调用到这个方法的呢?亲们,如果你有android手机,把它插到电脑上,然后开启已经搭建好的android开发环境的eclpise,打开logcat面板,相应地在你手机的快捷开关上开启和关闭移动网络,然后看看在logcat面板上出现什么了)。
既然知道是调用上面这两个方法了,我们是不是就可以直接调用这个两个方法实现了?NO,没这么简单,这个两个方法不能直接调用,必须通过反射机制调用(呵呵,没接触过java有关反射的知识的,或者是忘了的,可以去学习和温习一下)。
- /**
- * 设置手机的移动数据
- */
- public static void setMobileData(Context pContext, boolean pBoolean) {
- try {
- ConnectivityManager mConnectivityManager = (ConnectivityManager) pContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- Class ownerClass = mConnectivityManager.getClass();
- Class[] argsClass = new Class[1];
- argsClass[0] = boolean.class;
- Method method = ownerClass.getMethod("setMobileDataEnabled", argsClass);
- method.invoke(mConnectivityManager, pBoolean);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- System.out.println("移动数据设置错误: " + e.toString());
- }
- }
- /**
- * 返回手机移动数据的状态
- *
- * @param pContext
- * @param arg
- * 默认填null
- * @return true 连接 false 未连接
- */
- public static boolean getMobileDataState(Context pContext, Object[] arg) {
- try {
- ConnectivityManager mConnectivityManager = (ConnectivityManager) pContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- Class ownerClass = mConnectivityManager.getClass();
- Class[] argsClass = null;
- if (arg != null) {
- argsClass = new Class[1];
- argsClass[0] = arg.getClass();
- }
- Method method = ownerClass.getMethod("getMobileDataEnabled", argsClass);
- Boolean isOpen = (Boolean) method.invoke(mConnectivityManager, arg);
- return isOpen;
- } catch (Exception e) {
- // TODO: handle exception
- System.out.println("得到移动数据状态出错");
- return false;
- }
- }</span>
最后,别忘了在AndroidMannifest.xml文件里添加访问权限 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />,
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
通过上面的代码可以知道,当开启移动网络时调用:
setMobileData(context,true),关闭调用setMobileData(context,false),通过getMobileDataStatus(context)方法返回的布尔值判断当移动数据网络前状态的开启和关闭。
转自:http://blog.csdn.net/fangzhibin4712/article/details/26563285
实现开启和关闭android移动网络(转)的更多相关文章
- Ubuntu中开启和关闭防火墙-摘自网络
1.关闭ubuntu的防火墙 ufw disable开启防火墙ufw enable 2.卸载了iptablesapt-get remove iptables3.关闭ubuntu中的防火墙的其余命令ip ...
- Android网络开启、关闭整理
package com.my.device_admin.business; import java.lang.reflect.Method; import android.content.Contex ...
- [Android Traffic] Android网络开启、关闭整理
转载: http://blog.csdn.net/tu_bingbing/article/details/8469871 近段时间由于要对手机网络状况进行判断.开启和关闭,从网上找了些资料,现整理如下 ...
- Android中如何监听GPS开启和关闭
转自 chenming 原文 Android中如何监听GPS开启和关闭 摘要: 本文简单总结了如何监听GPS开关的小技巧 有时需要监听GPS的开关(这种需求并不多见).实现的思路是监听代表 GPS ...
- Android IntentService 与Alarm开启任务关闭任务
1:MyService public class MyService extends IntentService{ AlarmManager alarmManager = null; PendingI ...
- Android的WiFi开启与关闭
注意:要首先注册开启和关闭WiFi的权限, <?xml version="1.0" encoding="utf-8"?> <manifest ...
- Android手动控制软键盘的开启和关闭,判断软键盘是否显示;
工具类,拿走就能用: import android.annotation.TargetApi; import android.app.Activity; import android.content. ...
- Android 怎样开启与关闭adb 的认证机制(google adb secure) (adb RSA 指纹认证)
前言 欢迎大家我分享和推荐好用的代码段~~声明 欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net ...
- Android 开启与关闭软键盘
http://www.cnblogs.com/weixing/p/3300908.html InputMethodManager imm = (InputMethodManager)getSystem ...
随机推荐
- 自定义 SqlHelp
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Data; usin ...
- js中window的属性
Window的属性 属性描述 closed 获取引用窗口是否已关闭. defaultStatus 设置或获取要在窗口底部的状态栏上显示的缺省信息. dialogArguments 设置或获取传递给模式 ...
- IOS开发/iphone开发多线程
有时候可能有很多功能要同时实现,例如每隔多长时间就会检测程序网络连接,又或者有时候需要从服务器下载一个不小的文件,如果用单线程几乎是不可想的事情,程序将会卡的无法使用,用到多线程和不用多线程,给用户的 ...
- 转:Java NIO系列教程(八) DatagramChannel
Java NIO中的DatagramChannel是一个能收发UDP包的通道.因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入.它发送和接收的是数据包. 打开 DatagramChann ...
- linux 的终端字体色和背景色的修改方法(三)
除了在窗口下修改,配置文件中修改外,还可以用shell来修改,此处为B shell linux BASH shell下设置字体及背景颜色 类型:转载 这篇文章主要介绍了linux BASH shell ...
- Linux下链接mysql数据库的命令
一.MySQL 连接本地数据库,用户名为“root”,密码“123”(注意:“-p”和“123” 之间不能有空格) C:\>mysql -h localhost -u root -p123 二. ...
- 为wordpress添加Canonical标签
在 WordPress 2.9 之前,让 WordPress 博客支持 Canonical 标签是需要通过插件或者手工修改主题的 header.php 文件来实现.如在主题中加如下的代码: <? ...
- PHP连接MySQL报错:SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket 'MySQL' (2)
如下所示,PHP连接MySQL报错: SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket 'MySQL' ...
- 一个1年前的T-SQL问题
还记得年前的一个SQL问题,当时对SQL刚接触,因此绕开了它.用了别的办法.昨天看SQL突然想起了这个问题.百思不得其解,然后去SQL Server技术交流群,也请教了,大神高文佳,何志勇提示我因为先 ...
- java笔记--使用线程池优化多线程编程
使用线程池优化多线程编程 认识线程池 在Java中,所有的对象都是需要通过new操作符来创建的,如果创建大量短生命周期的对象,将会使得整个程序的性能非常的低下.这种时候就需要用到了池的技术,比如数据库 ...