java - Android蓝牙IOException:读取失败,套接字可能关闭或超时,读取ret:-1
问题描述
我在 Android 蓝牙 API 中连接客户端套接字时遇到问题。我已经阅读了这些帖子:this one , this one , this one and this one 根据这些帖子,我的代码如下所示,但仍然无法正常工作:
class MainActivity : AppCompatActivity()
{
private val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
private var connectThread: ConnectThread? = null
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (bluetoothAdapter != null)
{
if (!bluetoothAdapter.isEnabled)
bluetoothAdapter.enable()
val devices = bluetoothAdapter.bondedDevices.toTypedArray()
if (devices.isNotEmpty())
{
connectThread = ConnectThread(devices[0])
connectThread!!.run()
}
}
else
Log.i("BluetoothTest", "No bluetooth supported")
}
override fun onDestroy()
{
super.onDestroy()
connectThread!!.cancel()
}
private inner class ConnectThread(device: BluetoothDevice) : Thread()
{
//private val socket = device.createRfcommSocketToServiceRecord(UUID.fromString ("00001101-0000-1000-8000-00805F9B34FB"))
private val socket = device.javaClass.getMethod("createRfcommSocket", (Int::class
.javaPrimitiveType)).invoke(device, 2) as BluetoothSocket
override fun run()
{
bluetoothAdapter.cancelDiscovery()
socket.connect()
}
fun cancel()
{
socket.close()
}
}
}
以下是在 socket.connect() 上返回错误的日志:
--------- beginning of crash
05-15 15:59:19.553 24176-24176/com.bluetoothtest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.bluetoothtest, PID: 24176
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bluetoothtest/com.bluetoothtest.MainActivity}: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:685)
at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:697)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:374)
at com.bluetoothtest.MainActivity.onCreate(MainActivity.kt:36)
at android.app.Activity.performCreate(Activity.java:6999)
at android.app.Activity.performCreate(Activity.java:6990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
由于我在 Android 7.1 和 8.1 上的套接字的端口值,似乎问题出现在 Android 4.3 之后有人知道如何使蓝牙在 Android 上工作吗?
解决方案
最后,根本原因是因为无法读取套接字的输入流。那是因为服务器端没有具有相同 UUID的打开套接字。
因此,为了解决这个问题,我们需要一个在另一侧具有相同 UUID 的侦听套接字,对我来说,它是 python 中的树莓派:
from bluetooth import *
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "YOUR UUID"
advertise_service( server_sock, "SampleServer", service_id = uuid, service_classes = [ uuid, SERIAL_PORT_CLASS ], profiles = [ SERIAL_PORT_PROFILE ])
print("Waiting for connection on RFCOMM channel %d" % port)
client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)
try:
while True:
data = client_sock.recv(1024)
if len(data) == 0: break
print("received [%s]" % data)
except IOError:
pass
print("disconnected")
client_sock.close()
server_sock.close()
print("all done")
来自https://github.com/karulis/pybluez/blob/master/examples/simple/rfcomm-server.py
推荐阅读
- php - 如何在包含 html 的变量中执行 php 代码
- java - jna4412392371053342294.dll:找不到依赖库
- html - 更改嵌入文本文件的字体大小?
- javascript - 如何在 React select 中显示数据
- c# - 使用 LINQ Lambda 选择的 ASP.Net MVC 异步导致“在前一个操作完成之前,在此上下文上启动了第二个操作。”
- swiftui - SwiftUI、导航视图和目的地的动画过渡。VStack 有效,但 List 无效
- python - 我无法使用 python 和请求登录谷歌帐户
- c - strtok_r 随机插入新行
- javascript - 如何检查轮播中的对象重叠 - JavaScript
- node.js - 雷迪斯。当大部分都使用 WebSocket Secure 完成时,我将如何将这个内存数据库用于我的项目