如何在Android上禁用移动数据

在有人告诉我购买应用程序之前快速回到故事。 =)

我刚刚获得了一个EVO,它通过电池咀嚼相当快。 我下载了JuiceDefender来管理我的移动数据连接。 这似乎工作得很好。 但是,这些设置只是非常有限(甚至在付费版本上)。

截至目前,我正在尝试开发更多可定制的电池节能应用。 我首先要做的主要事情是能够随意启用/禁用移动数据连接。

问题是我找不到任何代码片段或文章如何做到这一点。 我发现的唯一的事情是以下。 我不知道这是多么准确,但这是我能拼凑在一起浏览developer.android.com

ConnectivityManager cm = (ConnectivityManager) this.getSystemService(CONNECTIVITY_SERVICE); cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "android.net.conn.CONNECTIVITY_CHANGE"); State state = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState(); textView.setText(state.name()); 

如果有人能指点我什么可以帮助的,那将是非常感激的。

UPDATE

看来,冲刺的HTC Evo不使用APN设置。 我通过下载APNDroid并观察它不起作用测试了这个。 然后,我做了一个快速的应用程序转储到屏幕上的所有APN条目。 这产生了一个结果,这是为了mms。

看着JuiceDefender运行时的电话信息,我发现GSRP网络正在打开和关闭。 这让我相信有可能通过代码来完成,即使我发现每个页面都提到了这个问题,但是这个问题说明了这个问题是无法完成的。 踢球者是他们都说要像APNDroid那样做。 请有人给我一些见解。

谢谢!

Dataconnection禁用和启用APIS隐藏在SDK中,而不会暴露给用户,这可以通过使用java反射技术访问ITelephony接口来实现。

干得好:

  Method dataConnSwitchmethod; Class telephonyManagerClass; Object ITelephonyStub; Class ITelephonyClass; TelephonyManager telephonyManager = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); if(telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED){ isEnabled = true; }else{ isEnabled = false; } telephonyManagerClass = Class.forName(telephonyManager.getClass().getName()); Method getITelephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony"); getITelephonyMethod.setAccessible(true); ITelephonyStub = getITelephonyMethod.invoke(telephonyManager); ITelephonyClass = Class.forName(ITelephonyStub.getClass().getName()); if (isEnabled) { dataConnSwitchmethod = ITelephonyClass .getDeclaredMethod("disableDataConnectivity"); } else { dataConnSwitchmethod = ITelephonyClass .getDeclaredMethod("enableDataConnectivity"); } dataConnSwitchmethod.setAccessible(true); dataConnSwitchmethod.invoke(ITelephonyStub); 

从“姜饼”开始,你可以使用IConnectivityManager.setMobileDataEnabled()方法。 它隐藏在API中,但可以通过反射来访问。 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/net/ConnectivityManager.java#376

使用此方法,您可以更改系统设置:“设置 – >无线和网络 – >移动网络设置 – > 数据已启用

代码示例:

 private void setMobileDataEnabled(Context context, boolean enabled) { final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); final Class conmanClass = Class.forName(conman.getClass().getName()); final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService"); iConnectivityManagerField.setAccessible(true); final Object iConnectivityManager = iConnectivityManagerField.get(conman); final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName()); final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE); setMobileDataEnabledMethod.setAccessible(true); setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled); } 

你也需要CHANGE_NETWORK_STATE权限。

 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> 

不用说,这种方法可能不适用于未来的Android版本。 但是我想像“3G看门狗”,“APNdroid”或“DataLock”这样的应用程序就是这样工作的。


更新
setMobileDataEnabled方法在Lollipop上不再可用

自从姜饼以来,通过改变APN的名字来切换移动数据网络连接不再有效。 而反射代码可能是正确的方法来做这个伎俩,它不会工作,因为该应用程序需要像Alex P.解释的android.permission.MODIFY_PHONE_STATE权限,否则你会得到这个讨厌的异常:

 03-18 21:54:55.074: WARN/System.err(1851): java.lang.reflect.InvocationTargetException (...) 03-18 21:54:55.263: WARN/System.err(1851): Caused by: java.lang.SecurityException: Neither user 10037 nor current process has android.permission.MODIFY_PHONE_STATE. (...) 03-18 21:54:55.303: WARN/System.err(1851): at com.android.internal.telephony.ITelephony$Stub$Proxy.disableDataConnectivity(ITelephony.java:888) 

不幸的是,你不能设置这个权限,因为它是应用程序不允许的3级权限:

 03-18 21:48:39.334: WARN/PackageManager(75): Not granting permission android.permission.MODIFY_PHONE_STATE to package XXX (protectionLevel=3 flags=0x8be46) 

我不认为任何人有办法重写权限授予抑制,而不是使用自己的固件。

我认为在Android设备上有两种主要的移动数据连接类型:WiFi和3G / HSDPA /等。

而afaik你应该能够以编程方式禁用WiFi,但我认为只能通过更改APN的名称来禁用3G / HSDPA / etc连接。 我这样说的原因是因为流行的应用程序APNDroid这样做。

请注意Android 2.3及更高版本不再支持“android.permission.MODIFY_PHONE_STATE”。

为什么2.3版本的android没有hava android.permission.MODIFY_PHONE_STATE? 这是什么解决方案?

添加一个切换按钮,您可以使用此代码另外弗拉基米尔的答案:

 TelephonyManager telephonyManager = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); switch (telephonyManager.getDataState()) { case TelephonyManager.DATA_CONNECTED: setMobileDataEnabledMethod.invoke(iConnectivityManager, false); break; case TelephonyManager.DATA_DISCONNECTED: setMobileDataEnabledMethod.invoke(iConnectivityManager, true); break; } 

这反射替代方法仍然在Android 4.0.4上工作

@Mariux:你可能忘了在AndroidManifest.xml中添加<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />