Как отключить мобильные данные на 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. Пожалуйста, дайте мне некоторое представление.
Спасибо!
Ответы
Ответ 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.
Ответ 5
Обратите внимание, что "Android-версия .MODIFY_PHONE_STATE" больше не поддерживается для Android 2.3 и выше.
почему 2.3 версия андроида не hava android.permission.MODIFY_PHONE_STATE? и каково решение для этого?
Ответ 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