Я'м пытаюсь получить некоторые данные из USB-устройства, подключенные к моей Android телефон, который находится в режиме хоста. Я'м способен передавать данные на нее, но читать не получается.
Я'вэ посмотрел на несколько примеры и попробовал все, что я мог но я не'т иметь какой-либо опыт в коммуникации USB, хотя теперь я немного знаю, и я'вэ застрял на этом больше, чем я хочу признаться.
Я'м не очень хорошо знакомы с конфигурацией конечной точки, но я знаю, что мое устройство использует ЦКЗ тип, способ связи и вывода (от модели устройства) и ввода зарегистрированы.
Здесь'ы весь класс, который управляет USB-подключение с только устройство, подключенное к телефону, он's не готовый с помощью любых средств, но я'd, как, чтобы получить, что значение часть работы, прежде чем идти дальше.
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");
}
}
};
}
Я постоянно получаю -1
от прочитать()
метод, который показывает какую-то ошибку, то всегда тайм-аут. Возможно, проблема исходит от конфигурации соединения, Я'пробовала несколько (читай: проб и ошибок) и никто не работал, на удивление я не'т нужна любой конфигурации для передачи данных на устройство.
Редактировать
Необходимо также отметить, что кабель я'м через микро-USB в микро-USB и он работает только в одну сторону, что мое устройство работает на моем телефоне только когда штекер подключен к телефону и B разъем подключен к устройству, а не наоборот... это кажется очень странным. Тот факт, что я'м способен передавать данные и не получить при подключении к way_ _right остается.
Редактирование 2
Я обнаружил, что кого-то еще была такая же проблема но, кажется, он вовсе'т способен ее решить.
Редактирование 3
Я, наконец, нашел решение на этой странице:
еще большая ошибка заключается в том, что нет механизма для хозяина, чтобы уведомить устройство, которое есть раковина сведения о принимающей стороне готов принять данные. Это означает, что устройство может пытаться отправить данные, пока хозяин не'т слушать, в результате продолжительного блокирования таймауты в режимах передачи. Таким образом настоятельно рекомендуется, что виртуальный последовательный линия DTR (терминал данных готов) сигнала будет использоваться, где это возможно, чтобы определить, если хост-приложение готово для сведения.
Поэтому сигнал DTR был обязательным и все, что мне нужно было добавить в настройки:
connection.controlTransfer(0x21, 0x22, 0x1, 0, null, 0, 0);
Редактирование 4
Если кто-то заинтересован, я закончил проект и он'ы открытых источников и публикуются на мою учетную запись GitHub. Это's не стабильный все время, хотя (см. ноты) и я Дон'т план уже работаю над этим, но это работает. Не стесняйтесь использовать его для своих собственных проектов.
Вы можете использовать UsbSerial Либ от https://github.com/mik3y/usb-serial-for-android
Мой пример кода:
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());
}