Android O communicate with a DLSR camera by USB3.0 cable

76
December 20, 2018, at 8:10 PM

these code works well when Android version is not 8.*.0 or usb cable of camera is not 3.0, but when Android O meet usb3.0, I can only send one command to camera and receive one reply, when I send the second command, the send method returns -1, which means send failed.

find device

    val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager
    //this method just filter the vendorId of device
    val dev = lookupCompatibleDevice(usbManager) ?: return

request permission

    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)
    }

claim interface and get endpoint

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

send command

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

receive response

res = connection.bulkTransfer(bulkIn, `in`.array(), maxPacketSize, AppConfig.USB_TRANSFER_TIMEOUT)
//placeholder...

I found if the size of sended data is the max packet size of endpoint, I can send the second command successful, and if I read data size exactly equals the data size of response, I can read the second response successful, but this is not work in the third command, it's always fail when I send the third command

Any help will be appreciated..

READ ALSO
What&#39;s the difference between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES

What's the difference between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES

I'm new to OpenGL ES in android developmentI found two types of texture during my study:

80
ffmpeg some frames are skipped or not getting visible

ffmpeg some frames are skipped or not getting visible

I am changing frames in every second of video, But some of them are getting glitched or not getting visible properlyMy all frames are

91
IPFS read data from network

IPFS read data from network

I am working on one application, where I am using IPFS for storing and getting files

98
as3 Android access csv file in download folder

as3 Android access csv file in download folder

For my app I want to send the user a text file of data on an e-mail which they save in the download folder on their Android device

100