标签:android style blog http color os 使用 io java
开启和关闭移动数据网络有两种方法:一种是通过操作系统的数据库改变APN(网络接入点),从而实现开启和关闭移动数据网络,另一种是通过反射调用系统(ConnectivityManager)的setMoblieDataEnabled方法,通过操作该方法开启和关闭系统移动数据,同时也可以通过反射调用getMoblieDataEnabled方法获取当前的开启和关闭状态。
第一种方式:
通过APN的方式开启和关闭很威猛啊,为什么这么说呢,废话不多说,先看代码:
1. 匹配类:
- public final class APNMatchTools
- {
-
-
- public static String CMWAP = "cmwap";
-
-
- public static String CMNET = "cmnet";
-
-
-
- public static String GWAP_3 = "3gwap";
-
-
- public static String GNET_3 = "3gnet";
-
-
- public static String UNIWAP = "uniwap";
-
-
- public static String UNINET = "uninet";
-
-
- public static String CTWAP = "ctwap";
-
-
- public static String CTNET = "ctnet";
-
- public static String matchAPN(String currentName)
- {
-
- if ("".equals(currentName) || null == currentName)
- {
-
- return "";
- }
-
-
- currentName = currentName.toLowerCase();
-
- 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");
-
-
- public void openAPN()
- {
- List<APN> list = getAPNList();
- for (APN apn : list)
- {
- ContentValues cv = new ContentValues();
-
-
- cv.put("apn", APNMatchTools.matchAPN(apn.apn));
- cv.put("type", APNMatchTools.matchAPN(apn.type));
-
-
- getContentResolver().update(uri, cv, "_id=?", new String[]
- {
- apn.id
- });
- }
-
- }
-
-
- public void closeAPN()
- {
- List<APN> list = getAPNList();
- for (APN apn : list)
- {
-
- ContentValues cv = new ContentValues();
-
- 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()
- {
-
- String projection[] =
- {
- "_id, apn, type, current"
- };
-
- Cursor cr = getContentResolver().query(uri, projection, null, null, null);
-
-
- 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) {
-
- e.printStackTrace();
- System.out.println("移动数据设置错误: " + e.toString());
- }
- }
-
- 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) {
-
-
- 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移动网络(转)
标签:android style blog http color os 使用 io java
原文地址:http://www.cnblogs.com/SharkBin/p/3946834.html