想实现两个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.   

    你只用了一段OTG线 + USB线是么?
      

  2.   

    谢谢,我也是用这种方式给POS机分发密钥
      

  3.   

    请问用OTG+数据线连接两个手机的时候会有什么提示吗?比如识别到USB设备之类的?我的插上没反应,只有一边是充电状态(USB调试状态)。这正常吗
      

  4.   

    这个问题有解决吗 楼主,我也是要   用OTG链接2个手机传输数据
      

  5.   

    你这个是host主机端的USB通信吧,在host通信方式中有一个Android 设备当做device,设备端的数据读写不应该用host端的方式吧,输入输出流的获取应该是直接操作设备节点才对吧,不应该从USB manager获得……?
      

  6.   

    https://blog.csdn.net/yaohui_/article/details/62435460
      

  7.   

    这样连接可以互传json数据吗?应该怎么实现