Подтвердить что ты не робот

Как отключить мобильные данные на Android

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

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

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

Спасибо!

4b9b3361

Ответ 1

Отключение и включение 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);

Ответ 2

Начиная с "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. Но я думаю, что такие приложения, как "Watchdog 3G", "APNdroid" или "DataLock", работают таким образом.


UPDATE:
setMobileDataEnabled метод больше не доступен на Lollipop

Ответ 3

Переключение мобильной сети передачи данных путем изменения имени 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)

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

Ответ 4

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

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

Ответ 6

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

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

Ответ 7

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