Uso de la API de host USB de Android para leer mi controlador de juego USB u otros datos de dispositivo USB

Estoy tratando de utilizar Android USB Host API para leer mis datos de controlador de juegos USB, una vez que tengo esto a trabajar, voy a conectar otro dispositivo para probar. Mi controlador de juego está conectado a mi teléfono Android utilizando el cable OTG. Ahora soy capaz de obtener dispositivo, información de puntos finales, pero no sé cómo leer los datos sin procesar y mostrarlo.

¿Puede alguien ayudarme por favor? Se apreciarán algunos códigos de ejemplo.

TextView countDisplay; ArrayList<String> listItems = new ArrayList<String>(); ArrayAdapter<String> adapter; String values = ""; UsbManager mManager; UsbDevice device = null; private byte[] bytes; private static int TIMEOUT = 0; private boolean forceClaim = true; static PendingIntent mPermissionIntent; UsbDeviceConnection connection = null; UsbEndpoint InputEndpoint = null; UsbEndpoint OutputEndpoint = null; private Handler mHandler = new Handler(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mManager = (UsbManager) getSystemService(Context.USB_SERVICE); mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent( "com.android.example.USB_PERMISSION"), 0); IntentFilter filter = new IntentFilter(); filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); registerReceiver(mUsbReceiver, filter); HashMap<String, UsbDevice> deviceList = mManager.getDeviceList(); values = values + "deviceListSize:" + deviceList.size() + ",tostring:" + deviceList.toString(); Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); while (deviceIterator.hasNext()) { device = deviceIterator.next(); values = values + ",device id:" + device.getDeviceId() + ",device name:" + device.getDeviceName(); values = values + ",Protocol:" + device.getDeviceProtocol() + ",ProductId:" + device.getProductId(); values = values + ",DeviceClass:" + device.getDeviceClass() + ",VendorId:" + device.getVendorId(); } if (device != null) { values = values + ",getInterfaceCount:" + device.getInterfaceCount(); UsbInterface intf = device.getInterface(0); values = values + ",intf.getEndpointCount():" + intf.getEndpointCount(); UsbEndpoint endpoint1 = intf.getEndpoint(0); UsbEndpoint endpoint2 = intf.getEndpoint(1); mManager.requestPermission(device, mPermissionIntent); if (mManager.hasPermission(device)) { values = values + ",has permission over device!"; connection = mManager.openDevice(device); if (connection == null) { values = values + ",connection null"; } else { values = values + ",getFileDescriptor:" + connection.getFileDescriptor(); if (endpoint1.getDirection() == UsbConstants.USB_DIR_IN) { InputEndpoint = endpoint1; } else { OutputEndpoint = endpoint1; } if (endpoint2.getDirection() == UsbConstants.USB_DIR_IN) { InputEndpoint = endpoint2; } else { OutputEndpoint = endpoint2; } } if (InputEndpoint == null) { countDisplay.setText(values + ",InputEndpoint is null"); } if (OutputEndpoint == null) { countDisplay.setText(values + ",OutputEndPoint is null"); } connection.claimInterface(intf, forceClaim); mHandler.postDelayed(runnable, 1); } else { values = values + ",Do not have permission over device!"; } } setContentView(R.layout.activity_main); LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = inflater.inflate(R.layout.activity_main, null); LinearLayout ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); int counter = 1; countDisplay = new TextView(this); ll.addView(countDisplay); countDisplay.setText(values + ",counter here"); final Button button = new Button(this); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (device != null && mManager.hasPermission(device)) { values = values + ",device id:" + device.getDeviceId() + ",device name:" + device.getDeviceName(); values = values + ",Protocol:" + device.getDeviceProtocol() + ",ProductId:" + device.getProductId(); values = values + ",DeviceClass:" + device.getDeviceClass() + ",VendorId:" + device.getVendorId(); countDisplay.setText(values + ",okok"); } else { if (device != null) mManager.requestPermission(device, mPermissionIntent); } } }); ll.addView(button); setContentView(ll); } 

Y Runnable:

 private Runnable runnable = new Runnable() { public void run() { if (connection != null) { int count = connection.bulkTransfer(InputEndpoint, bytes, bytes.length, TIMEOUT); countDisplay.setText(values + ",bultTransferNo:" + count); countDisplay.setText(values + "bulkValue:" + bytes); } else { countDisplay.setText(values + ",connection is null"); } } }; 

Este programa sirve como un ejemplo de las siguientes características de host USB:

  • Dispositivos coincidentes basados ​​en clase de interfaz, subclase y protocolo (consulte device_filter.xml)

  • Asignación de E / S asíncrona en puntos finales en bloque

Todo el código Copyright:

  /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 

AdbDevice

  package com.android.adb; import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbRequest; import android.util.SparseArray; import java.util.LinkedList; /* This class represents a USB device that supports the adb protocol. */ public class AdbDevice { private final AdbTestActivity mActivity; private final UsbDeviceConnection mDeviceConnection; private final UsbEndpoint mEndpointOut; private final UsbEndpoint mEndpointIn; private String mSerial; // pool of requests for the OUT endpoint private final LinkedList<UsbRequest> mOutRequestPool = new LinkedList<UsbRequest>(); // pool of requests for the IN endpoint private final LinkedList<UsbRequest> mInRequestPool = new LinkedList<UsbRequest>(); // list of currently opened sockets private final SparseArray<AdbSocket> mSockets = new SparseArray<AdbSocket>(); private int mNextSocketId = 1; private final WaiterThread mWaiterThread = new WaiterThread(); public AdbDevice(AdbTestActivity activity, UsbDeviceConnection connection, UsbInterface intf) { mActivity = activity; mDeviceConnection = connection; mSerial = connection.getSerial(); UsbEndpoint epOut = null; UsbEndpoint epIn = null; // look for our bulk endpoints for (int i = 0; i < intf.getEndpointCount(); i++) { UsbEndpoint ep = intf.getEndpoint(i); if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { epOut = ep; } else { epIn = ep; } } } if (epOut == null || epIn == null) { throw new IllegalArgumentException("not all endpoints found"); } mEndpointOut = epOut; mEndpointIn = epIn; } // return device serial number public String getSerial() { return mSerial; } // get an OUT request from our pool public UsbRequest getOutRequest() { synchronized(mOutRequestPool) { if (mOutRequestPool.isEmpty()) { UsbRequest request = new UsbRequest(); request.initialize(mDeviceConnection, mEndpointOut); return request; } else { return mOutRequestPool.removeFirst(); } } } // return an OUT request to the pool public void releaseOutRequest(UsbRequest request) { synchronized (mOutRequestPool) { mOutRequestPool.add(request); } } // get an IN request from the pool public UsbRequest getInRequest() { synchronized(mInRequestPool) { if (mInRequestPool.isEmpty()) { UsbRequest request = new UsbRequest(); request.initialize(mDeviceConnection, mEndpointIn); return request; } else { return mInRequestPool.removeFirst(); } } } public void start() { mWaiterThread.start(); connect(); } public AdbSocket openSocket(String destination) { AdbSocket socket; synchronized (mSockets) { int id = mNextSocketId++; socket = new AdbSocket(this, id); mSockets.put(id, socket); } if (socket.open(destination)) { return socket; } else { return null; } } private AdbSocket getSocket(int id) { synchronized (mSockets) { return mSockets.get(id); } } public void socketClosed(AdbSocket socket) { synchronized (mSockets) { mSockets.remove(socket.getId()); } } // send a connect command private void connect() { AdbMessage message = new AdbMessage(); message.set(AdbMessage.A_CNXN, AdbMessage.A_VERSION, AdbMessage.MAX_PAYLOAD, "host::\0"); message.write(this); } // handle connect response private void handleConnect(AdbMessage message) { if (message.getDataString().startsWith("device:")) { log("connected"); mActivity.deviceOnline(this); } } public void stop() { synchronized (mWaiterThread) { mWaiterThread.mStop = true; } } // dispatch a message from the device void dispatchMessage(AdbMessage message) { int command = message.getCommand(); switch (command) { case AdbMessage.A_SYNC: log("got A_SYNC"); break; case AdbMessage.A_CNXN: handleConnect(message); break; case AdbMessage.A_OPEN: case AdbMessage.A_OKAY: case AdbMessage.A_CLSE: case AdbMessage.A_WRTE: AdbSocket socket = getSocket(message.getArg1()); if (socket == null) { log("ERROR socket not found"); } else { socket.handleMessage(message); } break; } } void log(String s) { mActivity.log(s); } private class WaiterThread extends Thread { public boolean mStop; public void run() { // start out with a command read AdbMessage currentCommand = new AdbMessage(); AdbMessage currentData = null; // FIXME error checking currentCommand.readCommand(getInRequest()); while (true) { synchronized (this) { if (mStop) { return; } } UsbRequest request = mDeviceConnection.requestWait(); if (request == null) { break; } AdbMessage message = (AdbMessage)request.getClientData(); request.setClientData(null); AdbMessage messageToDispatch = null; if (message == currentCommand) { int dataLength = message.getDataLength(); // read data if length > 0 if (dataLength > 0) { message.readData(getInRequest(), dataLength); currentData = message; } else { messageToDispatch = message; } currentCommand = null; } else if (message == currentData) { messageToDispatch = message; currentData = null; } if (messageToDispatch != null) { // queue another read first currentCommand = new AdbMessage(); currentCommand.readCommand(getInRequest()); // then dispatch the current message dispatchMessage(messageToDispatch); } // put request back into the appropriate pool if (request.getEndpoint() == mEndpointOut) { releaseOutRequest(request); } else { synchronized (mInRequestPool) { mInRequestPool.add(request); } } } } } } 

AdbMessage

  package com.android.adb; import android.hardware.usb.UsbRequest; import java.nio.ByteBuffer; import java.nio.ByteOrder; /* This class encapsulates and adb command packet */ public class AdbMessage { // command names public static final int A_SYNC = 0x434e5953; public static final int A_CNXN = 0x4e584e43; public static final int A_OPEN = 0x4e45504f; public static final int A_OKAY = 0x59414b4f; public static final int A_CLSE = 0x45534c43; public static final int A_WRTE = 0x45545257; // ADB protocol version public static final int A_VERSION = 0x01000000; public static final int MAX_PAYLOAD = 4096; private final ByteBuffer mMessageBuffer; private final ByteBuffer mDataBuffer; public AdbMessage() { mMessageBuffer = ByteBuffer.allocate(24); mDataBuffer = ByteBuffer.allocate(MAX_PAYLOAD); mMessageBuffer.order(ByteOrder.LITTLE_ENDIAN); mDataBuffer.order(ByteOrder.LITTLE_ENDIAN); } // sets the fields in the command header public void set(int command, int arg0, int arg1, byte[] data) { mMessageBuffer.putInt(0, command); mMessageBuffer.putInt(4, arg0); mMessageBuffer.putInt(8, arg1); mMessageBuffer.putInt(12, (data == null ? 0 : data.length)); mMessageBuffer.putInt(16, (data == null ? 0 : checksum(data))); mMessageBuffer.putInt(20, command ^ 0xFFFFFFFF); if (data != null) { mDataBuffer.put(data, 0, data.length); } } public void set(int command, int arg0, int arg1) { set(command, arg0, arg1, (byte[])null); } public void set(int command, int arg0, int arg1, String data) { // add trailing zero data += "\0"; set(command, arg0, arg1, data.getBytes()); } // returns the command's message ID public int getCommand() { return mMessageBuffer.getInt(0); } // returns command's first argument public int getArg0() { return mMessageBuffer.getInt(4); } // returns command's second argument public int getArg1() { return mMessageBuffer.getInt(8); } // returns command's data buffer public ByteBuffer getData() { return mDataBuffer; } // returns command's data length public int getDataLength() { return mMessageBuffer.getInt(12); } // returns command's data as a string public String getDataString() { int length = getDataLength(); if (length == 0) return null; // trim trailing zero return new String(mDataBuffer.array(), 0, length - 1); } public boolean write(AdbDevice device) { synchronized (device) { UsbRequest request = device.getOutRequest(); request.setClientData(this); if (request.queue(mMessageBuffer, 24)) { int length = getDataLength(); if (length > 0) { request = device.getOutRequest(); request.setClientData(this); if (request.queue(mDataBuffer, length)) { return true; } else { device.releaseOutRequest(request); return false; } } return true; } else { device.releaseOutRequest(request); return false; } } } public boolean readCommand(UsbRequest request) { request.setClientData(this); return request.queue(mMessageBuffer, 24); } public boolean readData(UsbRequest request, int length) { request.setClientData(this); return request.queue(mDataBuffer, length); } private static String extractString(ByteBuffer buffer, int offset, int length) { byte[] bytes = new byte[length]; for (int i = 0; i < length; i++) { bytes[i] = buffer.get(offset++); } return new String(bytes); } @Override public String toString() { String commandName = extractString(mMessageBuffer, 0, 4); int dataLength = getDataLength(); String result = "Adb Message: " + commandName + " arg0: " + getArg0() + " arg1: " + getArg1() + " dataLength: " + dataLength; if (dataLength > 0) { result += (" data: \"" + getDataString() + "\""); } return result; } private static int checksum(byte[] data) { int result = 0; for (int i = 0; i < data.length; i++) { int x = data[i]; // dang, no unsigned ints in java if (x < 0) x += 256; result += x; } return result; } } 

AdbSocket

  package com.android.adb; /* This class represents an adb socket. adb supports multiple independent * socket connections to a single device. Typically a socket is created * for each adb command that is executed. */ public class AdbSocket { private final AdbDevice mDevice; private final int mId; private int mPeerId; public AdbSocket(AdbDevice device, int id) { mDevice = device; mId = id; } public int getId() { return mId; } public boolean open(String destination) { AdbMessage message = new AdbMessage(); message.set(AdbMessage.A_OPEN, mId, 0, destination); if (! message.write(mDevice)) { return false; } synchronized (this) { try { wait(); } catch (InterruptedException e) { return false; } } return true; } public void handleMessage(AdbMessage message) { switch (message.getCommand()) { case AdbMessage.A_OKAY: mPeerId = message.getArg0(); synchronized (this) { notify(); } break; case AdbMessage.A_WRTE: mDevice.log(message.getDataString()); sendReady(); break; } } private void sendReady() { AdbMessage message = new AdbMessage(); message.set(AdbMessage.A_OKAY, mId, mPeerId); message.write(mDevice); } } 

Para obtener información adicional sobre usb y conexión, puede encontrar el siguiente artículo útil.

http://android.serverbox.ch/?p=549

El último párrafo explica algunos de los problemas que podría enfrentar. El ejemplo que proporcionan también puede mostrarle cómo proceder para leer los datos y cómo tendrá que formatear los mensajes.

Parece que enfrentas dos problemas. Una configuración de su código para leer el mensaje, que la respuesta de Puspendu aludes a, y el segundo problema que es "cómo" para comunicarse, qué mensajes usted tendrá que enviar para establecer una conexión, apretón de manos, y determinar las cosas buenas, es decir, los datos usted quiere.

Puspendu ha mostrado un ejemplo de lectura y escritura en un dispositivo. Sin embargo, me imagino que dependiendo del dispositivo que conecte, el apretón de manos y la estructura del mensaje va a cambiar, por lo tanto, tendrá que mirar esas partes hasta (miedo no sé de otros ejemplos).

  • Controlador Prestigio Multipad PMP3370B USB
  • ¿Cómo puedo determinar la longitud de los bytes recibidos del método UsbRequest.queue (..)?
  • HP TouchPad USB conduce en Android
  • Nexus 7 no es recogido por adb (cuando lo conecto a la computadora portátil a través de usb)
  • Android ADK Modo de accesorio USB / modo de host
  • Android Development Usb Transferencia
  • Android USB Host API: tamaño del búfer de transferencia masiva
  • Android Studio no detecta dispositivo Android en Windows 10
  • Android como anfitrión de ATtiny85 Digispark
  • ¿Cómo puedo comunicar un accesorio para Android con un puerto serie USB?
  • Utilice el archivo de recursos device_filter.xml para filtrar resultados de enumeración USB
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.