无法再次打开新的蓝牙插座
Cannot open new bluetooth socket again
关闭蓝牙套接字后,我试图用同样的方式打开新的,但 android 告诉我,套接字已关闭。
这是我的蓝牙连接服务器线程:
private inner class AcceptBLThread : Thread() {
private val mmServerSocket: BluetoothServerSocket? by lazy {
bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(
connectionBLName,
UUID.fromString(connectionUUID)
)
}
override fun run() {
// Keep listening until exception occurs or a socket is returned.
isAwaitingForBLConnectionVal = true
Log.i(tag, "Awaiting for BL connection")
while (isAwaitingForBLConnectionVal) {
val socket: BluetoothSocket? = try {
mmServerSocket?.accept()
} catch (e: IOException) {
Log.e(tag, "Socket's accept() method failed", e)
isAwaitingForBLConnectionVal = false
null
}
socket?.also {
manageConnectedSocket(it)
mmServerSocket?.close()
isAwaitingForBLConnectionVal = false
if(settings.isSlaveIndoorMeasurementsEnabled) {
awaitForBLConnection()
}
}
}
}
// Closes the connect socket and causes the thread to finish.
fun cancel() {
try {
mmServerSocket?.close()
isBLMasterConnectedVal = false
if(settings.isSlaveIndoorMeasurementsEnabled) {
awaitForBLConnection()
}
Log.i(tag, "Master device disconnected")
Log.i(tag, "Closed server socket")
} catch (e: IOException) {
Log.e(tag, "Could not close the connect socket", e)
}
}
@Suppress("MoveVariableDeclarationIntoWhen")
private fun manageConnectedSocket(socket: BluetoothSocket) {
isBLMasterConnectedVal = true
val inStream = socket.inputStream
val outStream = socket.outputStream
val buffer = ByteArray(1024)
var numBytes: Int
if(socket.isConnected) {
Log.i(tag, "Master device connected")
} else {
Log.i(tag, "Master device connect failure")
}
// Keep listening to the InputStream until an exception occurs.
while (true) {
// Read from the InputStream.
numBytes = try {
inStream.read(buffer)
} catch (e: IOException) {
Log.d(tag, "Input stream was disconnected", e)
break
}
if(numBytes == 1) {
val commandType = BluetoothCommands.from(buffer.toInt())
when(commandType) {
BluetoothCommands.START_INDOOR -> {
}
BluetoothCommands.STOP_INDOOR -> {
}
BluetoothCommands.SEND_DATA_TO_MASTER -> {
}
BluetoothCommands.ON_MASTER_DISCONNECTED -> {
Log.i(tag, "Master disconnected BL event")
Handler(Looper.getMainLooper()).postDelayed({
if(settings.isSlaveIndoorMeasurementsEnabled
&& !isAwaitingForBLConnectionVal) {
awaitForBLConnection()
}
}, 1000)
}
}
}
}
}
}
这是我来自客户端连接的线程:
private inner class ConnectBLThread(
val device: BluetoothDevice,
val connectionCallback: BLCallback?
) : Thread() {
private val socket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
device.createRfcommSocketToServiceRecord(UUID.fromString(connectionUUID))
}
override fun run() {
bluetoothAdapter.cancelDiscovery()
socket?.let { socket ->
try {
Log.i(tag, "Connecting to slave device")
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
socket.connect()
// The connection attempt succeeded. Perform work associated with
// the connection in a separate thread.
manageConnectedSocket(socket)
} catch (exc: Exception) {
Log.i(tag, "Connecting to slave device failed")
connectionCallback?.onConnectionError(device.address)
}
}
}
// Closes the client socket and causes the thread to finish.
fun cancel() {
try {
socket?.outputStream?.write(
BluetoothCommands.ON_MASTER_DISCONNECTED.value.toByteArray()
)
Handler(Looper.getMainLooper()).postDelayed({
socket?.close()
connectionCallback?.onDisconnected(device.address)
},500)
} catch (e: IOException) {
Log.e(tag, "Could not close the client socket", e)
}
}
private fun manageConnectedSocket(socket: BluetoothSocket) {
Log.i(tag, "Connected to slave device successfully")
slaveSockets[device.address] = socket
connectionCallback?.onConnectedSuccessfully()
}
}
我希望在连接到设备时或不连接时有复选框。但是取消选中此复选框后,我无法再次连接。我在 ConnectBLThread 中调用“cancel()”方法,它调用
socket?.also {
manageConnectedSocket(it)
mmServerSocket?.close()
isAwaitingForBLConnectionVal = false
if(settings.isSlaveIndoorMeasurementsEnabled) {
awaitForBLConnection()
}
}
在带有 mmServerSocket?.close() 的 AcceptBLThread 中,然后我尝试再次连接。启动 ConnectBLThread,它给我套接字,它甚至说它已连接但已关闭。
如何在上次关闭后创建具有相同 UUID 的新套接字?或者我根本不应该关闭套接字,因为创建新套接字是不可能的?
原因是在关闭套接字之前关闭流。
socket.inputStream.close()
socket.outputStream.close()
Thread.sleep(1000) //it's imprortant too. You should give a time to close streams before close the socket
socket.close()
关闭蓝牙套接字后,我试图用同样的方式打开新的,但 android 告诉我,套接字已关闭。
这是我的蓝牙连接服务器线程:
private inner class AcceptBLThread : Thread() {
private val mmServerSocket: BluetoothServerSocket? by lazy {
bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(
connectionBLName,
UUID.fromString(connectionUUID)
)
}
override fun run() {
// Keep listening until exception occurs or a socket is returned.
isAwaitingForBLConnectionVal = true
Log.i(tag, "Awaiting for BL connection")
while (isAwaitingForBLConnectionVal) {
val socket: BluetoothSocket? = try {
mmServerSocket?.accept()
} catch (e: IOException) {
Log.e(tag, "Socket's accept() method failed", e)
isAwaitingForBLConnectionVal = false
null
}
socket?.also {
manageConnectedSocket(it)
mmServerSocket?.close()
isAwaitingForBLConnectionVal = false
if(settings.isSlaveIndoorMeasurementsEnabled) {
awaitForBLConnection()
}
}
}
}
// Closes the connect socket and causes the thread to finish.
fun cancel() {
try {
mmServerSocket?.close()
isBLMasterConnectedVal = false
if(settings.isSlaveIndoorMeasurementsEnabled) {
awaitForBLConnection()
}
Log.i(tag, "Master device disconnected")
Log.i(tag, "Closed server socket")
} catch (e: IOException) {
Log.e(tag, "Could not close the connect socket", e)
}
}
@Suppress("MoveVariableDeclarationIntoWhen")
private fun manageConnectedSocket(socket: BluetoothSocket) {
isBLMasterConnectedVal = true
val inStream = socket.inputStream
val outStream = socket.outputStream
val buffer = ByteArray(1024)
var numBytes: Int
if(socket.isConnected) {
Log.i(tag, "Master device connected")
} else {
Log.i(tag, "Master device connect failure")
}
// Keep listening to the InputStream until an exception occurs.
while (true) {
// Read from the InputStream.
numBytes = try {
inStream.read(buffer)
} catch (e: IOException) {
Log.d(tag, "Input stream was disconnected", e)
break
}
if(numBytes == 1) {
val commandType = BluetoothCommands.from(buffer.toInt())
when(commandType) {
BluetoothCommands.START_INDOOR -> {
}
BluetoothCommands.STOP_INDOOR -> {
}
BluetoothCommands.SEND_DATA_TO_MASTER -> {
}
BluetoothCommands.ON_MASTER_DISCONNECTED -> {
Log.i(tag, "Master disconnected BL event")
Handler(Looper.getMainLooper()).postDelayed({
if(settings.isSlaveIndoorMeasurementsEnabled
&& !isAwaitingForBLConnectionVal) {
awaitForBLConnection()
}
}, 1000)
}
}
}
}
}
}
这是我来自客户端连接的线程:
private inner class ConnectBLThread(
val device: BluetoothDevice,
val connectionCallback: BLCallback?
) : Thread() {
private val socket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
device.createRfcommSocketToServiceRecord(UUID.fromString(connectionUUID))
}
override fun run() {
bluetoothAdapter.cancelDiscovery()
socket?.let { socket ->
try {
Log.i(tag, "Connecting to slave device")
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
socket.connect()
// The connection attempt succeeded. Perform work associated with
// the connection in a separate thread.
manageConnectedSocket(socket)
} catch (exc: Exception) {
Log.i(tag, "Connecting to slave device failed")
connectionCallback?.onConnectionError(device.address)
}
}
}
// Closes the client socket and causes the thread to finish.
fun cancel() {
try {
socket?.outputStream?.write(
BluetoothCommands.ON_MASTER_DISCONNECTED.value.toByteArray()
)
Handler(Looper.getMainLooper()).postDelayed({
socket?.close()
connectionCallback?.onDisconnected(device.address)
},500)
} catch (e: IOException) {
Log.e(tag, "Could not close the client socket", e)
}
}
private fun manageConnectedSocket(socket: BluetoothSocket) {
Log.i(tag, "Connected to slave device successfully")
slaveSockets[device.address] = socket
connectionCallback?.onConnectedSuccessfully()
}
}
我希望在连接到设备时或不连接时有复选框。但是取消选中此复选框后,我无法再次连接。我在 ConnectBLThread 中调用“cancel()”方法,它调用
socket?.also {
manageConnectedSocket(it)
mmServerSocket?.close()
isAwaitingForBLConnectionVal = false
if(settings.isSlaveIndoorMeasurementsEnabled) {
awaitForBLConnection()
}
}
在带有 mmServerSocket?.close() 的 AcceptBLThread 中,然后我尝试再次连接。启动 ConnectBLThread,它给我套接字,它甚至说它已连接但已关闭。 如何在上次关闭后创建具有相同 UUID 的新套接字?或者我根本不应该关闭套接字,因为创建新套接字是不可能的?
原因是在关闭套接字之前关闭流。
socket.inputStream.close()
socket.outputStream.close()
Thread.sleep(1000) //it's imprortant too. You should give a time to close streams before close the socket
socket.close()