想实现两个Android设备的USB通信实验环境如下:
1、两个Android手机,红米(作为host),小米Note(作为accessory);
2、OTG线连host,accessory连usb线,再连接OTG;
参考文章及参考代码:
https://developer.android.com/guide/topics/connectivity/usb/host.html
https://developer.android.com/guide/topics/connectivity/usb/accessory.html
https://github.com/quandoo/android2android-accessory目前情况:
可以连接到设备,但是,
host端:
用connection.bulkTransfer(EndPointIn,...)收不到数据,改为通过UsbRequest收数据可以收到;
用connection.bulkTransfer(EndPointOut,...)发送数据一直返回-1, 用UsbRequst发送数据不会报错;
accessory端:
mOutStream.write可以发送;
mInStream.read一直阻塞,收不到数据,不明原因,是否还需要更多的协议通信过程? 如何实现呢?Host代码public class UsbHostActivity extends AppCompatActivity {
private UsbManager mUsbManager;
private UsbDevice mDevice;
private List<String> mSendMsgList;// 发送数据列表
private CommunicationThread mCommThread;
private PendingIntent mPermissionIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
//初始化控件,点击按扭调用checkDevice连接设备
} private void initStringControlTransfer(final UsbDeviceConnection deviceConnection,
final int index,
final String string) {
deviceConnection.controlTransfer(0x40, 52, 0, index, string.getBytes(), string.length(), 100);
} private volatile boolean mExit = false;
private class CommunicationThread extends Thread {
@Override
public void run() {
mExit = false;
UsbEndpoint endpointIn = null;
UsbEndpoint endpointOut = null;
UsbInterface usbInterface = mDevice.getInterface(0);
if (usbInterface == null) {
return;
}
UsbDeviceConnection connection = mUsbManager.openDevice(mDevice);
if (connection == null) {
return;
}
if (!connection.claimInterface(usbInterface, true)) {
connection.close();
return;
}
// 发送控制消息
initStringControlTransfer(connection, 0, "UsbTest Example"); // MANUFACTURER
initStringControlTransfer(connection, 1, "UsbTest"); // MODEL
initStringControlTransfer(connection, 2, "Test Usb Host and Accessory"); // DESCRIPTION
initStringControlTransfer(connection, 3, "0.1"); // VERSION
initStringControlTransfer(connection, 4, ""); // URI
initStringControlTransfer(connection, 5, "42"); // SERIAL
connection.controlTransfer(0x40, 53, 0, 0, new byte[]{}, 0, 100); for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
final UsbEndpoint endpoint = usbInterface.getEndpoint(i);
if (endpoint.getDirection() == UsbConstants.USB_DIR_IN) {
endpointIn = endpoint;
}
if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
endpointOut = endpoint;
}
}
byte buff[] = new byte[256];
while (!mExit) {
final int bytesTransferred = connection.bulkTransfer(endpointIn, buff, buff.length, 100);
if (bytesTransferred > 0) {
//TODO
} else {
//流程一直走在这里,接收数据失败
}
// 此方式成功收到消息
//ByteBuffer buffer = ByteBuffer.allocate(256);
//UsbRequest request = new UsbRequest();
//request.initialize(connection, endpointIn);
//boolean ret = request.queue(buffer, 256);
//if (ret) {
// if (mConnection.requestWait() == request) {
// }
//}
synchronized (mSendMsgList) {
if (!mSendMsgList.isEmpty()){
...
int len = connection.bulkTransfer(endpointOut, sendBuff, sendBuff.length, 100);
if (len >= 0) {
//TODO
} else {
//流程一直走在这里,发送失败
}
// 此方法可以发送,不会返回错误
//UsbRequest request = new UsbRequest();
//request.initialize(mConnection, mEndOut);
//ByteBuffer buffer = ByteBuffer.wrap(text.getBytes());
//boolean ret = request.queue(buffer, text.getBytes().length);
//if (ret) {
//}
}
}
}
...
}
} private void checkDevice() {
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
if (deviceList == null || deviceList.isEmpty()) {
return;
}
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
mUsbManager.requestPermission(device, mPermissionIntent);
break;
}
} private static final String ACTION_USB_PERMISSION = "com.mobilemerit.usbhost.USB_PERMISSION";
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) {
mDevice = device;
mCommThread = new CommunicationThread();
mCommThread.start();
}
}
}
}
}
};
}
Accessory代码public class UsbDeviceActivity extends AppCompatActivity {
private UsbManager mUsbManager;
private UsbAccessory mAccessory;
private ParcelFileDescriptor mFileDescriptor;
private FileInputStream mInStream;
private FileOutputStream mOutStream;
private CommunicationThread mCommThread;
private PendingIntent mPermissionIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
//初始化控件,点击按扭调用checkDevice连接设备
} private void getAccessory() {
UsbAccessory accessory = (UsbAccessory)getIntent().getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null) {
mUsbManager.requestPermission(accessory, mPermissionIntent);
}
} private volatile boolean mExit;
private class CommunicationThread extends Thread {
@Override
public void run() {
mExit = false;
byte[] msg = new byte[256];
while (!mExit) {
try {
// 阻塞在此处
int len = mInStream.read(msg);
if (len > 0) {
//TODO
} else {
//TODO
}
} catch (final Exception e) {
break;
}
synchronized (mSendMsgList) {
if (!mSendMsgList.isEmpty()){
...
try {
mOutStream.write(sendBuff);// 可以成功发送
} catch (IOException e) {
continue;
}
}
}
}
}
} private void openAccessory(UsbAccessory accessory) {
mFileDescriptor = mUsbManager.openAccessory(accessory);
if (mFileDescriptor != null) {
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInStream = new FileInputStream(fd);
mOutStream = new FileOutputStream(fd);
if(mInStream == null || mOutStream == null){
return;
}
mCommThread = new CommunicationThread();
mCommThread.start();
}
} private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
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) {
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(accessory != null){
mAccessory = accessory;
openAccessory(mAccessory);
}
}
}
}
}
};
}
1、两个Android手机,红米(作为host),小米Note(作为accessory);
2、OTG线连host,accessory连usb线,再连接OTG;
参考文章及参考代码:
https://developer.android.com/guide/topics/connectivity/usb/host.html
https://developer.android.com/guide/topics/connectivity/usb/accessory.html
https://github.com/quandoo/android2android-accessory目前情况:
可以连接到设备,但是,
host端:
用connection.bulkTransfer(EndPointIn,...)收不到数据,改为通过UsbRequest收数据可以收到;
用connection.bulkTransfer(EndPointOut,...)发送数据一直返回-1, 用UsbRequst发送数据不会报错;
accessory端:
mOutStream.write可以发送;
mInStream.read一直阻塞,收不到数据,不明原因,是否还需要更多的协议通信过程? 如何实现呢?Host代码public class UsbHostActivity extends AppCompatActivity {
private UsbManager mUsbManager;
private UsbDevice mDevice;
private List<String> mSendMsgList;// 发送数据列表
private CommunicationThread mCommThread;
private PendingIntent mPermissionIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
//初始化控件,点击按扭调用checkDevice连接设备
} private void initStringControlTransfer(final UsbDeviceConnection deviceConnection,
final int index,
final String string) {
deviceConnection.controlTransfer(0x40, 52, 0, index, string.getBytes(), string.length(), 100);
} private volatile boolean mExit = false;
private class CommunicationThread extends Thread {
@Override
public void run() {
mExit = false;
UsbEndpoint endpointIn = null;
UsbEndpoint endpointOut = null;
UsbInterface usbInterface = mDevice.getInterface(0);
if (usbInterface == null) {
return;
}
UsbDeviceConnection connection = mUsbManager.openDevice(mDevice);
if (connection == null) {
return;
}
if (!connection.claimInterface(usbInterface, true)) {
connection.close();
return;
}
// 发送控制消息
initStringControlTransfer(connection, 0, "UsbTest Example"); // MANUFACTURER
initStringControlTransfer(connection, 1, "UsbTest"); // MODEL
initStringControlTransfer(connection, 2, "Test Usb Host and Accessory"); // DESCRIPTION
initStringControlTransfer(connection, 3, "0.1"); // VERSION
initStringControlTransfer(connection, 4, ""); // URI
initStringControlTransfer(connection, 5, "42"); // SERIAL
connection.controlTransfer(0x40, 53, 0, 0, new byte[]{}, 0, 100); for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
final UsbEndpoint endpoint = usbInterface.getEndpoint(i);
if (endpoint.getDirection() == UsbConstants.USB_DIR_IN) {
endpointIn = endpoint;
}
if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
endpointOut = endpoint;
}
}
byte buff[] = new byte[256];
while (!mExit) {
final int bytesTransferred = connection.bulkTransfer(endpointIn, buff, buff.length, 100);
if (bytesTransferred > 0) {
//TODO
} else {
//流程一直走在这里,接收数据失败
}
// 此方式成功收到消息
//ByteBuffer buffer = ByteBuffer.allocate(256);
//UsbRequest request = new UsbRequest();
//request.initialize(connection, endpointIn);
//boolean ret = request.queue(buffer, 256);
//if (ret) {
// if (mConnection.requestWait() == request) {
// }
//}
synchronized (mSendMsgList) {
if (!mSendMsgList.isEmpty()){
...
int len = connection.bulkTransfer(endpointOut, sendBuff, sendBuff.length, 100);
if (len >= 0) {
//TODO
} else {
//流程一直走在这里,发送失败
}
// 此方法可以发送,不会返回错误
//UsbRequest request = new UsbRequest();
//request.initialize(mConnection, mEndOut);
//ByteBuffer buffer = ByteBuffer.wrap(text.getBytes());
//boolean ret = request.queue(buffer, text.getBytes().length);
//if (ret) {
//}
}
}
}
...
}
} private void checkDevice() {
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
if (deviceList == null || deviceList.isEmpty()) {
return;
}
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
mUsbManager.requestPermission(device, mPermissionIntent);
break;
}
} private static final String ACTION_USB_PERMISSION = "com.mobilemerit.usbhost.USB_PERMISSION";
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) {
mDevice = device;
mCommThread = new CommunicationThread();
mCommThread.start();
}
}
}
}
}
};
}
Accessory代码public class UsbDeviceActivity extends AppCompatActivity {
private UsbManager mUsbManager;
private UsbAccessory mAccessory;
private ParcelFileDescriptor mFileDescriptor;
private FileInputStream mInStream;
private FileOutputStream mOutStream;
private CommunicationThread mCommThread;
private PendingIntent mPermissionIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
//初始化控件,点击按扭调用checkDevice连接设备
} private void getAccessory() {
UsbAccessory accessory = (UsbAccessory)getIntent().getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null) {
mUsbManager.requestPermission(accessory, mPermissionIntent);
}
} private volatile boolean mExit;
private class CommunicationThread extends Thread {
@Override
public void run() {
mExit = false;
byte[] msg = new byte[256];
while (!mExit) {
try {
// 阻塞在此处
int len = mInStream.read(msg);
if (len > 0) {
//TODO
} else {
//TODO
}
} catch (final Exception e) {
break;
}
synchronized (mSendMsgList) {
if (!mSendMsgList.isEmpty()){
...
try {
mOutStream.write(sendBuff);// 可以成功发送
} catch (IOException e) {
continue;
}
}
}
}
}
} private void openAccessory(UsbAccessory accessory) {
mFileDescriptor = mUsbManager.openAccessory(accessory);
if (mFileDescriptor != null) {
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInStream = new FileInputStream(fd);
mOutStream = new FileOutputStream(fd);
if(mInStream == null || mOutStream == null){
return;
}
mCommThread = new CommunicationThread();
mCommThread.start();
}
} private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
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) {
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(accessory != null){
mAccessory = accessory;
openAccessory(mAccessory);
}
}
}
}
}
};
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货