Die setMobileDataEnabled Verfahren ist nicht mehr aufrufbar, wie der Android L und später

? ChuongPham @ | Original: StackOverFlow

Ich habe eingeloggt 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 mit Google in Bezug auf die Methode setMobileDataEnabled() als durch Reflexion nicht mehr aufrufbar . Es war abrufbare seit Android 2.1 (API 7) 4,4 (API 19) über Reflexion auf Android, aber ab Android L und später sogar mit Root ist die Methode setMobileDataEnabled() nicht aufrufbar .

Die offizielle Antwort ist, dass die Frage "Zu" und der Status auf " WorkingAsIntended " gesetzt. Googles einfache Erklärung :

Privat APIs sind private, weil sie nicht stabil und könnte ohne vorherige Ankündigung zu verschwinden.

Ja, Google, sind wir uns des Risikos mithilfe von Reflektion zu nennen versteckt Methoden-, noch bevor Android kam auf die Szene- aber Sie müssen eine solidere Antwort, Alternativen zur Ausführung das gleiche Ergebnis wie " stellen, falls vorhanden, ____" . (Wenn Sie mit Googles Entscheidung unzufrieden sind, wie ich bin, dann melden Sie sich in 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 und Stern es so viele wie möglich zu lassen Google kennen die Fehler aus dem Weg . )

Also, meine Frage an Sie ist : Sind wir in einer Sackgasse, wenn es um programmgesteuert zu aktivieren oder zu deaktivieren mobilen Netzwerkfunktion auf einem Android- Gerät kommt ? Diese plumpe Ansatz von Google irgendwie nicht gut mit mir . Wenn Sie Workaround für Android 5.0 ( Lutscher ) und darüber hinaus, würde ich gerne Ihre Antwort / Diskussion zu diesem Thema zu hören.

Ich habe den folgenden Code verwendet werden, um festzustellen, ob die setMobileDataEnabled() Verfahren zur Verfügung :

setMobileDataEnabled()

Aber es ist nicht .

UPDATE : Derzeit ist es möglich, Mobilnetz umzuschalten, wenn das Gerät verwurzelt. Jedoch für nicht verwurzelt Geräte, es ist immer noch ein Untersuchungsverfahren, da es keine universelle Methode zum Mobilfunknetz wechseln.

Top 5 Antwort

1Muzikant @

Nur um zu teilen sich ein paar Erkenntnisse und mögliche Lösung (zum verwurzelt Geräte und System -Anwendungen) .

Solution #1

Es scheint, wie die 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()); } } -Methode nicht mehr in setMobileDataEnabled vorhanden ist, und diese Funktionalität wurde zu ConnectivityManager mit zwei Methoden TelephonyManager und getDataEnabled verschoben. Ich habe versucht, den Aufruf dieser Methoden mit der Reflexion, wie Sie im folgenden Code sehen können :

setDataEnabled

Bei der Ausführung der Code, den Sie erhalten eine 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; } besagt, dass SecurityException

Also, ja das ist eine geplante Veränderung des internen API und ist nicht mehr verfügbar, um Anwendungen, die diesen Hack in früheren Versionen verwendet .

(Start rant : dass schreckliche android.permission.MODIFY_PHONE_STATE Erlaubnis ... Ende rant ) .

Die gute Nachricht ist, dass, wenn Sie bauen eine App, die MODIFY_PHONE_STATE Genehmigung (nur System Apps verwenden können, ) erwerben können, können Sie den obigen Code zu verwenden, um mobile Daten Zustand umzuschalten.

Solution #2

Um aktuellen Stand der mobilen Daten zu überprüfen können Sie das Feld Neither user 10089 nor current process has android.permission.MODIFY_PHONE_STATE. von mobile_data ( nicht in den offiziellen Unterlagen dokumentiert ) verwenden .

Settings.Global

Und aktivieren / deaktivieren Sie die mobile Daten Shell-Befehle auf verwurzelt Geräte verwenden können ( nur grundlegende Tests durchgeführt, um jedes Feedback in den Kommentaren geschätzt wird ) . Sie können den folgenden Befehl ein (e) als root ( 1 = aktiviert, 0 = deaktiviert ) ausgeführt :

Settings.Global.getInt(contentResolver, "mobile_data");
2ChuongPham @

So verlängern Muzicant die Lösung 2, kann jemand versuchen Sie bitte die unten Lösung auf einem Android- 5.0 verwurzelt Gerät (wie ich im Moment nicht ein besitzen ), und lassen Sie mich wissen, ob es funktioniert oder nicht funktioniert .

So aktivieren oder deaktivieren Sie die mobile Daten, versuchen Sie :

settings put global mobile_data 1
settings put global mobile_data 0

Hinweis: Die // 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 Variable kann in Android API 21 Quellcodes auf mobile_data gefunden werden und wird als deklariert :

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

Während die /** * Whether mobile data connections are allowed by the user. See * ConnectivityManager for more info. * @hide */ public static final String MOBILE_DATA = "mobile_data"; Intent kann in Android API 21 Quellcodes auf android.intent.action.ANY_DATA_STATE gefunden werden und wird als deklariert :

/android-sdk/sources/android-21/com/android/internal/telephony/TelephonyIntents.java

UPDATE 1: Wenn Sie nicht möchten, dass die oben genannten Java -Codes in Ihrem Android- Anwendung zu implementieren, dann können Sie diese mit /** * 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"; Befehle über eine Shell (Linux) oder Eingabeaufforderung (Windows) wie folgt:

su

Hinweis: adb shell "su -c 'settings put global mobile_data 1; am broadcast -a android.intent.action.ANY_DATA_STATE --ez state 1'" am Verzeichnis adb entfernt. Der Befehl /android-sdk/platform-tools/ wird nur auf Android 4.2 oder höher unterstützt. Ältere Android-Version wird einen Fehler settings Bericht zu erstatten.

UPDATE 2: Eine weitere Möglichkeit, Mobilnetz auf einer verwurzelt Android 5+ Gerät zu wechseln wäre, die ohne Papiere "sh: settings: not found" Shell-Befehl zu verwenden. Mit dem folgenden Befehl kann über ADB ausgeführt, um Mobilfunknetz umgeschaltet werden :

service

Or just:

// 1: Enable; 0: Disable
adb shell "su -c 'service call phone 83 i32 1'"

Hinweis: // 1: Enable; 0: Disable adb shell service call phone 83 i32 1 am Verzeichnis adb entfernt. Wenn Sie nicht möchten, dass ADB verwenden, führen Sie die Verfahren über /android-sdk/platform-tools/ in Ihrer Anwendung .

3rgruet @

Lösung 1 von Muzicant scheint zu funktionieren, wenn Sie die App "System", indem der APK in den Ordner su, nicht auf die /system/priv-app/ zu machen ( jaumard : vielleicht ist das, warum Ihr Test nicht funktioniert ) .

Wenn der APK ist im Ordner /system/app/, kann es erfolgreich beantragen die schreckliche /system/priv-app/ Genehmigung im Manifest und rufen android.permission.MODIFY_PHONE_STATE und TelephonyManager.setDataEnabled .

Mindestens die auf Nexus 5 / Android 5.0 funktioniert. Die APK- Dauerwellen sind TelephonyManager.getDataEnabled . Sie müssen das Gerät neu zu starten, damit die Änderungen berücksichtigt werden, vielleicht könnte dies vermieden werden - siehe http://stackoverflow.com/questions/26487750/android-5-0-lollipop-force-rescan-of-system- priv - App .

4Sahil Lombar @

Zur Korrektur Muzicant Lösung 2

0144

Hat ermöglichen nur den Schalter für die mobile Daten aber tut nichts, um die Konnektivität. Nur der Knebel aktiviert . Um die Daten arbeitet mit bis zu

settings put global mobile_data 1

Gibt Fehler wie die extra

su -c am broadcast -a android.intent.action.ANY_DATA_STATE --ez state 1

Erfordert String -Objekt, während --ez Parameter für boolean verwendet . Ref: PhoneGlobals.java & amp; PhoneConstants.java . Nach der Verwendung von Anschluss oder als Extra mit dem Befehl verbunden

android.intent.action.ANY_DATA_STATE

Noch tut nichts, um die Daten zu ermöglichen.