Отключить / Включить мобильные данные на Android L с корневым доступом

Я пишу небольшое приложение, которое только я буду использовать, и я хочу прагматично включить / отключить свои мобильные данные на корневом устройстве Android 4.5 (я запускаю пользовательский Android L для Nexus 4).

Я искал какое-то время, и я нашел методы с отражением, которые работали до Android 4.3. Я также видел метод из этого сообщения. Переключайте мобильные данные программно на Android 4.4.2, но для этого требуется cyanogenmod.

Из того, что я могу найти в Интернете, это невозможно для приложений без полномочий root, но мой вопрос:

Есть ли что-то, что я могу сделать с моими привилегиями root для этого?

Я создал этот метод, оглядываясь по интернету; Он отлично работает на укоренившемся Android-версии 5.0.1. В основном вам нужно передать true, если вы хотите, чтобы соединение было включено, false в противном случае и контекст вашего приложения.

private final static String COMMAND_L_ON = "svc data enable\n "; private final static String COMMAND_L_OFF = "svc data disable\n "; private final static String COMMAND_SU = "su"; public static void setConnection(boolean enable,Context context){ String command; if(enable) command = COMMAND_L_ON; else command = COMMAND_L_OFF; try{ Process su = Runtime.getRuntime().exec(COMMAND_SU); DataOutputStream outputStream = new DataOutputStream(su.getOutputStream()); outputStream.writeBytes(command); outputStream.flush(); outputStream.writeBytes("exit\n"); outputStream.flush(); try { su.waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } outputStream.close(); }catch(IOException e){ e.printStackTrace(); } } 

Сообщайте, есть ли проблемы на каком-либо устройстве.

EDIT : теперь также совместим с android 5.1 Credit

Использовать это

 TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); Method methodSet = tm.class.getDeclaredMethod( "setDataEnabled", boolean.class); methodSet.invoke(tm, true); 

Изменить: для этого требуется разрешение MODIFY_PHONE_STATE , это разрешение на уровне системы или уровня MODIFY_PHONE_STATE .

В идеале вы можете создать исполняемый файл jar с этим кодом и выполнить его, используя

 export CLASSPATH=<jar path> exec app_process <jar-dir-path> your.package.name.classname "$@" 

Из su оболочка.

Я заметил, что метод вызова службы не работает последовательно на всех устройствах. Номер, который будет использоваться в нем, варьируется от устройства к устройству.

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

Просто выполните следующее через su

Чтобы включить мобильные данные

 svc data enable 

Отключение мобильных данных

 svc data disable 

Это так просто.

 void turnData(boolean ON) throws Exception { int currentapiVersion = android.os.Build.VERSION.SDK_INT; if(currentapiVersion == Build.VERSION_CODES.FROYO) { Log.i("version:", "Found Froyo"); try{ Method dataConnSwitchmethod; Class telephonyManagerClass; Object ITelephonyStub; Class ITelephonyClass; TelephonyManager telephonyManager = (TelephonyManager) cx.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); 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 (ON) { dataConnSwitchmethod = ITelephonyClass.getDeclaredMethod("enableDataConnectivity"); } else { dataConnSwitchmethod = ITelephonyClass.getDeclaredMethod("disableDataConnectivity"); } dataConnSwitchmethod.setAccessible(true); dataConnSwitchmethod.invoke(ITelephonyStub); }catch(Exception e){ Log.e("Error:",e.toString()); } } else { Log.i("version:", "Found Gingerbread+"); final ConnectivityManager conman = (ConnectivityManager) cx.getApplicationContext().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, ON); } }