蓝牙聊天中未收到消息。我的处理程序坏了吗?
message not received in Bluetooth chat. Is my handler broken?
我正在 android 开发人员的项目上工作。 BluetoothChat 的网站,它似乎可以正确发送消息但没有收到消息。在过去,
我试图创建另一个蓝牙应用程序,当连接到设备时,系统提示我确认连接并提供了个人识别码。在处理当前应用程序时,我从未收到提示。但是,它没有遇到任何异常,并且消息似乎正在发送。这是我用于管理连接的线程 class:
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()
}
}
我只是不确定我的错误在哪里。我在想我发送消息的方式有问题吗?但是当我用调试器单步执行我的代码时,我真的没有发现任何不合适的地方。现在我认为问题出在接收设备的末端,它似乎根本没有收到任何东西。我也会 post 我的 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 写我的。
我注意到您的 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 中,没有 break
的 switch
分支进入下一行代码,直到程序遇到 break
而在 Kotlin 中,条目带有 arrow/braces 定义一个分支。只需仔细检查所有 when
语句,确保它们符合预期的 Java switch
行为。
原来问题出在我的 while 循环上。 while(mState!=STATE_CONNECTED
循环应该包含 run()
函数体的其余部分。所以解决方案只是移动花括号。有时是小事。但我非常感谢我的 when 表达式的帮助。
我正在 android 开发人员的项目上工作。 BluetoothChat 的网站,它似乎可以正确发送消息但没有收到消息。在过去, 我试图创建另一个蓝牙应用程序,当连接到设备时,系统提示我确认连接并提供了个人识别码。在处理当前应用程序时,我从未收到提示。但是,它没有遇到任何异常,并且消息似乎正在发送。这是我用于管理连接的线程 class:
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()
}
}
我只是不确定我的错误在哪里。我在想我发送消息的方式有问题吗?但是当我用调试器单步执行我的代码时,我真的没有发现任何不合适的地方。现在我认为问题出在接收设备的末端,它似乎根本没有收到任何东西。我也会 post 我的 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 写我的。
我注意到您的 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 中,没有 break
的 switch
分支进入下一行代码,直到程序遇到 break
而在 Kotlin 中,条目带有 arrow/braces 定义一个分支。只需仔细检查所有 when
语句,确保它们符合预期的 Java switch
行为。
原来问题出在我的 while 循环上。 while(mState!=STATE_CONNECTED
循环应该包含 run()
函数体的其余部分。所以解决方案只是移动花括号。有时是小事。但我非常感谢我的 when 表达式的帮助。