返回

安卓设备USB仅识别“无数据传输”模式?C# LibUsbDotNet连接问题解决

Android

安卓设备只能在“无数据传输”模式下被电脑识别?排查与解决之道

最近在用 C# 开发一个应用,需要通过批量端点传输(Bulk Endpoint Transfer)向安卓设备(平板)发送数据。遇到的一个怪事是,我的平板设置了 USB 用于“无数据传输”,并且打开了开发者选项和 USB 调试,只有这样才能在 Windows 的设备列表中看到它,选其他选项压根就不显示设备。

目前尝试了 LibUsbDotNet 文档中的 Bulk Read/Write 示例。读取持续失败,抛出 “Read failed:ErrorPipe”。

更奇怪的是, 除了“无数据传输”模式,其他任何模式下都无法显示设备,如下方所示的代码:

 public static void Main(string[] args)
 {
     UsbRegDeviceList allDevices = UsbDevice.AllDevices;
     foreach (UsbRegistry usbRegistry in allDevices)
     {
         if (usbRegistry.Open(out MyUsbDevice))
         {
             Console.WriteLine(MyUsbDevice.Info.ToString());
             for (int iConfig = 0; iConfig < MyUsbDevice.Configs.Count; iConfig++)
             {
                 UsbConfigInfo configInfo = MyUsbDevice.Configs[iConfig];
                 Console.WriteLine(configInfo.ToString());

                 ReadOnlyCollection<UsbInterfaceInfo> interfaceList = configInfo.InterfaceInfoList;
                 for (int iInterface = 0; iInterface < interfaceList.Count; iInterface++)
                 {
                     UsbInterfaceInfo interfaceInfo = interfaceList[iInterface];
                     Console.WriteLine(interfaceInfo.ToString());

                     ReadOnlyCollection<UsbEndpointInfo> endpointList = interfaceInfo.EndpointInfoList;
                     for (int iEndpoint = 0; iEndpoint < endpointList.Count; iEndpoint++)
                     {
                         Console.WriteLine(endpointList[iEndpoint].ToString());
                     }
                 }
             }
         }
     }

设备使用 ADB 接口,一开始我觉得这可能是问题所在,但现在有点搞不清问题到底出在哪儿,也不知道该怎么解决或绕过这个问题。

问题原因分析

这种情况可能由多种原因导致,下面列出几种可能性:

  1. 驱动问题: 即使打开了 USB 调试,Windows 可能没有正确安装或识别安卓设备的驱动。ADB 接口有时需要特定的驱动程序才能进行除调试之外的数据传输。

  2. USB 模式限制: 某些安卓设备制造商或 ROM 对 USB 模式做了限制,可能阻止了在非“无数据传输”模式下进行批量端点传输。

  3. LibUsbDotNet 库的兼容性问题: LibUsbDotNet 可能与特定安卓设备或其使用的 USB 控制器存在兼容性问题。或者库的使用方式上有不正确的地方。

  4. 安卓设备的安全设置: 安卓设备的安全设置,例如权限、USB 调试授权等,可能会影响数据传输。

  5. 硬件问题 极少的情况下是由于USB线或者接口的问题引起的。

解决方案

针对上述可能的原因,可以尝试以下解决方案:

1. 检查和更新驱动程序

Windows 系统可能没有正确的安卓设备驱动,或者驱动程序需要更新。

  • 手动更新驱动程序:
    1. 在 Windows 设备管理器中找到安卓设备(可能显示为带有黄色感叹号的未知设备或 ADB Interface)。
    2. 右键单击设备,选择“更新驱动程序”。
    3. 选择“浏览我的计算机以查找驱动程序软件”。
    4. 选择“让我从计算机上的可用驱动程序列表中选取”。
    5. 选择 "Android Device" 或 "Android ADB Interface".
    6. 如果之前安装过 Google USB Driver,则应该可以在这里找到。 如果不行,尝试手动安装。
    7. 完成驱动安装。
  • 安装 Google USB Driver:
    如果以上不成功, 直接安装Google 官方 USB Driver:
    1. 打开 Android SDK 管理器。
    2. 在 "Extras" 目录下找到 "Google USB Driver", 安装.
    3. 安装完成后,重复手动安装步骤。驱动路径:<sdk>\extras\google\usb_driver ( <sdk>是 SDK 安装路径)。
  • 安全建议: 从可信来源(例如 Google 或设备制造商)下载驱动程序。

2. 确认 USB 调试授权

确保已在安卓设备上授权计算机进行 USB 调试。

  • 重新插拔 USB 连接: 重新连接设备时,注意安卓设备上的 USB 调试授权提示。
  • 撤销 USB 调试授权:
    1. 进入安卓设备的“开发者选项”。
    2. 点击“撤销 USB 调试授权”。
    3. 重新连接设备,并在弹出的提示中选择“始终允许”。

3. 尝试不同的 USB 端口和数据线

排除硬件连接问题,换个 USB 口或者线再试试。

  • 使用电脑上的其他 USB 端口(最好是 USB 3.0 或更高版本)。
  • 更换一条已知良好的 USB 数据线(确保数据线支持数据传输,而不是仅充电)。

4. 检查并修改 LibUsbDotNet 代码

仔细审查 LibUsbDotNet 的代码,特别是设备选择和端点配置部分,排查代码问题。

  • 验证 Vendor ID 和 Product ID:

    • 确保代码中使用的 Vendor ID 和 Product ID 与安卓设备匹配。可通过查看Windows 设备管理器 -> 安卓设备详情 -> 硬件ID。
    • 在 LibUsbDotNet 中,通常使用 UsbDeviceFinder 来查找设备:
      UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(vendorId, productId); // 替换为实际的 ID
      MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
      
  • 明确指定接口和端点:

    • ADB接口往往只支持ADB协议,对于Bulk传输可能需要使用别的接口。 需要在代码中明确指定要使用的接口和端点编号:
      // 获取配置
      IUsbDevice usbDevice = MyUsbDevice as IUsbDevice;
      if (usbDevice != null)
      {
      	usbDevice.SetConfiguration(1); // 通常是配置 1, 查看上面列出的所有配置.
      
          // 获取接口: 找到非ADB的interface
            usbDevice.ClaimInterface(interfaceNumber); // interfaceNumber 替换为你想要使用的接口编号
      }
      
      
      // 打开读取和写入端点
      UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01); // 根据实际端点修改,例如 ReadEndpointID.Ep01
      UsbEndpointWriter writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep02); // 根据实际端点修改,例如 WriteEndpointID.Ep02
      
    • 补充: 接口和端口号都可以在C#代码一开始的foreach循环中的打印中看到。
  • 尝试不同的配置(Configuration): 一些设备可能有多个配置, 用不同配置尝试一下。

  • 进阶技巧 :尝试使用LibUsbDotNet读取一些简单设备信息。比如字符串符, 这样有助于测试驱动和连接性.

5. 调整安卓设备的 USB 设置(如果可能)

有些安卓设备或 ROM 允许更细粒度的 USB 设置控制。

  • 查找更高级的 USB 设置: 在“开发者选项”或“USB 设置”中,查看是否有与 USB 模式或协议相关的更详细的选项。
  • 尝试不同的 USB 模式: 即便它们最初不显示设备,也尝试切换到“文件传输 (MTP)”或“照片传输 (PTP)”等模式,然后重新运行 LibUsbDotNet 代码看看有没有不同。
  • 注意, 一些定制过的安卓设备可能会阻止正常USB功能, 如果以上均不成功, 这可能是根本原因。

6. 使用不同的库或工具进行测试

如果怀疑是 LibUsbDotNet 的问题,试试用其他USB 库,看看是否能连上并传输数据.

  • 使用 ADB 命令行工具进行测试:
    • 通过 adb devices 命令检查设备是否被 ADB 正确识别。
    • 尝试使用 adb pushadb pull 命令传输文件,以验证 ADB 连接是否正常。
    • 如果连 ADB 命令都失败,优先解决 ADB 连接问题。
  • 尝试其他库或工具:
    • 比如 libusb (C/C++). 能够交叉验证是否特定于LibUsbDotNet.
    • 或者用别的工具直接和安卓的 Bulk EndPoints通信.

7. Root 设备 (谨慎操作!)

如果以上所有都无效,可以尝试对安卓进行 root。 有的设备会因此解除一些 USB 的限制。
注意这步有风险。

  • 风险告知: Rooting 设备可能会使设备保修失效,并存在变砖风险. 务必对自己的行为负责。

8. 特定的 ADB Interface

对于有些ADB interface. 除了安装正常驱动以外. 可能需要把 interface 加入一个允许名单.
具体根据不同操作系统实现.
例如, 在Linux 上, 可以编辑 /etc/udev/rules.d/51-android.rules, 加入对应 vendor ID和 Product ID.

总结来说, 你的安卓设备目前看起来对 USB 数据传输的支持有限制。上述这些方法就是为了把这些可能的问题一个一个解决掉, 找到让它乖乖传输数据的正确方法. 希望能帮上忙!