如何捕获来自未知 USB OTG 设备的信号?

How to catch signals from a unknown USB OTG device?

我有一个像鼠标一样的 USB OTG 设备,是在中国买的,关于所用控制器的信息不多。当我将它连接到我的 android 时,有一个鼠标光标,并且该设备有 5 个硬按钮(左、右、上、下、输入)。我想为我的应用程序的按钮编程以执行特定任务。所以我需要读取输入信号并覆盖它们。

我怎样才能捕捉到信号?

我找到了供应商 (0x04D9) 和产品 ID (0x2519) 以及控制器名称 Lenovo Calliope USB Keyboard。但是不知道用过的芯片,是隐蔽的。

它不适用于方法 onKeyDowndispatchKeyEventUSB serial Lib 也没有,因为无法使用提供的 VID 和 PID 找到/识别设备(请参阅下面与 Fatih Şennik 的讨论,其他设备可以用它识别)。

我目前的假设是我无法获得信号是硬件/芯片问题。但奇怪的是,该设备在其他方面做了它应该做的事情。

您可以使用 USB 串行库,例如 https://github.com/mik3y/usb-serial-for-android,并提供 USB OTG 设备的供应商和产品 ID 来控制它。因此,您可以在任何监视器中捕捉左、右、上、下和十六进制代码,并基于原始字节,进行类似开关的操作。

UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { 
     //Defining a Callback which triggers whenever data is read.
        @Override
        public void onReceivedData(byte[] arg0) {
            String data = null;
            try {
                data = new String(arg0, "UTF-8");
                data.concat("/n");
                switch() // etc
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    };

让我们首先尝试将我们的 android phone 连接到 USB otg 设备。至于产品和供应商 ID,您可以在将其插入电脑时找到它。如果建立了连接,那么剩下的就会来。如果您能在这里分享 USB Otg 设备数据表,将会很有帮助。

public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
        ProbeTable customTable = new ProbeTable();
        customTable.addProduct(0x0403, 0x6001, CdcAcmSerialDriver.class);

        List<UsbSerialDriver> availableDrivers = new UsbSerialProber(customTable).findAllDrivers(manager);
        ArrayAdapter<String> deviceList = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_2);
        ListView listDevices = (ListView) findViewById(R.id.listView);
        if(!availableDrivers.isEmpty()) {
            for(UsbSerialDriver driver: availableDrivers) {
                deviceList.add(driver.getDevice().getDeviceName());
            }
            listDevices.setAdapter(deviceList);
        } else {
            Toast.makeText(getApplicationContext(), "No devices found", Toast.LENGTH_LONG).show();
        }
    }
}

如果是 USB 隐藏设备,尝试此代码可能会有所帮助;

UsbManager mManager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = mManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

while (deviceIterator.hasNext())
    {
        UsbDevice device = deviceIterator.next();
        Log.i(TAG,"Model: " + device.getDeviceName());
        Log.i(TAG,"ID: " + device.getDeviceId());
        Log.i(TAG,"Class: " + device.getDeviceClass());
        Log.i(TAG,"Protocol: " + device.getDeviceProtocol());
        Log.i(TAG,"Vendor ID " + device.getVendorId());
        Log.i(TAG,"Product ID: " + device.getProductId());
        Log.i(TAG,"Interface count: " + device.getInterfaceCount());
        Log.i(TAG,"---------------------------------------");
   // Get interface details
        for (int index = 0; index < device.getInterfaceCount(); index++)
        {
        UsbInterface mUsbInterface = device.getInterface(index);
        Log.i(TAG,"  *****     *****");
        Log.i(TAG,"  Interface index: " + index);
        Log.i(TAG,"  Interface ID: " + mUsbInterface.getId());
        Log.i(TAG,"  Inteface class: " + mUsbInterface.getInterfaceClass());
        Log.i(TAG,"  Interface protocol: " + mUsbInterface.getInterfaceProtocol());
        Log.i(TAG,"  Endpoint count: " + mUsbInterface.getEndpointCount());
    // Get endpoint details 
            for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++)
        {
            UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi);
            Log.i(TAG,"    ++++   ++++   ++++");
            Log.i(TAG,"    Endpoint index: " + epi);
            Log.i(TAG,"    Attributes: " + mEndpoint.getAttributes());
            Log.i(TAG,"    Direction: " + mEndpoint.getDirection());
            Log.i(TAG,"    Number: " + mEndpoint.getEndpointNumber());
            Log.i(TAG,"    Interval: " + mEndpoint.getInterval());
            Log.i(TAG,"    Packet size: " + mEndpoint.getMaxPacketSize());
            Log.i(TAG,"    Type: " + mEndpoint.getType());
        }
        }
    }
    Log.i(TAG," No more devices connected.");
}

如果没有任何效果,解决方案:我得到了一个arduino控制器并将其焊接到按钮上。没那么复杂。

重要的是控制器支持隐藏,例如带有atmega32u4芯片的leonardo pro micro。使用 google.

可以轻松找到控制器的代码

然后它与覆盖 onKeyDown 或 onKeyUp 等一起工作