Android Studio 设备在Android上断开连接后发送BLE蓝牙数据

lg40wkob  于 2023-02-09  发布在  Android
关注(0)|答案(1)|浏览(253)

BLE设备在与GATT服务器断开连接时获取数据。我尝试通过GATT服务器向BLE设备发送数据。当我尝试发送数据时,命令为(字符串)到BLE设备,调用gattscancallback,它说写入成功,但BLE设备没有任何React。但当我退出应用程序时,BLE设备获取数据,我发现BLE设备在与gatt服务器断开连接时获取数据,如何解决这个问题?这是我的GattCallback

private val gattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
    override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
        super.onConnectionStateChange(gatt, status, newState)
        if( status == BluetoothGatt.GATT_FAILURE ) {
            disconnect()
            return
        } else if( status != BluetoothGatt.GATT_SUCCESS ) {
            disconnect()
            return
        }
        if( newState == BluetoothProfile.STATE_CONNECTED ) {
            // update the connection status message

            Log.d(TAG, "Connected to the GATT server")
            gatt.discoverServices()
        } else if ( newState == BluetoothProfile.STATE_DISCONNECTED ) {
            disconnect()
        }
    }
    override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
        super.onServicesDiscovered(gatt, status)

        // check if the discovery failed
        if (status != BluetoothGatt.GATT_SUCCESS) {
            Log.e(TAG, "Device service discovery failed, status: $status")
            return
        }
        // log for successful discovery
        Log.d(TAG, "Services discovery is successful")
        isStatuschanged = "connected"

        // find command characteristics from the GATT server
        val respCharacteristic = gatt?.let { BluetoothUtils.findResponseCharacteristic(it) }
        // disconnect if the characteristic is not found
        if( respCharacteristic == null ) {
            Log.e(TAG, "Unable to find cmd characteristic")
            disconnect()
            return
        }
        gatt.setCharacteristicNotification(respCharacteristic, true)
        // UUID for notification
        val descriptor: BluetoothGattDescriptor = respCharacteristic.getDescriptor(
            UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG)
        )
        descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
        gatt.writeDescriptor(descriptor)
    }

    override fun onCharacteristicChanged(
        gatt: BluetoothGatt?,
        characteristic: BluetoothGattCharacteristic
    ) {
        super.onCharacteristicChanged(gatt, characteristic)
        //Log.d(TAG, "characteristic changed: " + characteristic.uuid.toString())
        readCharacteristic(characteristic)
    }

    override fun onCharacteristicWrite(
        gatt: BluetoothGatt?,
        characteristic: BluetoothGattCharacteristic?,
        status: Int
    ) {
        super.onCharacteristicWrite(gatt, characteristic, status)
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.d(TAG, "Characteristic written successfully")
        } else {
            Log.e(TAG, "Characteristic write unsuccessful, status: $status")
            disconnect()
        }
    }

    override fun onCharacteristicRead(
        gatt: BluetoothGatt?,
        characteristic: BluetoothGattCharacteristic,
        status: Int
    ) {
        super.onCharacteristicRead(gatt, characteristic, status)
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.d(TAG, "Characteristic read successfully")
            readCharacteristic(characteristic)
        } else {
            Log.e(TAG, "Characteristic read unsuccessful, status: $status")
            // Trying to read from the Time Characteristic? It doesnt have the property or permissions
            // set to allow this. Normally this would be an error and you would want to:
            // disconnectGattServer()
        }
    }

    /**
     * Log the value of the characteristic
     * @param characteristic
     */

}

这是我的write函数

fun write(message: String) {

    val cmdCharacteristic = BluetoothUtils.findCommandCharacteristic(bluetoothGatt!!)
    if (cmdCharacteristic == null) {
        Log.e(TAG, "Unable to find cmd characteristic")
        disconnect()
        return
    }

    cmdCharacteristic?.value = message.toByteArray()
    //bluetoothGatt!!.writeCharacteristic(cmdCharacteristic)
    val success: Boolean = bluetoothGatt!!.writeCharacteristic(cmdCharacteristic)
    if (!success) {
        Log.d("jay", "failed to write command")
    }
    Log.d("jay", "write succesful")
    //disconnect()
}

这是我的断开功能

fun disconnect() {
    Log.d("jay", "disconnect: bluetoothGatt is null? ${bluetoothGatt == null}")
    bluetoothDeviceAddress = null
    bluetoothGatt?.disconnect()
    isStatuschanged = "disconnected"
    bluetoothGatt = null
}
eqqqjvef

eqqqjvef1#

可以显示disconnect()方法吗?因为如果您编写了当应用程序关闭时中央设备将数据发送到ble设备,这意味着gattCallback的onConnectionState是通过调用newState == BluetoothProfile.STATE_DISCONNECTED和调用disconnet()方法触发的。
问题可能在于您需要明确指定特征的记录类型,例如:BluetoothGattCharacteristic.WRITE_TYPE_DEFAULTBluetoothGattCharacteristic.WRITE_TYPE_WITHOUT_RESPONSE
此外,调用代码中可能存在错误,例如,如果您使用了协程并错误地管理它们
我最近遇到了类似的问题,我通过指定特性写入类型并添加setCharacteristicNotification()方法来解决这个问题
我最近也遇到过类似的问题,但我通过指定特征记录类型并添加setCharacteristicNotification方法解决了它。我还使用了协程和一个带数据的特征记录,我将launch {}封装在里面。它看起来像这样:

if (characteristic != null){
                    // Set write type to a characteristic
                    // Set charateristic notification
                                          
                        val writeJob = launch {
                            characteristic.value = *value*
                            connectedDevice?.writeCharacteristic(characteristic)
                        }

                        writeJob.join()
 
                }

相关问题