Как отключить мобильные данные на Android - PullRequest
44 голосов
/ 05 сентября 2010

Быстрая история, прежде чем кто-то скажет мне купить приложение. =) * * Тысяча одна

Я только что получил 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 on Sprint не использует настройки APN. Я проверил это, загрузив APNDroid и наблюдая, как он не работает. Затем я сделал быстрое приложение, чтобы вывести все записи APN на экран. Это дало один результат, и это было для ммс.

Просматривая информацию о телефоне, когда JuiceDefender работает, я обнаружил, что сеть GSRP включается и выключается. Это оставляет меня верить, что это можно сделать с помощью кода, даже если на каждой странице, на которой я спрашиваю об этой же проблеме, написано, что это невозможно. Кикер, они все говорят, что делают это как APNDroid. Пожалуйста, кто-нибудь, дайте мне немного понимания.

Спасибо!

Ответы [ 8 ]

73 голосов
/ 22 января 2012

Начиная с 'Gingerbread', вы можете использовать метод 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 watchdog», «APNdroid» или «DataLock» работают таким образом.


UPDATE
Метод setMobileDataEnabled больше не доступен в Lollipop

38 голосов
/ 29 ноября 2010

Отключение и включение APIS Dataconnection скрыты в SDK и не предоставляются пользователю, этого можно достичь, получив доступ к интерфейсу ITelephony с использованием техники отражения Java.

здесь вы идете:

    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);
4 голосов
/ 19 марта 2011

Переключение подключения к мобильной сети передачи данных путем изменения имени APN больше не работает со времен Gingerbread. И хотя код отражения, вероятно, является правильным способом решения этой проблемы, он не будет работать, поскольку приложению необходимо разрешение 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)

Я не думаю, что у кого-либо есть способ переопределить подавление разрешения доступа, кроме как с помощью собственной прошивки.

3 голосов
/ 27 июня 2012

чтобы добавить кнопку-переключатель, вы можете использовать этот код дополнительно. Ответ Владимира:

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

3 голосов
/ 18 апреля 2011

Обратите внимание, что "android.permission.MODIFY_PHONE_STATE" больше не поддерживается для Android 2.3 и более поздних версий.

почему версия 2.3 android не имеет android.permission.MODIFY_PHONE_STATE?и какое решение для этого?

3 голосов
/ 05 сентября 2010

Я думаю, что есть два основных типа мобильной передачи данных на устройстве Android: WiFi и 3G / HSDPA / и т. Д.

И, кстати, вы сможете программно отключить WiFi, но я думаю, что соединения 3G / HSDPA / etc можно отключить только путем изменения имени APN. Я говорю об этом потому, что популярное приложение APNDroid делает это так.

0 голосов
/ 15 июня 2018
    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
0 голосов
/ 15 февраля 2011

@ Mariux: Вы, вероятно, забыли добавить <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> в AndroidManifest.xml

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...