Программно подключить и отключить Android-устройство
Мне нужно найти способ (с помощью приложения для Android) программно подключить и отключить Android-устройство от хоста.
Я использую Galaxy Nexus. Моя цель - сохранить все как можно ближе к запасу, хотя я уже включил подробные сообщения об отладке в ядре и, чтобы их просмотреть, разрешил доступ root к телефону для доступа к /proc/kmsg
(и команде оболочки dmesg
).
Я уверен, что есть способ использовать root-доступ для выполнения того, что мне нужно сделать, но все мои попытки привели к nix.
- Беспорядок с
/proc/bus/usb
- Беспорядок с
/dev/bus/usb
- Изменение между MTP/PTP (неспособное делать программно)
- Включение драйвера гаджета Android USB в модуль < -???
Я попытаюсь выяснить, как сделать последний объект в списке, так как тогда я смог бы rmmod
и insmod
результирующий *.ko
в моем приложении, и это будет подключать и отключать Телефон. Однако я не уверен в возможности этого варианта.
Ответы
Ответ 1
Решение приблизилось к предельному сроку, поэтому я почти уверен, что это не лучший способ сделать что-то, но он соответствовал моим требованиям.
Build Modded kernel (чтобы разрешить привязку определенной функции)
- Измените конфигурацию ядра для поддержки Kprobes (установите CONFIG_KPROBES на Y)
- Удалите ключевое слово static из определения android_setup() (драйвер/usb/gadget/android.c)
- Построить это ядро
Создайте модуль ядра (который дает фактическую функциональность подключения и отключения)
- Используйте Kallsyms для динамического вытягивания абсолютного адреса android_setup()
- Используя kprobes, перетащите android_setup()
- Настройте два таймера для выполнения каждый раз, когда вызывается функция android_setup()
- Первый таймер установлен на 2 секунды, второй установлен на 2.005 секунд.
- Оба таймера берут указатель на struct usb_gadget как свои данные
- В соответствующих функциях обратного вызова вызовите usb_gadget_connect() и usb_gadget_disconnect(), что вынудит физическое отсоединение, а затем повторно подключиться к Samsung Galaxy Nexus
Сборка приложения
- Должен иметь внедренное устройство
- Просто сделайте вызов оболочки с SU-привилегией - "insmod module_name". Пока вы не назовете rmmod, модуль заставит устройство перейти в цикл перечисления, непрерывно отключая и снова подключаясь.
Если вы заинтересованы в повторении этих результатов, прочитайте документ, размещенный здесь, и не стесняйтесь присылать мне какие-либо вопросы.
https://docs.google.com/uc?export=download&id=0B9WchRkSOWwJbi10MGhLWUljT2s
Ответ 2
Вы можете попытаться включить/отключить некоторые защищенные настройки, такие как Settings.Secure.USB_MASS_STORAGE_ENABLED
или Settings.Secure.ADB_ENABLED
(в зависимости от того, что вы называете "connect"!)
Этот код должен работать (отключая запоминающее устройство USB):
Settings.Secure.putInt(getContentResolver(),Settings.Secure.USB_MASS_STORAGE_ENABLED, 0);
Ответ 3
Настройки .Secure.putInt(getContentResolver(), Settings.Secure.USB_MASS_STORAGE_ENABLED, 0);
Ответ 4
InternetControl.java
public class InternetControl {
public static void EnableInternet(Context context)
{
try {
Log.i("Reached Enable", "I am here");
setMobileDataEnabled(context,true);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static void DisableInternet(Context context)
{
try {
Log.i("Reached Disable", "I am here");
setMobileDataEnabled(context,false);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private static void setMobileDataEnabled(Context context , boolean enabled) throws Exception{
final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final Class connClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = connClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conn);
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
}
}
manifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
Включить или отключить функцию статичны, чтобы вы могли звонить с помощью
classname.functionname();