La méthode setMobileDataEnabled ne est plus appelable que d'Android L et plus tard

? ChuongPham @ | Original: StackOverFlow

Je ai connecté https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=78084 avec Google concernant la méthode setMobileDataEnabled() ne étant plus appelable par réflexion . Ce était appelable depuis Android 2.1 ( API 7 ) à Android 4.4 ( API 19 ) par réflexion, mais comme d'Android L et plus tard, même avec la racine, la méthode setMobileDataEnabled() ne est pas appelable .

La réponse officielle est que la question est " fermé " et le statut réglé sur " WorkingAsIntended " . Explication simple de Google est :

API privées ont parce qu'ils ne sont pas stables et pourraient disparaître sans préavis .

Oui, Google, nous sommes conscients du risque d' utiliser la réflexion pour appeler caché méthodologie avant même l'entrée Android sur la scène-, mais vous devez fournir une réponse plus solide que des solutions de rechange, le cas échéant, pour accomplir le même résultat que "____ ». ( Si vous êtes mécontent de la décision de Google que je suis, puis connectez-vous en https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=78084 et Star, il autant que possible de laisser Google sait l'erreur de leur chemin. )

Donc, ma question est : Sommes-nous dans une impasse quand il se agit d'activer ou de désactiver la fonction de réseau mobile sur un périphérique Android programmation? Cette approche musclée de Google en quelque sorte ne pas très bien avec moi. Si vous avez solution de contournement pour Android 5.0 ( Lollipop ) et au-delà, je aimerais entendre votre réponse / discussion dans ce fil.

Je ai utilisé le code ci-dessous pour voir si le setMobileDataEnabled() une méthode est disponible :

setMobileDataEnabled()

Mais ce ne est pas .

MISE À JOUR: Actuellement, il est possible de basculer réseau mobile si le dispositif est enraciné . Toutefois, pour les appareils non - enracinée, ce est toujours un processus d'enquête qu'il n'y a pas de méthode universelle pour basculer réseau mobile .



Top 5 Respuesta

1Muzikant @

Juste pour partager un peu plus d'idées et solution possible ( pour les appareils enracinées et applications du système ) .

Solution #1

Il semble que le final Class<?> conmanClass = Class.forName(context.getSystemService(Context.CONNECTIVITY_SERVICE).getClass().getName()); final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService"); iConnectivityManagerField.setAccessible(true); final Object iConnectivityManager = iConnectivityManagerField.get(context.getSystemService(Context.CONNECTIVITY_SERVICE)); final Class<?> iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName()); final Method[] methods = iConnectivityManagerClass.getDeclaredMethods(); for (final Method method : methods) { if (method.toGenericString().contains("set")) { Log.i("TESTING", "Method: " + method.getName()); } } méthode ne existe plus dans «____» et cette fonctionnalité a été déplacé à setMobileDataEnabled avec deux méthodes ConnectivityManager et TelephonyManager . Je ai essayé d'appeler ces méthodes avec la réflexion que vous pouvez voir dans le code ci-dessous :

getDataEnabled

Lors de l'exécution du code vous obtenez un setDataEnabled indiquant que public void setMobileDataState(boolean mobileDataEnabled) { try { TelephonyManager telephonyService = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); Method setMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("setDataEnabled", boolean.class); if (null != setMobileDataEnabledMethod) { setMobileDataEnabledMethod.invoke(telephonyService, mobileDataEnabled); } } catch (Exception ex) { Log.e(TAG, "Error setting mobile data state", ex); } } public boolean getMobileDataState() { try { TelephonyManager telephonyService = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); Method getMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("getDataEnabled"); if (null != getMobileDataEnabledMethod) { boolean mobileDataEnabled = (Boolean) getMobileDataEnabledMethod.invoke(telephonyService); return mobileDataEnabled; } } catch (Exception ex) { Log.e(TAG, "Error getting mobile data state", ex); } return false; }

Donc, oui ce est un projet de modification de l'API interne et ne est plus disponible pour les applications qui utilisaient que bidouille dans les versions précédentes .

( commencer diatribe : que l'autorisation de android.permission.MODIFY_PHONE_STATE terrible ... diatribe de fin) .

Les bonnes nouvelles sont que si vous construisez une application qui peut acquérir la permission de MODIFY_PHONE_STATE (seulement applications système peuvent utiliser que ), vous pouvez utiliser le code ci-dessus pour alterner la condition de données mobile.

Solution #2

Pour vérifier l'état actuel des données mobile, vous pouvez utiliser le champ SecurityException de Neither user 10089 nor current process has android.permission.MODIFY_PHONE_STATE. ( non documenté dans la documentation officielle ) .

mobile_data

Et pour activer / désactiver les données mobile, vous pouvez utiliser des commandes shell sur les appareils enracinées ( tests Juste base effectuée de façon tout commentaire dans les commentaires est apprécié ) . Vous pouvez exécuter la commande (s ) suivante en tant que root ( 1 = permettent, 0 = désactivé ) :

Settings.Global


2ChuongPham @

Pour prolonger Solution N ° 2 Muzikant, quelqu'un peut-il se il vous plaît essayer la solution ci-dessous sur une 5,0 périphérique enracinée Android ( comme je ne possède actuellement l'un ) et laissez -moi savoir si cela fonctionne ou ne fonctionne pas .

Pour activer ou désactiver les données mobiles, essayez :

Settings.Global.getInt(contentResolver, "mobile_data");

Remarque: Le settings put global mobile_data 1 settings put global mobile_data 0 variable peut être trouvé dans Android API 21 codes sources au «____» et est déclaré comme suit:

// 1: Enable; 0: Disable
su -c settings put global mobile_data 1
su -c am broadcast -a android.intent.action.ANY_DATA_STATE --ez state 1

Alors que le mobile_data L'intention peut être trouvé dans l'API Android 21 codes sources au «____» et est déclaré comme suit:

/android-sdk/sources/android-21/android/provider/Settings.java

UPDATE 1 : Si vous ne voulez pas mettre en œuvre les codes Java ci-dessus dans votre application Android, alors vous pouvez exécuter le /** * Whether mobile data connections are allowed by the user. See * ConnectivityManager for more info. * @hide */ public static final String MOBILE_DATA = "mobile_data"; commandes via un shell ( Linux ) ou de l'invite de commande (Windows ) comme suit :

android.intent.action.ANY_DATA_STATE

Note: /android-sdk/sources/android-21/com/android/internal/telephony/TelephonyIntents.java est situé à répertoire /** * Broadcast Action: The data connection state has changed for any one of the * phone's mobile data connections (eg, default, MMS or GPS specific connection). * * <p class="note"> * Requires the READ_PHONE_STATE permission. * <p class="note">This is a protected intent that can only be sent by the system. * */ public static final String ACTION_ANY_DATA_CONNECTION_STATE_CHANGED = "android.intent.action.ANY_DATA_STATE"; . La commande su est pris en charge uniquement sur ​​Android 4.2 ou ultérieure . Ancienne version Android sera signaler une erreur adb shell "su -c 'settings put global mobile_data 1; am broadcast -a android.intent.action.ANY_DATA_STATE --ez state 1'" .

UPDATE 2 : Une autre façon de basculer réseau mobile sur un 5+ appareil Android enracinée serait d'utiliser le adb commande shell sans-papiers . La commande suivante peut être exécutée par l'intermédiaire de la BAD pour basculer réseau mobile :

/android-sdk/platform-tools/

Or just:

settings

Note: "sh: settings: not found" est situé à répertoire service . Si vous ne souhaitez pas utiliser la BAD, exécuter la méthode via // 1: Enable; 0: Disable adb shell "su -c 'service call phone 83 i32 1'" dans votre application .

3rgruet @

Solution n ° 1 de Muzikant semble fonctionner si vous faites le «système» de l'application en déplaçant le .apk dans le dossier // 1: Enable; 0: Disable adb shell service call phone 83 i32 1 , pas à la adb une ( jaumard : peut-être ce est pourquoi votre test n'a pas fonctionné ) .

Lorsque le .apk est dans le dossier /android-sdk/platform-tools/, il peut demander au succès terrible su permission dans le manifeste et appeler «____» et «____» .

Au moins qui fonctionne sur Nexus 5 / Android 5.0 . Les perms .apk sont «____» . Vous devez redémarrer l'appareil pour que la modification soit prise en compte, peut-être cela pourrait être évité - voir http://stackoverflow.com/questions/26487750/android-5-0-lollipop-force-rescan-of-system- priv -app .

4Sahil Lombar @

Pour corriger Muzikant Solution # 2

/system/priv-app/

Ne permet que la bascule pour les données mobiles, mais ne fait rien pour la connectivité . Seule la bascule est activée. Afin d'obtenir les données de travail à l'aide

/system/app/

Donne erreur comme le supplément pour

/system/priv-app/

Nécessite cordes objet tout paramètre --ez est utilisé pour booléenne . Réf : PhoneGlobals.java & amp; PhoneConstants.java . Après l'utilisation de la connexion ou monté en utilisant la commande supplémentaire

android.permission.MODIFY_PHONE_STATE

Ne marche pas toujours faire quelque chose pour que les données .