M7E - How to connect to Android over USB-c

Hello all!
I’ve been trying to connect the the M7E in my Flutter Android app, but I’ve been having some trouble. I’ve got an Android tablet running a Flutter app and in that Flutter app I detect when the M7E is connected via USB to the tablet. I then request USB permissions and connect to the M7E. The problems start when I try to connect to the M7E. I’m constantly getting the following errors when I try to execute the reader.connect() command:

E/AndroidUSBTransport( 8573): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
E/AndroidUSBTransport( 8573):   at com.thingmagic.AndroidUsbReflection.isOpen(AndroidUsbReflection.java:177)
E/AndroidUSBTransport( 8573):   at com.thingmagic.AndroidUSBTransport.open(AndroidUSBTransport.java:98)
E/AndroidUSBTransport( 8573):   at com.thingmagic.SerialReader.openSerialPort(SerialReader.java:16400)
E/AndroidUSBTransport( 8573):   at com.thingmagic.SerialReader.openPort(SerialReader.java:16411)
E/AndroidUSBTransport( 8573):   at com.thingmagic.SerialReader.connect(SerialReader.java:11077)
E/AndroidUSBTransport( 8573):   at com.example.rfid_test_flutter_v3_29.MainActivity$setupRFID$1.invokeSuspend(oldMainActivity.kt:157)
E/AndroidUSBTransport( 8573):   at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
E/AndroidUSBTransport( 8573):   at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
E/AndroidUSBTransport( 8573):   at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
E/AndroidUSBTransport( 8573):   at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:100)
E/AndroidUSBTransport( 8573):   at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
E/AndroidUSBTransport( 8573):   at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
E/AndroidUSBTransport( 8573):   at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
E/AndroidUSBTransport( 8573):   at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
E/SetupRFID( 8573): Failed to setup reader
E/SetupRFID( 8573): com.thingmagic.ReaderException: Couldn't open device
E/SetupRFID( 8573):     at com.thingmagic.AndroidUSBTransport.open(AndroidUSBTransport.java:110)
E/SetupRFID( 8573):     at com.thingmagic.SerialReader.openSerialPort(SerialReader.java:16400)
E/SetupRFID( 8573):     at com.thingmagic.SerialReader.openPort(SerialReader.java:16411)
E/SetupRFID( 8573):     at com.thingmagic.SerialReader.connect(SerialReader.java:11077)
E/SetupRFID( 8573):     at com.example.rfid_test_flutter_v3_29.MainActivity$setupRFID$1.invokeSuspend(oldMainActivity.kt:157)
E/SetupRFID( 8573):     at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
E/SetupRFID( 8573):     at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
E/SetupRFID( 8573):     at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
E/SetupRFID( 8573):     at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:100)
E/SetupRFID( 8573):     at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
E/SetupRFID( 8573):     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
E/SetupRFID( 8573):     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
E/SetupRFID( 8573):     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)

Here is the Kotlin code that I’m using to connect to the reader:

    private fun setupRFID(result: MethodChannel.Result) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                if (currentDevice == null || !usbManager.hasPermission(currentDevice)) {
                    result.error("USB_ERROR", "No USB permission or device", null)
                    return@launch
                }


                Log.d("USB", "Using device: ${currentDevice?.deviceName}, VID=${currentDevice?.vendorId}, PID=${currentDevice?.productId}")
                reader = SerialReader.create("tmr:///dev/ttyUSB0")
                // SerialReader.setSerialTransport(AndroidUSBTransport(currentDevice, usbManager))

                reader?.connect()
                reader?.paramSet("/reader/region/id", Reader.Region.NA)
                Log.d("SetupRFID", "Reader setup complete - $reader")
                result.success("Reader setup complete")
            } catch (e: Exception) {
                Log.e("SetupRFID", "Failed to setup reader", e)
                result.error("SETUP_ERROR", e.message, e)
            }
        }
    }

I have downloaded the [ ThingMagic® Mercury API BILBO 1.37.3.29] from the Jadak website and I went into the Java directory, found the sample Android project and copied the files in the sample project’s libs folder into my project’s libs folder. So I have 4 files in my Android libs folder:

  • d2xx.jar
  • jmdns-3.4.1.jar
  • ltkjava-1.0.0.6.jar
  • mercuryapi.jar

Does anybody have an idea of what I might be doing wrong? Am I creating the SerialReader with the wrong uri? Is it even possible to control the M7E from an Android app? I’ve been trying to follow the Mercury API’s programmer guide but I haven’t seen anything in there about this.

I look forward to hearing from everyone!

This is a bit outside of our expertise, but perplexity.ai had what appear to be some excellent pointers here mostly related to using slightly different formatting/inputs that might get it going

Thanks, I’ll take a look at that! I decompiled the Mercury API and went hunting through the source code so we’ll see what I can find.

1 Like