Cómo deshabilitar datos móviles en Android

Una historia rápida antes de que alguien me diga que compre una aplicación. =)

Acabo de recibir un EVO y mastica la batería bastante rápido. Descargué JuiceDefender para administrar mi conexión de datos móviles. Eso parece haber funcionado bastante bien. Sin embargo, la configuración es muy restringida (incluso en las versiones pagas).

A partir de ahora estoy tratando de desarrollar una aplicación de ahorro de batería mucho más personalizable. Lo principal que bash hacer primero es habilitar / deshabilitar la conexión de datos móviles a voluntad.

El problema es que no puedo encontrar fragmentos de código o artículos sobre cómo hacer esto. Lo único que he encontrado es lo siguiente. No sé qué tan preciso es esto, pero esto fue todo lo que pude armar explorando 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()); 

Si alguien puede señalarme algo que podría ayudar, sería muy apreciado.

ACTUALIZAR

Parece que el HTC Evo en Sprint no usa configuraciones APN. Probé esto descargando APNDroid y viendo que no funcionaba. Luego hice una aplicación rápida para volcar todas las entradas APN a la pantalla. Eso produjo un resultado y fue por mms.

Al ver la información del teléfono cuando JuiceDefender se está ejecutando, descubrí que la red GSRP se está activando y desactivando. Esto me hace creer que es posible hacerlo a través del código, aunque cada página que encuentro preguntando sobre este mismo tema dice que no se puede hacer. El pateador es que todos dicen que lo hagan como APNDroid. Por favor, alguien me dé una idea.

¡Gracias!

La desconexión de Dataconnection y la activación de APIS están ocultas en el SDK y no están expuestas al usuario; esto se puede lograr accediendo a la interfaz de ITelephony utilizando la técnica de reflexión de Java.

aqui tienes:

  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); 

A partir de ‘Gingerbread’ puede usar el método IConnectivityManager.setMobileDataEnabled () . Está oculto en API, pero se puede acceder con reflexión . http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/net/ConnectivityManager.java#376

Con este método puede cambiar la configuración del sistema: ‘Configuración -> Conexiones inalámbricas y red -> Configuración de red móvil -> Datos habilitados

Ejemplo de código:

 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); } 

También necesita el permiso CHANGE_NETWORK_STATE .

  

Huelga decir que este enfoque podría no funcionar en futuras versiones de Android. Pero supongo que aplicaciones como ‘3G watchdog’, ‘APNdroid’ o ‘DataLock’ funcionan de esta manera.


ACTUALIZAR :
El método setMobileDataEnabled ya no está disponible en Lollipop

Cambiar la conectividad de red de datos móviles al cambiar el nombre de la APN ya no funciona bien desde Gingerbread. Y aunque el código de reflexión es probablemente la manera correcta de hacerlo, no funcionará, porque la aplicación necesita el permiso android.permission.MODIFY_PHONE_STATE explicado por Alex P. De lo contrario, obtendrá esta desagradable excepción:

 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) 

Desafortunadamente, no puede establecer este permiso, ya que es un permiso de nivel 3 no permitido para las aplicaciones:

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

No creo que nadie tenga una forma de anular la supresión de concesión de permisos que no sea mediante el uso de firmware propio.

Creo que hay dos tipos principales de conexión de datos móviles en un dispositivo Android: WiFi y 3G / HSDPA / etc.

Y afaik deberías poder desactivar WiFi programáticamente, pero creo que las conexiones 3G / HSDPA / etc solo se pueden desactivar cambiando el nombre de la APN. La razón por la que digo esto es porque la popular aplicación APNDroid lo hace de esa manera.

Tenga en cuenta que “android.permission.MODIFY_PHONE_STATE” ya no es compatible con Android 2.3 y versiones posteriores.

¿Por qué la versión 2.3 de Android no tiene hava android.permission.MODIFY_PHONE_STATE? y cual es la solucion para esto?

para agregar un botón de alternar puedes usar este código además de la respuesta de Vladimir:

 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; } 

Esta solución de reflexión todavía funciona para mí en Android 4.0.4

@Mariux: Probablemente olvidaste agregar a AndroidManifest.xml

  final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); final Class conmanClass = Class.forName(conman.getClass().getName()); final Field connectivityManagerField = conmanClass.getDeclaredField("mService"); connectivityManagerField.setAccessible(true); final Object connectivityManager = connectivityManagerField.get(conman); final Class connectivityManagerClass = Class.forName(connectivityManager.getClass().getName()); final Method setMobileDataEnabledMethod = connectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE); setMobileDataEnabledMethod.setAccessible(true); setMobileDataEnabledMethod.invoke(connectivityManager, enabled); // pass true or false