Android 蓝牙聊天中未收到消息。我的手柄坏了吗?

Android 蓝牙聊天中未收到消息。我的手柄坏了吗?,android,bluetooth,kotlin,bluetooth-socket,Android,Bluetooth,Kotlin,Bluetooth Socket,我正在安卓开发平台上做这个项目。这是一个BluetoothChat的网站,它似乎正确地发送消息,但没有收到消息。过去,, 我试图创建另一个蓝牙应用程序,当连接到设备时,系统会提示我确认连接并显示pin码。在使用当前应用程序时,我从未收到过提示。然而,它没有遇到任何异常,消息似乎正在发送。下面是我管理连接的线程类: inner class ConnectedThread(val socket:BluetoothSocket, val socketType:String) : Thread(){

我正在安卓开发平台上做这个项目。这是一个BluetoothChat的网站,它似乎正确地发送消息,但没有收到消息。过去,, 我试图创建另一个蓝牙应用程序,当连接到设备时,系统会提示我确认连接并显示pin码。在使用当前应用程序时,我从未收到过提示。然而,它没有遇到任何异常,消息似乎正在发送。下面是我管理连接的线程类:

inner class ConnectedThread(val socket:BluetoothSocket, val socketType:String) : Thread(){

    val inStream = socket.inputStream
    val outStream = socket.outputStream

    init {
        mState = STATE_CONNECTED
    }

    override fun run() {
        Log.i(TAG, "BEGIN mConnectedThread")
        val buffer = ByteArray(1024)
        var bytes:Int

        while (mState == STATE_CONNECTED){
            try {
                bytes = inStream.read(buffer)

                mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget()
            }catch (ioe:IOException){
                Log.e(TAG, "disconnected", ioe)
                connectionLost()
                break
            }
        }
    }

    fun write(buffer:ByteArray){
        try {
            outStream.writeMessage(buffer, mHandler)
        }catch (ioe:IOException){
            Log.e(TAG, "Exception during write", ioe)
        }
    }

    fun cancel(){
        try {
            socket.close()
        }catch (ioe:IOException){
            Log.e(TAG, "close of connect socket failed", ioe)
        }
    }
}

}
下面是用于写入OutputStream的扩展函数:

fun OutputStream.writeMessage(buffer:ByteArray, handler:Handler? = null){
write(buffer)

handler?.let {
    it.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
            .sendToTarget()
}
}
我只是不确定我的错误在哪里。我想这是因为我发送信息的方式有问题?但是当我使用调试器逐步检查代码时,我真的没有看到任何不合适的地方。现在我想问题出在接收设备的末端,它似乎根本没有接收任何东西。我将发布我的处理程序和广播接收器:

val mHandler = object:Handler(){
    override fun handleMessage(msg: Message?) {
        when(msg!!.what) {
            Constants.MESSAGE_STATE_CHANGE -> {
                when(msg.arg1) {
                    BluetoothChatService.STATE_CONNECTED -> {
                        setStatus(getString(R.string.title_connected_to, mConnectedDeviceName))
                        mConversationArrayAdapter!!.clear()
                    }
                    BluetoothChatService.STATE_CONNECTING -> {
                        setStatus(getString(R.string.title_connecting))
                    }
                    BluetoothChatService.STATE_LISTEN -> {
                    }
                    BluetoothChatService.STATE_NONE -> {
                        setStatus(getString(R.string.title_not_connected))
                    }
                }
            }
            Constants.MESSAGE_WRITE -> {
                val writeBuf = msg.obj as ByteArray
                val writeMessage = String(writeBuf)
                mConversationArrayAdapter!!.add("Me: $writeMessage")
            }
            Constants.MESSAGE_READ -> {
                val readBuf = msg.obj as ByteArray
                val readMessage = String(readBuf, 0, msg.arg1)
                mConversationArrayAdapter!!.add("$mConnectedDeviceName: $readMessage")
            }
            Constants.MESSAGE_DEVICE_NAME -> {
                mConnectedDeviceName = msg.data.getString(Constants.DEVICE_NAME)
                if (activity!=null)Toast.makeText(activity, "Connected to $mConnectedDeviceName", Toast.LENGTH_SHORT).show()
            }
            Constants.MESSAGE_TOAST -> {
                if (activity!=null)Toast.makeText(activity, msg.data.getString(Constants.TOAST), Toast.LENGTH_SHORT).show()
            }
        }
    }
}

val mReceiver:BroadcastReceiver = object:BroadcastReceiver(){
    override fun onReceive(context: Context, intent: Intent) {
         val action = intent.action

        if (BluetoothDevice.ACTION_FOUND.equals(action)){
            val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
            if (device.bondState!=BluetoothDevice.BOND_BONDED){
                mNewDevicesArrayAdapter.add("${device.name} \n ${device.address}")
            }
        }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
            setProgressBarIndeterminateVisibility(false)
            setTitle(R.string.select_device)
            if (mNewDevicesArrayAdapter.count==0){
                val noDevices = resources.getText(R.string.none_found).toString()
                mNewDevicesArrayAdapter.add(noDevices)
            }
        }
    }

}

如果你能发现什么,请告诉我。我真的很感激你的帮助。另外,我应该提到原始代码是用Java编写的。我正在用Kotlin编写我的代码。

我注意到当块没有从Java代码复制函数时,您的Kotlin

科特林:

when (mState) {
    STATE_LISTEN -> {}
    STATE_CONNECTING -> {
        connected(socket!!, socket!!.remoteDevice, mSocketType)
    }
...
不是Java代码:

switch (mState) {
    case STATE_LISTEN:
    case STATE_CONNECTING:
        // Situation normal. Start the connected thread.
        connected(socket, socket.getRemoteDevice(), mSocketType);
        break;
...
但事实是:

switch (mState) {
    case STATE_LISTEN:
        break;
    case STATE_CONNECTING:
        // Situation normal. Start the connected thread.
        connected(socket, socket.getRemoteDevice(), mSocketType);
        break;
...
您的Kotlin代码应为:

when (mState) {
    STATE_LISTEN, STATE_CONNECTING -> {
        connected(socket!!, socket!!.remoteDevice, mSocketType)
    }
...

在Java中,开关
分支不带中断会一直延伸到下一行代码,直到程序点击一个中断,而在Kotlin中,带箭头/大括号的条目定义了一个分支。只需仔细检查所有
when
语句,确保它们遵循预期的Java
开关
行为。

我注意到,Kotlin
when
块没有从Java代码复制函数

科特林:

when (mState) {
    STATE_LISTEN -> {}
    STATE_CONNECTING -> {
        connected(socket!!, socket!!.remoteDevice, mSocketType)
    }
...
不是Java代码:

switch (mState) {
    case STATE_LISTEN:
    case STATE_CONNECTING:
        // Situation normal. Start the connected thread.
        connected(socket, socket.getRemoteDevice(), mSocketType);
        break;
...
但事实是:

switch (mState) {
    case STATE_LISTEN:
        break;
    case STATE_CONNECTING:
        // Situation normal. Start the connected thread.
        connected(socket, socket.getRemoteDevice(), mSocketType);
        break;
...
您的Kotlin代码应为:

when (mState) {
    STATE_LISTEN, STATE_CONNECTING -> {
        connected(socket!!, socket!!.remoteDevice, mSocketType)
    }
...

在Java中,开关分支不带中断会一直延伸到下一行代码,直到程序点击一个中断,而在Kotlin中,带箭头/大括号的条目定义了一个分支。只需仔细检查所有
when
语句,以确保它们遵循预期的Java
开关
行为。

结果表明问题出在我的while循环上。
while(mState!=STATE\u CONNECTED
循环应该包含
run()
函数体的其余部分。因此,解决方案只是移动大括号。有时是一些小事情。但我非常感谢when表达式的帮助。

结果表明问题出在我的while循环中。
while(mState!=STATE_CONNECTED
循环应该包含
运行()的其余部分
函数体。所以解决方案就是移动大括号。有时是一些小事情。但我非常感谢您对我的when表达式的帮助。

假设您是基于谷歌蓝牙聊天示例,那么您的
AcceptThread
是什么样子的。@MorrisonChang我刚刚在一次编辑中发布了AcceptThread的代码哦,是的,这是基于谷歌示例。假设你是基于谷歌示例蓝牙聊天,你的
AcceptThread
是什么样子的。@莫里森昌我刚刚在编辑中发布了AcceptThread的代码,是的,这是基于谷歌示例。我做了你建议的更改,但我仍然看不见ng有什么不同。这可能与没有收到允许设备连接提示有关吗?我应该看到吗?如果您只是在Kotlin中重写蓝牙聊天应用程序,提示行为应该相同。您可能希望禁用“即时运行”和/或删除该应用程序以确保安全。一种方法是在Java和Kotlin版本之间逐行查看Kotlin代码中是否存在类似于
分支时的
的其他差异。另一种方法是使用更多日志重新运行Java版本,然后对Kotlin版本重复相同的步骤。使用足够的日志应该会显示一些差异,这将指向错误。我做了您建议的更改,但仍然没有看到任何差异。这可能与没有收到允许设备连接提示有关吗?我应该看到吗?如果您只是在Kotlin中重写蓝牙聊天应用程序,提示行为应该是相同的。您可能要禁用“即时运行”和/或删除该应用程序以确保安全。一种方法是在Java和Kotlin版本之间逐行查看Kotlin代码中是否存在类似于
分支时的
的其他差异。另一种方法是使用更多日志重新运行Java版本,然后对Kotlin版本重复相同的步骤。使用足够的日志应该会出现一些差异,指出错误。