两个Android手机通过OTG线+Usb线连接,可连接,但不无法收发数据

Yondu202 2016-09-07 02:32:22
想实现两个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);
}
}
}
}
}
};
}
...全文
2946 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_43610460 2019-06-19
  • 打赏
  • 举报
回复
这样连接可以互传json数据吗?应该怎么实现
Yondu202 2018-06-29
  • 打赏
  • 举报
回复
引用 9 楼 BlueGoDisplay 的回复:
https://blog.csdn.net/yaohui_/article/details/62435460


谢谢
BlueGoDisplay 2018-06-28
  • 打赏
  • 举报
回复
https://blog.csdn.net/yaohui_/article/details/62435460
Yondu202 2017-09-25
  • 打赏
  • 举报
回复
引用 5 楼 kongbaidepao 的回复:
这个问题有解决吗 楼主,我也是要 用OTG链接2个手机传输数据
这个问题,还没解决,之后没在看,有什么想法,可以讨论一下。
Yondu202 2017-09-25
  • 打赏
  • 举报
回复
引用 4 楼 hansion3333 的回复:
请问用OTG+数据线连接两个手机的时候会有什么提示吗?比如识别到USB设备之类的?我的插上没反应,只有一边是充电状态(USB调试状态)。这正常吗
不好意思才看到,希望你已经解决了。 我的情况是,会有提示,具体什么提示,有点忘记了,大概是是否同意连接之类的,没提示那应该是不合理的。
笑面图 2017-09-06
  • 打赏
  • 举报
回复
你这个是host主机端的USB通信吧,在host通信方式中有一个Android 设备当做device,设备端的数据读写不应该用host端的方式吧,输入输出流的获取应该是直接操作设备节点才对吧,不应该从USB manager获得……?
空白的泡 2017-08-26
  • 打赏
  • 举报
回复
这个问题有解决吗 楼主,我也是要 用OTG链接2个手机传输数据
Handev 2017-04-25
  • 打赏
  • 举报
回复
请问用OTG+数据线连接两个手机的时候会有什么提示吗?比如识别到USB设备之类的?我的插上没反应,只有一边是充电状态(USB调试状态)。这正常吗
andrew_style 2017-02-08
  • 打赏
  • 举报
回复
谢谢,我也是用这种方式给POS机分发密钥
Yondu202 2016-12-17
  • 打赏
  • 举报
回复
@am256341 是的
andrew_style 2016-12-16
  • 打赏
  • 举报
回复
你只用了一段OTG线 + USB线是么?

80,349

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧