Android Kotlin 应用未根据接收到的蓝牙数据显示或隐藏图像

Android Kotlin app not displaying or hiding an image based on received bluetooth data

我的应用程序通过蓝牙连接到 Arduino,板上有一个由按钮控制的 LED。 LED 打开或关闭。当状态发生变化时,Arduino 将传输 1(开)或 0(关)。

我的 app/phone 连接正常。我可以在应用程序的日志中看到这些 LED 状态变化。

LOGCAT

2019-12-04 09:36:41.271 30645-32215/com.example.pigcatcher I/MainActivity: 1

2019-12-04 09:36:42.288 30645-32215/com.example.pigcatcher I/MainActivity: 0

2019-12-04 09:36:43.395 30645-32215/com.example.pigcatcher I/MainActivity: 1

2019-12-04 09:36:44.207 30645-32215/com.example.pigcatcher I/MainActivity: 0

此函数侦听那些 LED 状态更改消息:

private fun readBlueToothDataFromMothership(bluetoothSocket: android.bluetooth.BluetoothSocket) {
    val bluetoothSocketInputStream = bluetoothSocket.inputStream
    val buffer = ByteArray(256)
    var bytes: Int

    while (true) {
        try {
            bytes = bluetoothSocketInputStream.read(buffer)       
            val readMessage = String(buffer, 0, bytes)

            Log.i(LOGTAG, readMessage)

            if (readMessage.equals(1)) {
                imageView_mothership_LED_state.showOrHideImage(true)
            } else {
                imageView_mothership_LED_state.showOrHideImage(false)
            }
        } catch (e: IOException) {
            e.printStackTrace()
            break
        }
    }
}

此函数是从上面的 while 循环中调用的。

private fun View.showOrHideImage(imageShow: Boolean) {
    visibility = if (imageShow) {
        View.VISIBLE
    } else {
        View.INVISIBLE
    }
}

这是来自 .xml 文件的相关图像。

<ImageView
        android:id="@+id/imageView_mothership_button_pushed"
        android:layout_width="228dp"
        android:layout_height="204dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="75dp"
        android:contentDescription="Star"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_led_off"
        app:srcCompat="@android:drawable/btn_star_big_on" />

这就是我的 question/problem 发挥作用的地方。这不会发生。如上面的日志所示,应用程序正在查看那些 LED 状态更改消息。但是应用程序中没有任何反应。我敢肯定,我设置不正确,但我无法弄清楚我做错了什么。

编辑

我忘记包含以下内部 class,其中调用了 "readBlueToothDataFromMothership" 函数。

private inner class ConnectThread(device: BluetoothDevice): Thread() {
    private var newSocket = device.createRfcommSocketToServiceRecord(uuid)

    override fun run() {
        try {
            Log.d(LOGTAG, "Connecting bluetoothSocket")
            handler.post {
                connectedOrNotTextView.text = getString(R.string.connecting)
                connectToDeviceButton.isEnabled = false
            }
            bluetoothSocket = newSocket
            bluetoothSocket.connect()
            Log.d(LOGTAG, "Socket connected")
            handler.post {
                connectedOrNotTextView.text = getString(R.string.connected)
                connectToDeviceButton.isEnabled = false; disconnectButton.isEnabled = true
            }
        }catch (e1: Exception){
            Log.e(LOGTAG, "Error connecting bluetoothSocket, $e1")
            handler.post {
                connectedOrNotTextView.text = getString(R.string.connection_failed)
                connectToDeviceButton.isEnabled = true; disconnectButton.isEnabled = false
            }
        }
        readBlueToothDataFromMothership(bluetoothSocket)
    }
}

编辑 2

正如评论中所指出的,readMessage 是一个字符串而不是一个整数。

所以,我改变了:

if (readMessage.equals(1) {

至: 如果 (readMessage == "1") {

不,它似乎实际上是在点击 View.showOrHideImage() 函数。但是,该应用程序现在崩溃并显示以下内容:

2019-12-04 12:49:53.983 19718-19987/com.example.pigcatcher I/MainActivity: 1

2019-12-04 12:49:54.018 19718-19987/com.example.pigcatcher E/AndroidRuntime: FATAL EXCEPTION: Thread-6 Process: com.example.pigcatcher, PID: 19718 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

at com.example.pigcatcher.MainActivity.showOrHideImage(MainActivity.kt:102)

at com.example.pigcatcher.MainActivity.readBlueToothDataFromMothership(MainActivity.kt:89)

at com.example.pigcatcher.MainActivity.access$readBlueToothDataFromMothership(MainActivity.kt:31)

at com.example.pigcatcher.MainActivity$ConnectThread.run(MainActivity.kt:173)

第 102 行指向以下内容:

visibility = if (imageShow) {

第 173 行是:

readBlueToothDataFromMothership(bluetoothSocket)

来自 ConnectThread() 内部 class。

我想,我从错误的地方调用了那个函数?

因为 readMessage 是一个 String按照下面的代码

val readMessage = String(buffer, 0, bytes)

您的情况

if (readMessage.equals(1)) {
    imageView_mothership_LED_state.showOrHideImage(true)
} else {
    imageView_mothership_LED_state.showOrHideImage(false)
}

应该是

imageView_mothership_LED_state.showOrHideImage(readMessage == "1")

OR(对于 UI/Main 线程以外的线程)

imageView_mothership_LED_state.post {
    imageView_mothership_LED_state.showOrHideImage(readMessage == "1")
}
val readMessage = "1"
if(readMessage.equals(1)) System.out.println("true")
else System.out.println("false")
O/P -> false

如果我从你的代码中了解到你得到的 String 为 1 并且你正在将它与 Int 1 进行比较,因为它返回 false 并且你的条件没有得到执行

尝试在readMessage中写一个日志并打印值,这将有助于解决您的问题