Android O связывается с камерой DLSR с помощью кабеля USB3.0 - PullRequest
0 голосов
/ 20 декабря 2018

этот код хорошо работает, когда версия Android не 8. *. 0 или USB-кабель камеры не 3.0, но когда Android O соответствует usb3.0, я могу отправить только одну команду на камеру и получить один ответ, когда яотправить вторую команду, метод send возвращает -1, что означает, что отправка не удалась.

найти устройство

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

запросить разрешение

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

интерфейс запроса и получить конечную точку

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

класс UsbConnection просто упаковать EndPoints

команда отправки

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
}

байтбуфер содержит данные, которые должны быть отправлены

получение ответа

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

Я нашел, если размер отправленногоdata - максимальный размер пакета конечной точки, я могу отправить вторую команду успешно, и если я читаю размер данных, точно равный размеру данных ответа, я могу прочитать второй ответ успешно, но в третьей команде это не работает, этовсегда терпит неудачу, когда я посылаю третью команду

Любая помощь будет оценена ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...