android - usar - cable otg
Leyendo datos crudos del mouse en Android (1)
En mi aplicación de Android, leo los valores de un 3DConnexion SpaceNavigator a través de USB-OTG para controlar un AR.Drone .
Ahora quiero hacer lo mismo con un mouse. Sin embargo, Android está agarrando el mouse y presentando un cursor de mouse. Cuando escribo un filtro de dispositivo con el proveedor y el Id. Del producto del mouse, no lo consigo como con el SpaceNavigator (strangely, both are HID -- I get no cursor with the SpaceNavigator).
¿Hay alguna manera de obtener los datos crudos del mouse sin el cursor?
Sería perfecto con el stock de Android. pero también consideraría alterar la ROM para eso.
Tan pronto como su aplicación reclama el mouse (como dispositivo USB HID mientras está siendo host), Android debería ocultar el cursor y podrá leer los datos sin procesar. Esto debería funcionar en stock android, pero su dispositivo tiene que ser compatible con el modo de host USB y se necesitará un cable USB OTG para conectar el mouse.
Procedimiento básico:
- enumerar dispositivos
- pedir permiso para acceder al dispositivo USB
- reclamar el dispositivo
- leer un paquete de datos desde el punto final de HID
- analice la posición X e Y, haga clic en los botones y desplace la rotación de la rueda desde el paquete de datos
Código de ejemplo que me funciona (Android 5.0):
UsbManager usbManager;
UsbDevice usbDevice;
private void connect() {
this.usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
// just get the first enumerated USB device
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
if (deviceIterator.hasNext()) {
this.usbDevice = deviceIterator.next();
}
if (usbDevice == null) {
Log.w(TAG, "no USB device found");
return;
}
// ask for permission
final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
// call method to set up device communication
Log.i(TAG, "permission granted. access mouse.");
// repeat in a different thread
transfer(device);
}
}
else {
Log.d(TAG, "permission denied for device " + device);
}
}
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
// TODO:
// call your method that cleans up and closes communication with the device
// usbInterface.releaseInterface();
// usbDeviceConnection.close();
}
}
}
};
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
context.registerReceiver(mUsbReceiver, filter);
usbManager.requestPermission(usbDevice, mPermissionIntent);
}
private void transfer(UsbDevice device) {
int TIMEOUT = 0;
boolean forceClaim = true;
// just grab the first endpoint
UsbInterface intf = device.getInterface(0);
UsbEndpoint endpoint = intf.getEndpoint(0);
UsbDeviceConnection connection = this.usbManager.openDevice(device);
connection.claimInterface(intf, forceClaim);
byte[] bytes = new byte[endpoint.getMaxPacketSize()];
connection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT);
// depending on mouse firmware and vendor the information you''re looking for may
// be in a different order or position. For some logitech devices the following
// is true:
int x = (int) bytes[1];
int y = (int) bytes[2];
int scrollwheel = (int) bytes[3]
// call a listener, process your data ...
}