0

我正在开发 android dev 上的项目。BluetoothChat 的网站,它似乎可以正确发送消息但没有收到它们。过去,我尝试创建另一个蓝牙应用程序,当连接到设备时,系统会提示我确认连接并显示 PIN 码。在当前的应用程序上工作时,我从来没有得到提示。但是,它没有遇到任何异常,并且似乎正在发送消息。这是我用于管理连接的 Thread 类:

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

我只是不确定我的错误在哪里。我在想这是我发送消息的方式有问题吗?但是当我使用调试器单步执行我的代码时,我真的没有看到任何不合适的地方。现在我认为问题出在接收设备的末端,它似乎根本没有收到任何东西。我也会发布我的 Handler 和 broadcastReceiver :

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

}

这也是我的 AcceptThread:

    inner class AcceptThread(val secure:Boolean) : Thread(){
    var mmServerSocket:BluetoothServerSocket? = null
    val mSocketType:String = if (secure) "Secure" else "Insecure"

    init {
        try {
            mmServerSocket = if (secure){
                mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, UUID_SECURE)
            } else {
                mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, UUID_INSECURE)
            }
        }catch (ioe:IOException){
            Log.e(TAG, "Socket Type: $mSocketType listen() failed", ioe)
        }
        mState = STATE_LISTEN
    }

    override fun run() {
        Log.d(TAG, "Socket Type: $mSocketType BEGIN $this")
        name = "AcceptThread $mSocketType"

        var socket:BluetoothSocket? = null

        while (mState!=STATE_CONNECTED){
            try {
                socket = mmServerSocket!!.accept()
            }catch (ioe:IOException){
                Log.e(TAG, "Socket Type: $mSocketType accept failed", ioe)
                break
            }
        }

        socket?.let {
            synchronized(this@BluetoothChatService){
                when(mState){
                    STATE_LISTEN -> {}
                    STATE_CONNECTING -> {
                        connected(socket!!, socket!!.remoteDevice, mSocketType)
                    }
                    STATE_NONE -> {}
                    STATE_CONNECTED -> {
                        try {
                        it.close()
                    }catch (ioe:IOException){
                        Log.e(TAG, "Could not close unwanted socket", ioe)
                        }
                    }
                    else->{throw BluetoothChatServiceException("Invalid Service State")}
                }
            }
        }
        Log.i(TAG, "End mAcceptThread, Socket Type: $mSocketType")
    }

    fun cancel(){
        Log.d(TAG, "Socket Type: $mSocketType cancel $this")
        try {
            mmServerSocket!!.close()
        }catch (ioe:IOException){
            Log.e(TAG, "Socket Type: $mSocketType close() of server failed", ioe)
        }
    }

}

如果你能发现任何东西,请告诉我。我非常感谢您的帮助。另外,我应该提到原始代码是用 Java 编写的。我正在用 Kotlin 写我的。

4

2 回答 2

3

我注意到您的 Kotlinwhen块没有从 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 中,switch没有 的分支break一直到下一行代码,直到程序break在 Kotlin 中遇到一段时间,带有箭头/大括号的条目定义了一个分支。只需仔细检查所有when语句以确保它们遵循预期的 Javaswitch行为。

于 2017-11-09T07:02:49.633 回答
0

原来问题是我的while循环。while(mState!=STATE_CONNECTED循环应该包含run()函数体的其余部分。所以解决方案只是移动花括号。有时是小事。但我确实感谢我的 when 表达的帮助。

于 2017-11-14T06:41:26.753 回答