44 votes

Comment désactiver les données mobiles sur Android

Une brève histoire avant que quelqu'un ne me dise d'acheter une application. =)

Je viens d'avoir un EVO et il consomme la batterie assez rapidement. J'ai téléchargé JuiceDefender pour gérer ma connexion de données mobiles. Cela semble avoir fonctionné assez bien. Cependant, les paramètres sont très limités (même sur les versions payantes).

Pour l'instant, j'essaie de développer une application d'économie de batterie beaucoup plus personnalisable. La principale chose que j'essaie de faire est de pouvoir activer/désactiver la connexion de données mobiles à volonté.

Le problème est que je ne trouve aucun extrait de code ou article sur la façon de procéder. La seule chose que j'ai trouvée est la suivante. Je ne sais pas si cela est exact, mais c'est tout ce que j'ai pu trouver en parcourant 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 quelqu'un peut m'indiquer quelque chose qui pourrait m'aider, ce serait très apprécié.

UPDATE

Il semble que le HTC Evo sur Sprint n'utilise pas les paramètres APN. J'ai testé cela en téléchargeant APNDroid et en le regardant ne pas fonctionner. J'ai ensuite créé une application rapide pour afficher toutes les entrées APN à l'écran. Cela a donné un résultat et c'était pour les mms.

En regardant les informations du téléphone lorsque JuiceDefender est en cours d'exécution, j'ai constaté que le réseau GSRP est allumé et éteint. Cela me laisse croire qu'il est possible de le faire par code, même si toutes les pages que je trouve sur ce même sujet disent que c'est impossible. Le problème est qu'ils disent tous de le faire comme APNDroid. S'il vous plaît, que quelqu'un me donne son avis.

Gracias.

73voto

Vladimir Sorokin Points 842

À partir de "Gingerbread", vous pouvez utiliser la fonction IConnectivityManager.setMobileDataEnabled() méthode. Elle est cachée dans l'API, mais on peut y accéder avec réflexion . http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.Android/Android/2.2_r1.1/Android/net/ConnectivityManager.java#376

Cette méthode vous permet de modifier les paramètres du système : Paramètres -> Sans fil et réseau -> Paramètres du réseau mobile -> Données activées '

Exemple de code :

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

Vous avez également besoin de la CHANGE_NETWORK_STATE permission.

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

Inutile de dire que cette approche pourrait ne pas fonctionner dans les futures versions d'Android. Mais je suppose que des applications telles que '3G watchdog', 'APNdroid' ou 'DataLock' fonctionnent de cette manière.


UPDATE :
la méthode setMobileDataEnabled n'est plus disponible sur Lollipop

0 votes

La 3G ne reste pas activée lorsque le WiFi est activé, dans mon vrai téléphone. Elle s'allume brièvement puis s'éteint. Comment faire pour qu'elle reste allumée ?

1 votes

InvocationTargetException en 2.2.1

0 votes

Java.lang.IllegalArgumentException : expected receiver of type Android.net.IConnectivityManager$Stub$Proxy, but got java.lang.Class<Android.net.IConnectivityManager$Stub$Proxy>. Que puis-je faire ?

39voto

Vinay Points 344

La désactivation de la connexion de données et l'activation de l'APIS sont cachées dans le SDK et ne sont pas exposées à l'utilisateur, ce qui peut être réalisé en accédant à l'interface ITelephony à l'aide de la technique de réflexion Java.

voilà :

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

3 votes

Cela ne fonctionne pas sur Gingerbread 2.3+ : stackoverflow.com/questions/4715250/

1 votes

La solution ci-dessus de phaniKumar exige également <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/> déclaré dans AndroidManifest.xml . Sans la permission, vous obtiendrez un InvocationTargetException erreur lancée.

2 votes

J'ai essayé le code ci-dessus... il me donne java.lang.SecurityException : Ni l'utilisateur 10126 ni le processus actuel n'ont la permission Android.permission.MODIFY_PHONE_STATE... Lorsque j'inclus <uses-permission Android:name="Android.permission.MODIFY_PHONE_STATE"/> dans le manifeste, j'obtiens l'erreur "Permission is only granted to system apps"...n'y a-t-il pas un autre moyen d'accéder à cette fonctionnalité ? ?

4voto

Z80 Points 31

Changer la connectivité du réseau de données mobiles en changeant le nom de l'APN ne fonctionne plus très bien depuis Gingerbread. Et bien que le code de réflexion soit probablement la bonne façon de faire, il ne fonctionnera pas, car l'application a besoin de la permission Android.permission.MODIFY_PHONE_STATE comme expliqué par Alex P. Sinon, vous obtenez cette exception désagréable :

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)

Malheureusement, vous ne pouvez pas définir cette autorisation, car il s'agit d'une autorisation de niveau 3 non autorisée pour les applications :

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

Je suppose que personne n'a un moyen de passer outre la suppression de l'octroi de permission autrement qu'en utilisant son propre firmware.

3voto

Telmo Marques Points 3397

Je pense qu'il existe deux principaux types de connexion de données mobiles sur un appareil Android : WiFi et 3G/HSDPA/etc.

Et je crois que vous devriez pouvoir désactiver le WiFi de manière programmatique, mais je pense que les connexions 3G/HSDPA/etc ne peuvent être désactivées qu'en changeant le nom de l'APN. La raison pour laquelle je dis cela est que l'application populaire APNDroid le fait de cette façon.

0 votes

Merci beaucoup. En regardant le code d'APNDroid, il semble que ce soit ce qui se passe. J'ai pensé que je pouvais juste retourner un peu. Eh bien, hehe.

0 votes

Explosion ! J'ai téléchargé l'application, mais il semble qu'elle ne fonctionne pas pour l'Evo 4G.

3voto

Muzikant Points 31

Notez que "Android.permission.MODIFY_PHONE_STATE" n'est plus supporté pour Android 2.3 et plus.

Pourquoi la version 2.3 d'Android ne dispose pas de Android.permission.MODIFY_PHONE_STATE ? et quelle est la solution ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X