Cuando su dispositivo con Android está en modo host USB, actúa como el host USB, alimenta el bus y enumera los dispositivos USB conectados. El modo host USB es compatible con Android 3.1 y versiones posteriores.
descripción general de la API
antes de comenzar, es importante comprender las clases con las que necesita trabajar. En la siguiente tabla se describen las API de host USB del paquete android.hardware.usb
.
Cuadro 1., USB Host Api
Clase | Descripción |
---|---|
UsbManager |
Permite enumerar y comunicarse con los dispositivos USB conectados. |
UsbDevice
|
representa un dispositivo USB conectado y contiene métodos para acceder a su información de identificación, interfaces y puntos finales. |
UsbInterface |
Representa una interfaz de un dispositivo USB, el cual define un conjunto de funciones para el dispositivo., Un dispositivo puede tener una o más interfaces en las que comunicarse. |
UsbEndpoint |
Representa una interfaz de punto final, que es un canal de comunicación para esta interfaz. Una interfaz puede tener uno o más puntos finales, y por lo general tiene puntos finales de entrada y salida para la comunicación bidireccional con el dispositivo. |
UsbDeviceConnection
|
representa una conexión al dispositivo, que transfiere datos en los endpoints. Esta clase le permite enviar datos de ida y vuelta de forma sincrónica o asincrónica., |
UsbRequest |
Representa una solicitud asincrónica para comunicarse con un dispositivo a través de un UsbDeviceConnection . |
UsbConstants
|
define constantes USB que corresponden a las definiciones en linux/usb/ch9.h del núcleo Linux. |
en la mayoría de las situaciones, debe usar todas estas clases (UsbRequest
solo se requiere si está haciendo comunicación asincrónica) al comunicarse con un dispositivo USB., En general, se obtiene un UsbManager
para recuperar el UsbDevice
deseado. Cuando tenga el dispositivo, debe encontrar el UsbInterface
y el UsbEndpoint
de esa interfaz para comunicarse. Una vez que obtenga el punto final correcto, abra un UsbDeviceConnection
para comunicarse con el dispositivo USB.,
requisitos del Manifiesto de Android
la siguiente lista describe lo que necesitas agregar al archivo de manifiesto de tu aplicación antes de trabajar con las API de host USB:
- dado que no todos los dispositivos con Android son compatibles con las API de host USB, incluye un elemento
<uses-feature>
que declare que tu aplicación utiliza la funciónandroid.hardware.usb.host
. - establezca el SDK mínimo de la aplicación en el nivel de API 12 o superior. Las API de host USB no están presentes en niveles de API anteriores.,
- Si desea que se notifique a su aplicación de un dispositivo USB conectado, especifique un par de elementos
<intent-filter>
y<meta-data>
para la intentandroid.hardware.usb.action.USB_DEVICE_ATTACHED
en su actividad principal. El elemento<meta-data>
apunta a un archivo de recursos XML externo que declara información de identificación sobre el dispositivo que desea detectar.en el archivo de recursos XML, declare elementos
<usb-device>
para los dispositivos USB que desea filtrar. La siguiente lista describe los atributos de<usb-device>
., En general, use vendor and product ID si desea filtrar para un dispositivo específico y use class, subclass y protocol si desea filtrar para un grupo de dispositivos USB, como dispositivos de almacenamiento masivo o cámaras digitales. Puede especificar ninguno o todos estos atributos., La especificación de los atributos coincide con todos los dispositivos USB, así que sólo puede hacer esto si su aplicación requiere:vendor-id
product-id
class
subclass
-
protocol
(dispositivo o interfaz)
Guarde el archivo de recursos en el
res/xml/
directorio. El nombre del archivo de recursos (sin el .extensión xml) debe ser la misma que la especificada en el elemento<meta-data>
. El formato para el archivo de recursos XML se encuentra en el siguiente ejemplo.,
ejemplos de manifiesto y archivo de recursos
el siguiente ejemplo muestra un manifiesto de muestra y su archivo de recursos correspondiente:
en este caso, el siguiente archivo de recursos debe guardarse en res/xml/device_filter.xml
y especifica que cualquier dispositivo USB con los atributos especificados debe filtrarse:
trabajar con dispositivos
Cuando los usuarios conectan dispositivos USB a un dispositivo con Android, el sistema Android puede determinar si su aplicación está interesada en el dispositivo conectado. Si es así, puede configurar la comunicación con el dispositivo si lo desea., Para ello, la aplicación debe:
- descubrir dispositivos USB conectados mediante un filtro de intent para recibir notificaciones cuando el usuario conecta un dispositivo USB o enumerando dispositivos USB que ya están conectados.
- pida al usuario permiso para conectarse al dispositivo USB, Si aún no lo ha obtenido.
- comuníquese con el dispositivo USB leyendo y escribiendo datos en los puntos finales de interfaz apropiados.,
descubrir un dispositivo
Su aplicación puede descubrir dispositivos USB utilizando un filtro de intents para recibir notificaciones cuando el usuario conecta un dispositivo o enumerando dispositivos USB que ya están conectados. El uso de un filtro de intents es útil si desea que su aplicación detecte automáticamente un dispositivo deseado. Enumerar dispositivos USB conectados es útil si desea obtener una lista de todos los dispositivos conectados o si su aplicación no filtró una intent.,
Use un filtro de intents
para que su aplicación Descubra un dispositivo USB en particular, puede especificar un filtro de intents para filtrar la intent android.hardware.usb.action.USB_DEVICE_ATTACHED
. Junto con este filtro de intents, debe especificar un archivo de recursos que especifique las propiedades del dispositivo USB, como el ID del producto y del proveedor. Cuando los usuarios conectan un dispositivo que coincide con su filtro de dispositivo, el sistema les presenta un cuadro de diálogo que les pregunta si desean iniciar la aplicación. Si los usuarios aceptan, la aplicación tiene permiso para acceder al dispositivo automáticamente hasta que el dispositivo se desconecte.,
el siguiente ejemplo muestra cómo declarar el filtro de intent:
el siguiente ejemplo muestra cómo declarar el archivo de recursos correspondiente que especifica los dispositivos USB que le interesan:
<?xml version="1.0" encoding="utf-8"?><resources> <usb-device vendor-id="1234" product-id="5678" /></resources>
en su actividad, puede obtener el UsbDevice
que representa el dispositivo conectado desde la intent de esta manera:
enumerar dispositivos
si su aplicación está interesada en inspeccionar todos los dispositivos USB conectados actualmente mientras su aplicación se está ejecutando, puede enumerar dispositivos en el bus., Utilice el método getDeviceList()
para obtener un mapa hash de todos los dispositivos USB que están conectados. El mapa hash está marcado por el nombre del dispositivo USB si desea obtener un dispositivo del mapa.
si lo desea, también puede obtener un iterador del mapa hash y procesar cada dispositivo uno por uno:
obtener permiso para comunicarse con un dispositivo
antes de comunicarse con el dispositivo USB, su aplicación debe tener permiso de sus usuarios.,
Nota: Si tu aplicación utiliza un filtro de intent para descubrir dispositivos USB a medida que están conectados, recibe automáticamente permisos si el usuario permite que tu aplicación maneje la intent. Si no es así, debe solicitar permiso explícitamente en su aplicación antes de conectarse al dispositivo.
pedir permiso explícitamente puede ser necesario en algunas situaciones, como cuando su aplicación enumera dispositivos USB que ya están conectados y luego quiere comunicarse con uno. Debe verificar si tiene permiso para acceder a un dispositivo antes de intentar comunicarse con él., Si no, recibirá un error de tiempo de ejecución si el usuario denegó el permiso para acceder al dispositivo.
para obtener permiso explícitamente, primero cree un receptor de transmisión. Este receptor escucha la intent que se emite cuando llamas a requestPermission()
. La llamada a requestPermission()
muestra un diálogo al usuario pidiendo permiso para conectarse al dispositivo., El siguiente código de ejemplo muestra cómo crear el receptor de difusión:
para registrar el receptor de difusión, agregue esto en su método onCreate()
en su actividad:
para mostrar el cuadro de diálogo que pide a los usuarios permiso para conectarse al dispositivo, llame al método requestPermission()
:
Cuando los usuarios responden al cuadro de diálogo, su receptor de difusión recibe la intent el EXTRA_PERMISSION_GRANTED
extra, que es un booleano que representa la respuesta. Marque este extra para un valor de true antes de conectarse al dispositivo.,
Comunicarse con un dispositivo
la Comunicación con un dispositivo USB puede ser sincrónica o asincrónica. En cualquier caso, debe crear un nuevo subproceso en el que realizar todas las transmisiones de datos, para que no bloquee el subproceso de interfaz de usuario. Para configurar correctamente la comunicación con un dispositivo, usted necesita para obtener el correspondiente UsbInterface
y UsbEndpoint
del dispositivo que se desea comunicar y enviar solicitudes sobre este extremo con un UsbDeviceConnection
., En general, el código debe:
- comprobar los atributos de un objeto
UsbDevice
, como ID de Producto, ID de Proveedor o clase de dispositivo, para saber si desea o no comunicarse con el dispositivo. - Cuando usted está seguro de que desea comunicarse con el dispositivo, encontrar el
UsbInterface
que desea utilizar para comunicarse, junto con el correspondienteUsbEndpoint
de la interfaz. Las Interfaces pueden tener uno o más puntos finales, y comúnmente tendrán un punto final de entrada y salida para la comunicación bidireccional., - Cuando encuentre el punto final correcto, abra un
UsbDeviceConnection
en ese punto final. - proporcionar los datos que se desea transmitir en el extremo con el
bulkTransfer()
ocontrolTransfer()
método. Debes llevar a cabo este paso en otro subproceso para evitar bloquear el subproceso principal de la interfaz de usuario. Para obtener más información sobre el uso de subprocesos en Android, consulte procesos e subprocesos.
el siguiente fragmento de código es una forma trivial de realizar una transferencia de datos síncrona., Su código debe tener más lógica para encontrar correctamente la interfaz y los puntos finales correctos para comunicarse y también debe hacer cualquier transferencia de datos en un subproceso diferente al subproceso principal de la interfaz de usuario:
para enviar datos de forma asíncrona, use la clase UsbRequest
a initialize
y queue
solicitud asíncrona, luego espere el resultado con requestWait()
.,
terminar la comunicación con un dispositivo
Cuando haya terminado de comunicarse con un dispositivo o si el dispositivo se desconectó, cierre UsbInterface
y UsbDeviceConnection
llamando a releaseInterface()
y close()
. Para escuchar eventos separados, cree un receptor de transmisión como el siguiente:
crear el receptor de transmisión dentro de la aplicación, y no el manifiesto, permite que su aplicación solo maneje eventos separados mientras se está ejecutando., De esta manera, los eventos separados solo se envían a la aplicación que se está ejecutando actualmente y no se transmiten a todas las aplicaciones.