Interfaz USB en Android

Enraqué mi dispositivo y funcionando en el modo host. Puedo capaz de detectar el dispositivo USB conectado a mi ficha, pero tengo dos preguntas.

1) intento mostrar el nombre de mi dispositivo usando device.getDeviceName (); Pero su mostrar algo como / dev / usb / 002/002 Necesito obtener el nombre del fabricante del nombre del dispositivo usb. I cosa su disponible en modo accesorio pero necesito conseguir el nombre del fabricante en modo de anfitrión.

2) Necesito transferir algunos datos de mi aplicación al puerto usb en android. Puedo capaz de detectar el dispositivo, pero por favor ayuda en la transferencia de algunos datos o archivo de mi aplicación Android para el almacenamiento masivo conectado al puerto usb.

5 Solutions collect form web for “Interfaz USB en Android”

Probablemente usted realmente tendrá que leer los Descriptores USB Raw para obtener los datos que desea. He aquí un programa básico de descubrimiento de dispositivos USB que escribí para mis propios propósitos. Ten en cuenta que estoy buscando un dispositivo específico (un sistema de adquisición de datos Dajac Easy I / O 1000), pero puedes aplicar los mismos principios. Te muestro cómo obtener los datos que estás buscando.

Aquí está el código primero. Mi paquete es usbtest3, y el archivo es MainActivity.java:

package com.hotspotoffice.usbtest3; // David Schofield, Hotspot Office, LLC., Pittsburgh, PA. // Donations via PayPal always welcome! schofield (dot) david (at) verizon.net import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Iterator; import android.os.Bundle; import android.app.Activity; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.view.View; import android.view.Menu; import android.widget.Button; import android.widget.TextView; import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbInterface; public class MainActivity extends Activity { protected static final int STD_USB_REQUEST_GET_DESCRIPTOR = 0x06; // http://libusb.sourceforge.net/api-1.0/group__desc.html protected static final int LIBUSB_DT_STRING = 0x03; private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"; private Button btnDiscover; private TextView txtInfo; private PendingIntent mPermissionIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnDiscover=(Button)findViewById(R.id.btnDiscover); txtInfo=(TextView)findViewById(R.id.txtInfo); mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); registerReceiver(mUsbReceiver, filter); btnDiscover.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // txtInfo.setText("Button has been Pressed for "+(++i)+" Times."); UsbManager manager = (UsbManager)getSystemService(Context.USB_SERVICE); HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); while(deviceIterator.hasNext()){ UsbDevice device = deviceIterator.next(); manager.requestPermission(device, mPermissionIntent); txtInfo.append("Model:" + device.getDeviceName() + "\n"); txtInfo.append("DeviceID:" + device.getDeviceId() + "\n"); txtInfo.append("Vendor:" + device.getVendorId() + "\n"); txtInfo.append("Product:" + device.getProductId() + "\n"); txtInfo.append("Class:" + device.getDeviceClass() + "\n"); txtInfo.append("Subclass:" + device.getDeviceSubclass() + "\n"); txtInfo.append("Protocol:" + device.getDeviceProtocol() + "\n"); UsbInterface intf = device.getInterface(0); int epc = 0; epc = intf.getEndpointCount(); txtInfo.append("Endpoints:" + epc + "\n"); txtInfo.append("Permission:" + Boolean.toString(manager.hasPermission(device)) + "\n"); UsbDeviceConnection connection = manager.openDevice(device); if(null==connection){ txtInfo.append("(unable to establish connection)\n"); } else { // Claims exclusive access to a UsbInterface. // This must be done before sending or receiving data on // any UsbEndpoints belonging to the interface. connection.claimInterface(intf, true); // getRawDescriptors can be used to access descriptors // not supported directly via the higher level APIs, // like getting the manufacturer and product names. // because it returns bytes, you can get a variety of // different data types. byte[] rawDescs = connection.getRawDescriptors(); String manufacturer = "", product = ""; try { byte[] buffer = new byte[255]; int idxMan = rawDescs[14]; int idxPrd = rawDescs[15]; int rdo = connection.controlTransfer(UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_STANDARD, STD_USB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | idxMan, 0, buffer, 0xFF, 0); manufacturer = new String(buffer, 2, rdo - 2, "UTF-16LE"); rdo = connection.controlTransfer(UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_STANDARD, STD_USB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | idxPrd, 0, buffer, 0xFF, 0); product = new String(buffer, 2, rdo - 2, "UTF-16LE"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } txtInfo.append("Manufacturer:" + manufacturer + "\n"); txtInfo.append("Product:" + product + "\n"); txtInfo.append("Serial#:" + connection.getSerial() + "\n"); } txtInfo.append("------------------------------------\n"); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } private 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 } } else { txtInfo.append("permission denied for device " + device); } } } } }; } 

Mi archivo de manifiesto que contiene las intenciones y los requisitos para la compatibilidad del dispositivo USB Host:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.hotspotoffice.usbtest3" android:versionCode="1" android:versionName="1.0" > <uses-feature android:name="android.hardware.usb.host" /> <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="15" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.hotspotoffice.usbtest3.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> </intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" /> </activity> </application> </manifest> 

Por último, necesitará un filtro de dispositivo. Esto se encuentra en \ res \ xml \ device_filter.xml Tenga en cuenta que tuve que crear la carpeta xml yo mismo, bajo \ res.

 <?xml version="1.0" encoding="utf-8"?> <resources> <usb-device vendor-id="7635" product-id="1" class="255" subclass="255" protocol="0" /> </resources> 

Tenga en cuenta que todos los campos deben estar en decimal, no en hexadecimal. Tendrá que sustituir su propio proveedor, producto, clase y valores de subclase de su propio dispositivo. Puede usar un programa como "USB Host View" o "USB Device Info" para descubrir estos valores. (Descargarlos gratis desde la Play Store).

Por último, aquí es cómo definí la interfaz de usuario en Activity_Main.xml
Necesitará al menos el botón Descubrir y TextMultiline para la salida. (Ignore los botones Init y On / Off.)

BTW, estoy usando un 10 "Toshiba Thrive tablet, por lo que YMMV.

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <EditText android:id="@+id/txtInfo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/btnDiscover" android:layout_alignRight="@+id/textView1" android:layout_centerVertical="true" android:ems="10" android:inputType="textMultiLine" android:maxLines="50" android:minLines="20" android:minWidth="400dp" > <requestFocus /> </EditText> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/btnToggleDIO" android:layout_marginLeft="192dp" android:layout_toRightOf="@+id/btnDiscover" android:text="@string/lblDIO" android:textAppearance="?android:attr/textAppearanceMedium" /> <Button android:id="@+id/btnDiscover" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/btnInit" android:layout_alignBottom="@+id/btnInit" android:layout_alignParentLeft="true" android:layout_marginLeft="73dp" android:text="@string/strDiscover" /> <ToggleButton android:id="@+id/btnToggleDIO" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/btnInit" android:layout_alignBottom="@+id/btnInit" android:layout_alignLeft="@+id/textView1" android:text="@string/strIOState" /> <Button android:id="@+id/btnInit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/txtInfo" android:layout_marginBottom="29dp" android:layout_marginLeft="48dp" android:layout_toRightOf="@+id/btnDiscover" android:text="@string/strInit" /> </RelativeLayout> 

Cuando ejecuto mi programa y enchufar mi dispositivo, pide mi permiso de conexión y digo "Ok". Entonces hago clic en Discover, y me dice entre otras cosas que el fabricante es "Dajac Inc." El producto es "EIO1000" y el número de serie es "0000004B".

Les deseo buena providencia; Usted puede darme el crédito pero es solamente colocándose en los hombros de otros (con muchos de mi propio sudor) he podido ver esto lejano. ¡Aprovéchalo! David

El código anterior funciona correctamente para la mayoría de los dispositivos, excepto los dispositivos móviles de Samsung. Para hacerlos fuente de la identificación de la lengua otra cosa usted conseguirá la parada.

 int rdo = connection.controlTransfer(UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_STANDARD, STD_USB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | idxMan, 0x0409, buffer, 0xFF, 0); 

nombre del dispositivo

Esto se parece al nombre de dispositivo interno del kernel de Linux.

Nombre del Fabricante

Sólo se obtiene esto indirectamente a través del USB VID (Vendor ID). Ellos son asignados y mantenidos por el USB-IF .

Un dispositivo puede proporcionar un nombre para el fabricante en su descriptor de cadena, pero AFAIK esto es opcional – y no está expuesto en el alto nivel de la interfaz java de Android.

Usted puede intentar su suerte con UsbDeviceConnection.getRawDescriptors , pero eso requeriría bastante feo fiddeling con bytes.

Al almacenamiento masivo

USB de almacenamiento masivo es un protocolo bastante complejo, por lo que hablar directamente a través de USB Host API sería bastante difícil de implementar. Algunas imágenes de firmware de Android pueden montar unidades flash USB, que sería mucho más simple.

  1. GetVendorId () debería darle el nombre del fabricante. Otras llamadas incluyen getDeviceName (), getDeviceId (), getDeviceClass (), getDeviceSubclass (), getDeviceProtocol (), getProductId (). Consulte este enlace: Android USB Host

  2. Para transferencias de datos, consulte este enlace: BulkTransfer . Leer desde el archivo en un búfer y pasar el búfer a la llamada bulkTransfer junto con la salida específica Endpoint de su dispositivo y la longitud de los datos.

Sólo una nota menor sobre el código anterior, que en principio funciona muy bien. Solicitar al usuario permiso para acceder al dispositivo USB es una llamada asíncrona. Por lo tanto, el código no debe proceder para ese dispositivo en particular si no tiene (todavía) permisos.

Permítanme hacer una pequeña actualización de los métodos onClick y onReceive:

  Button btnDiscover = (Button) findViewById(R.id.buttonDiscover); btnDiscover.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { txtInfo.setText(""); HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); for (UsbDevice device : deviceList.values()) { Log.i("discover", "Model :" + device.getDeviceName()); if (!manager.hasPermission(device)) { Log.i("discover", "No permission to access, so requesting it now from user (async)"); manager.requestPermission(device, mPermissionIntent); } else { showUsbDetails(device); } } } }); private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (MainActivity.ACTION_USB_PERMISSION.equals(action)) { Log.i("BroadcastReceiver", "onReceive: ACTION_USB_PERMISSION"); synchronized (this) { UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { if(device != null){ showUsbDetails(device); } } else { txtInfo.append("permission denied for device " + device); } } 

No hace falta decir que showUsbDetails contiene ahora la parte del código original que realiza la comunicación con el dispositivo USB para consultar el fabricante y otras cadenas.

  • La aplicación no se iniciará cuando se utiliza la biblioteca `com.android.future.usb.accessory`
  • Android: perdiendo los datos USB entrantes (alta velocidad)
  • ¿Conectar el dispositivo USB al emulador de Android?
  • Conectar el dispositivo Android con el dispositivo Puerto virtual COM
  • Envío de datos a la impresora térmica desde el dispositivo Android a través de USB
  • Nexus 7 no es recogido por adb (cuando lo conecto a la computadora portátil a través de usb)
  • ¿Qué sucede después de que DTR / RTS sea enviado a una placa Arduino basada en FTDI?
  • USB Accessory API en el Samsung Galaxy S2 Android
  • ¿Cómo comunicarse con un dispositivo USB desde una tableta Android?
  • El desarrollo de una aplicación de comunicación de dispositivos especiales que se conecta a través de puerto USB en Android
  • Comunicación entre PhoneGap, dispositivo externo usb y modo host Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.