support reconoce otg lista con compatibles checker celulares celular android usb host cdc

reconoce - Android USB host leer desde el dispositivo



usb otg android apk (1)

Puede usar UsbSerial Lib de several

Mi código de ejemplo:

UsbManager usbManager = null; UsbDeviceConnection connection = null; UsbSerialDriver driver = null; UsbSerialPort port = null; usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager); // Open a connection to the first available driver. for (UsbSerialDriver usd : availableDrivers) { UsbDevice udv = usd.getDevice(); if (udv.getVendorId()==0x067B || udv.getProductId()==2303){ driver = usd; break; } } connection = usbManager.openDevice(driver.getDevice()); port = driver.getPorts().get(0); driver.getDevice(). } if (connection == null) return; try{ port.open(connection); port.setParameters(4800, UsbSerialPort.DATABITS_8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE); try{ byte buffer[] = new byte[250]; //Log.d("GPS_REQ", "->"); int numBytesRead = port.read(buffer, 500); //5000; }catch (Exception e) { Log.d("GPS_ERR", e.getLocalizedMessage()); }

Estoy tratando de obtener algunos datos de un dispositivo USB conectado a mi teléfono Android que está en modo de host. Puedo enviarle datos, pero la lectura falla.

He visto several examples y he intentado todo lo que pude, pero no tengo ninguna experiencia en comunicación USB, aunque ahora sé un poco, y he estado atrapado en esto por más tiempo que me importa admitir.

No estoy muy familiarizado con la configuración del punto final, pero sé que mi dispositivo utiliza un método de comunicación de tipo CDC y se registran tanto la salida (desde el teléfono al dispositivo) como la entrada.

Aquí está toda la clase que administra la conexión USB con el único dispositivo que está conectado al teléfono, no está terminado de ninguna manera, pero me gustaría que esa parte de lectura funcione antes de seguir adelante.

public class UsbCommunicationManager { static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"; UsbManager usbManager; UsbDevice usbDevice; UsbInterface intf = null; UsbEndpoint input, output; UsbDeviceConnection connection; PendingIntent permissionIntent; Context context; byte[] readBytes = new byte[64]; public UsbCommunicationManager(Context context) { this.context = context; usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); // ask permission from user to use the usb device permissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); context.registerReceiver(usbReceiver, filter); } public void connect() { // check if there''s a connected usb device if(usbManager.getDeviceList().isEmpty()) { Log.d("trebla", "No connected devices"); return; } // get the first (only) connected device usbDevice = usbManager.getDeviceList().values().iterator().next(); // user must approve of connection usbManager.requestPermission(usbDevice, permissionIntent); } public void stop() { context.unregisterReceiver(usbReceiver); } public String send(String data) { if(usbDevice == null) { return "no usb device selected"; } int sentBytes = 0; if(!data.equals("")) { synchronized(this) { // send data to usb device byte[] bytes = data.getBytes(); sentBytes = connection.bulkTransfer(output, bytes, bytes.length, 1000); } } return Integer.toString(sentBytes); } public String read() { // reinitialize read value byte array Arrays.fill(readBytes, (byte) 0); // wait for some data from the mcu int recvBytes = connection.bulkTransfer(input, readBytes, readBytes.length, 3000); if(recvBytes > 0) { Log.d("trebla", "Got some data: " + new String(readBytes)); } else { Log.d("trebla", "Did not get any data: " + recvBytes); } return Integer.toString(recvBytes); } public String listUsbDevices() { HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList(); if(deviceList.size() == 0) { return "no usb devices found"; } Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); String returnValue = ""; UsbInterface usbInterface; while(deviceIterator.hasNext()) { UsbDevice device = deviceIterator.next(); returnValue += "Name: " + device.getDeviceName(); returnValue += "/nID: " + device.getDeviceId(); returnValue += "/nProtocol: " + device.getDeviceProtocol(); returnValue += "/nClass: " + device.getDeviceClass(); returnValue += "/nSubclass: " + device.getDeviceSubclass(); returnValue += "/nProduct ID: " + device.getProductId(); returnValue += "/nVendor ID: " + device.getVendorId(); returnValue += "/nInterface count: " + device.getInterfaceCount(); for(int i = 0; i < device.getInterfaceCount(); i++) { usbInterface = device.getInterface(i); returnValue += "/n Interface " + i; returnValue += "/n/tInterface ID: " + usbInterface.getId(); returnValue += "/n/tClass: " + usbInterface.getInterfaceClass(); returnValue += "/n/tProtocol: " + usbInterface.getInterfaceProtocol(); returnValue += "/n/tSubclass: " + usbInterface.getInterfaceSubclass(); returnValue += "/n/tEndpoint count: " + usbInterface.getEndpointCount(); for(int j = 0; j < usbInterface.getEndpointCount(); j++) { returnValue += "/n/t Endpoint " + j; returnValue += "/n/t/tAddress: " + usbInterface.getEndpoint(j).getAddress(); returnValue += "/n/t/tAttributes: " + usbInterface.getEndpoint(j).getAttributes(); returnValue += "/n/t/tDirection: " + usbInterface.getEndpoint(j).getDirection(); returnValue += "/n/t/tNumber: " + usbInterface.getEndpoint(j).getEndpointNumber(); returnValue += "/n/t/tInterval: " + usbInterface.getEndpoint(j).getInterval(); returnValue += "/n/t/tType: " + usbInterface.getEndpoint(j).getType(); returnValue += "/n/t/tMax packet size: " + usbInterface.getEndpoint(j).getMaxPacketSize(); } } } return returnValue; } private void setupConnection() { // find the right interface for(int i = 0; i < usbDevice.getInterfaceCount(); i++) { // communications device class (CDC) type device if(usbDevice.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) { intf = usbDevice.getInterface(i); // find the endpoints for(int j = 0; j < intf.getEndpointCount(); j++) { if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { // from android to device output = intf.getEndpoint(j); } if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { // from device to android input = intf.getEndpoint(j); } } } } } private final BroadcastReceiver usbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(ACTION_USB_PERMISSION.equals(action)) { // broadcast is like an interrupt and works asynchronously with the class, it must be synced just in case synchronized(this) { if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { setupConnection(); connection = usbManager.openDevice(usbDevice); connection.claimInterface(intf, true); // set flow control to 8N1 at 9600 baud int baudRate = 9600; byte stopBitsByte = 1; byte parityBitesByte = 0; byte dataBits = 8; byte[] msg = { (byte) (baudRate & 0xff), (byte) ((baudRate >> 8) & 0xff), (byte) ((baudRate >> 16) & 0xff), (byte) ((baudRate >> 24) & 0xff), stopBitsByte, parityBitesByte, (byte) dataBits }; connection.controlTransfer(UsbConstants.USB_TYPE_CLASS | 0x01, 0x20, 0, 0, msg, msg.length, 5000); } else { Log.d("trebla", "Permission denied for USB device"); } } } else if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) { Log.d("trebla", "USB device detached"); } } }; }

Sigo recibiendo -1 del método read() que indica algún tipo de error, siempre agota el tiempo. Tal vez el problema proviene de la configuración de conexión, he intentado con varios (léase: prueba y error) y ninguno funcionó, sorprendentemente no necesito ninguna configuración para enviar datos al dispositivo.

Editar

También debe tenerse en cuenta que el cable que estoy utilizando es micro-USB a micro-USB y solo funciona de una manera, es decir, mi dispositivo funciona con mi teléfono solo cuando el enchufe A está conectado al teléfono y el enchufe B está conectado a dispositivo, no al revés ... parece muy extraño. El hecho de que puedo enviar datos y no recibirlos cuando está enchufado de la manera correcta permanece.

EDIT 2

Descubrí que alguien más tenía el mismo problema, pero parece que no fue capaz de resolverlo.

EDIT 3

Finalmente encontré la solución en esta página :

Otra supervisión importante es que no hay ningún mecanismo para que el host notifique al dispositivo que hay un receptor de datos en el lado del host listo para aceptar datos. Esto significa que el dispositivo puede tratar de enviar datos mientras el host no está escuchando, lo que provoca tiempos de espera de bloqueo prolongados en las rutinas de transmisión. Por lo tanto, se recomienda encarecidamente utilizar la señal de línea serie virtual DTR (Data Terminal Ready) cuando sea posible para determinar si una aplicación de host está lista para datos.

Entonces, la señal DTR era obligatoria y todo lo que tenía que hacer era agregar esto a la configuración de la interfaz:

connection.controlTransfer(0x21, 0x22, 0x1, 0, null, 0, 0);

EDIT 4

Si alguien está interesado, terminé el proyecto y es de código abierto y publicado en mi cuenta de GitHub . Aunque no es estable todo el tiempo (ver las notes ) y no planeo seguir trabajando en eso, pero funciona. Siéntase libre de usarlo para sus propios proyectos.