0
votes

I am looking for an Android USB-Serial example in Kotlin. Almost every example I have found is in Java, which I suppose is still ok, but I haven't been able to compile any of them successfully. I am quite new to Android / Kotlin, and just want to get the most basic send and receive going from my phone to a USB device over an OTG cable. Any help / pointers / suggestions gratefully received. Thank you Garrett

1
Unfortunately, the USB APIs have been privatized in the past years. I haven't touched USB via Android since 2017, but at that time it was really difficult to find good examples. Your best bet is to take the java examples, and copy paste them. IntelliJ offers to convert to Java to Kotlin, and then you can work through updating the code to your needs.Benjamin Charais
Thanks Benjamin - I have tried that. The only Java project I got working was so complicated and weighty, that, as a relative newbie, I had difficulty extracting any re-usability from itgarrettb

1 Answers

0
votes

I was able to dig up some old code to reference for this. I don't guarantee any of it, but in combination with your Java based libraries, this should be a start, and then combining with reference from: https://github.com/mik3y/usb-serial-for-android

One thing I recall being a massive problem, was we had to have the app as a system level app. Which was either by installing it in a specific directory and checking the "System App" permission.

class SerialPort(private val serialPort: Any) {
    private val serialPortR: Class<*> = Class.forName("android.hardware.SerialPort")

    fun read(buffer: ByteBuffer): Int {
        val read = serialPortR.getMethod("read", ByteBuffer::class.java)
        return read.invoke(this, buffer) as Int
    }

    fun write(buffer: ByteBuffer, len: Int) {
        val write = serialPortR.getMethod("write", ByteBuffer::class.java, Int::class.java)
        write.invoke(this, buffer, len)
    }

    fun close() {
        val close = serialPortR.getMethod("close")
        close.invoke(this)
    }
}

class SerialManager private constructor(private val serialService: Any) {
    private val serialManager: Class<*> = Class.forName("android.hardware.SerialManager")

    fun openSerialPort(port: String, baudRate: Int): SerialPort = reflectSerialPort(port, baudRate)

    private fun reflectSerialPort(port: String, baudRate: Int): SerialPort {
        serialManager.cast(this)
        val openSerialPort = serialManager.getMethod("openSerialPort", String::class.java, Int::class.java)
        return SerialPort(openSerialPort.invoke(serialManager, port, baudRate))
    }

    companion object {
        fun get(c: Context): SerialManager {
            val serialService = getSerialService(c)
            return SerialManager(serialService)
        }

        @SuppressLint("WrongConstant")
        private fun getSerialService(c: Context) = c.getSystemService("serial") ?: throw Exception("No Serial Service")
    }
}