通过编程连接和断开 Android 设备

17

我需要找到一种方法(使用Android应用程序)以编程方式连接和断开Android设备与主机的连接。

我正在使用Galaxy Nexus。我的目标是尽可能贴近原始设置,尽管我已经在内核中启用了详细的调试消息,并且为了查看它们,已经在手机上启用了root访问来访问/proc/kmsg(以及shell命令dmesg)。

我确定有一种方法可以利用root访问来做我需要做的事情,但是我所有的尝试都导致失败。

  • 玩弄/proc/bus/usb
  • 玩弄/dev/bus/usb
  • 在MTP / PTP之间切换(无法以编程方式执行)
  • 将Android USB gadget驱动程序变成模块 <- ???

我将尝试弄清楚列表中的最后一个项目,因为那样我就可以在我的应用程序中rmmodinsmod结果为*.ko的文件,从而连接和断开手机。但我不确定这个选项的可行性。


我成功将Android USB gadget驱动程序制作成一个模块,但随之而来的问题是尝试在没有内置模块的情况下运行内核。 - RyanLeonard
那么,如果您的设备有打开和关闭方法,那么使用开发人员页面作为指南,您是否可以调用这些方法来“断开”和“重新连接”您的设备?或者我可能没有完全理解您想要做什么...? - TronicZomB
如果 PTP 能够与 Android 兼容,那么你不能用它来控制吗? - user784435
我正在查看http://www.dankulp.com/ptpfs/。 - user784435
4个回答

1

解决方案在截止日期前出现,所以我几乎可以确定这不是做事情的最佳方式,但它满足了我的要求。

构建修改版内核(允许钩取特定功能)

  • 修改内核配置以支持Kprobes(将CONFIG_KPROBES设置为Y)
  • android_setup()定义中删除“static”关键字(driver/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上强制物理断开连接,然后重新连接

构建应用程序

  • 需要有root权限的设备
  • 只需使用SU权限运行shell命令:“insmod module_name”,在调用rmmod之前,该模块将强制设备进入枚举循环,不断断开和重新连接。

如果您有兴趣重复这些结果,请阅读此处发布的文档,并随时向我发送任何问题。

https://docs.google.com/uc?export=download&id=0B9WchRkSOWwJbi10MGhLWUljT2s


0

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();


0

Settings.Secure.putInt(getContentResolver(), Settings.Secure.USB_MASS_STORAGE_ENABLED, 0);

设置.安全.putInt(获取内容解析器(), 设置.安全.USB_MASS_STORAGE_ENABLED, 0);


0

您可以尝试启用/禁用一些安全设置,例如 Settings.Secure.USB_MASS_STORAGE_ENABLEDSettings.Secure.ADB_ENABLED(取决于您所说的“连接”!)

这段代码应该可以工作(禁用 USB 大容量存储):

Settings.Secure.putInt(getContentResolver(), Settings.Secure.USB_MASS_STORAGE_ENABLED, 0);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接