the following process works fine on phones that are not in the Android O system version, and works well when Android O connects to USB2.0, only when Android O connects to USB3.0/3.1 The sending and receiving of the first instruction is normal, but the second instruction fails. Return-1. I have tried to modify the third parameter of the bulkTransfer method (that is, the data length) to the MaXPacketSize of EndPoint, and the third parameter of the bulkTransfer method to the size of the received data, which is 0x0c in my use, so that the second instruction can be sent and received normally. But the third instruction will still fail, which may have something to do with this, but at most two instructions have been sent successfully
< H2 > looking for USB devices < / H2 > val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager
//this method just filter the vendorId of device
val dev = lookupCompatibleDevice(usbManager) ?: return
< H2 > apply for permission < / H2 >
if (usbManager.hasPermission(dev)){
//if has permission already
connect(context, dev)
}else {
//request permission and connect device in receiver
registerPermissionReceiver(context)
val mPermissionIntent = PendingIntent.getBroadcast(context, 0, Intent(
ACTION_USB_PERMISSION), 0)
usbManager.requestPermission(dev, mPermissionIntent)
}
< H2 > get EndPoint < / H2 >
fun connect(context: Context, device: UsbDevice){
val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager
var intf : UsbInterface? = null
(0 until (device.interfaceCount)).forEach {
val i = device.getInterface(it)
if (i.interfaceClass == UsbConstants.USB_CLASS_STILL_IMAGE){
intf = i
}
}
if (intf == null){
//PTP interface not found
connectListener.onConnectStateChange(ConnectState.NO_PTP_INTERFACE)
return
}
if (device.interfaceCount > 1){
connectListener.onConnectStateChange(ConnectState.MULTI_INTERFACE)
return
}
val conn = usbManager.openDevice(device) ?: return
if (conn.claimInterface(intf, true)){
Log.i(TAG, "claim interface successful")
}else {
Log.i(TAG, "claim interface failure")
}
var bulkIn: UsbEndpoint? = null
var bulkOut: UsbEndpoint? = null
(0 until (intf!!.endpointCount)).forEach {
val endpoint = intf!!.getEndpoint(it)
Log.d(TAG, "connect: endpoint type: " + endpoint.type + "direction: " + endpoint.direction)
if (endpoint.type == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (endpoint.direction == UsbConstants.USB_DIR_IN) {
bulkIn = endpoint
} else if (endpoint.direction == UsbConstants.USB_DIR_OUT) {
bulkOut = endpoint
}
}
}
if (bulkIn == null || bulkOut == null) {
//
connectListener.onConnectStateChange(ConnectState.BULK_NOT_ENOUGH)
return
}
if (AppConfig.LOG) {
Log.i(TAG, "Found compatible USB interface")
Log.i(TAG, "Interface class " + intf?.interfaceClass)
Log.i(TAG, "Interface subclass " + intf?.interfaceSubclass)
Log.i(TAG, "Interface protocol " + intf?.interfaceProtocol)
Log.i(TAG, "Bulk out max size " + bulkOut?.maxPacketSize)
Log.i(TAG, "Bulk in max size " + bulkIn?.maxPacketSize)
}
val connection = UsbConnection(context.applicationContext, device.vendorId, conn, bulkOut!!, bulkIn!!, object : Connection.ConnectStateListener {
override fun onConnectStateChange(state: ConnectState) {
connectListener.onConnectStateChange(state)
if (state.state < ConnectState.WIFI_ACKNOWLEDGED.state){
CameraHolder.disconnectCamera(context)
}
}
})
when(device.vendorId){
CanonVendorId -> { camera = CanonCamera(context, connection, cameraListener) }
NikonVendorId -> { camera = NikonCamera(context, connection, cameraListener) }
SonyVendorId -> { camera = SonyCamera(context, connection, cameraListener) }
else -> { camera = Camera(context, connection, cameraListener) }
}
connectListener.onConnectStateChange(ConnectState.USB_CONNECTED)
}
the UsbConnection class just pack the EndPoints
< H2 > send instructions < / H2 >fun send(): Int {
if (AppConfig.LOG_PACKETS){
PacketUtil.logHexdump(TAG, byteBuffer.array(), byteBuffer.position(), byteBuffer.limit())
}
val res = connection.bulkTransfer(bulkOut, byteBuffer.array(), byteBuffer.limit(), timeout)
return res
}
the bytebuffer contains the data that needs to be send
< H2 > receive instructions < / H2 >res = connection.bulkTransfer(bulkIn, `in`.array(), maxPacketSize, AppConfig.USB_TRANSFER_TIMEOUT)
Any help will be appreciated..