Browse Source

修复ble假连接&设置phy值为2M不成功问题

weicu
fdp 1 year ago
parent
commit
efe7985ef8
  1. 1
      lib/data/services/bluetooth_manager.dart
  2. 6
      lib/modules/home/controllers/home_controller.dart
  3. 10
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleConst.kt
  4. 52
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt
  5. 2
      local_plugins/classic_bluetooth/android/build.gradle.kts
  6. 24
      local_plugins/classic_bluetooth/android/src/main/kotlin/com/yunqiinnovation/classic_bluetooth/ClassicBluetoothPlugin.kt

1
lib/data/services/bluetooth_manager.dart

@ -46,6 +46,7 @@ class BluetoothManager extends GetxService {
/// 释放资源 /// 释放资源
@override @override
void onClose() { void onClose() {
print("蓝牙服务关闭");
_bluetoothSubscription?.cancel(); _bluetoothSubscription?.cancel();
super.onClose(); super.onClose();
} }

6
lib/modules/home/controllers/home_controller.dart

@ -171,7 +171,7 @@ class HomeController extends GetxController {
Future<void> _checkConnectionStatus() async { Future<void> _checkConnectionStatus() async {
try { try {
final currentBleState = await _bleManager.getConnectionState(); final currentBleState = await _bleManager.getConnectionState();
print('fdp--_checkConnectionStatus--currentBleState: $currentBleState');
bool hasClassicBluetooth = currentDevice != null; bool hasClassicBluetooth = currentDevice != null;
bool hasBleConnection = currentBleState == 2; bool hasBleConnection = currentBleState == 2;
bool wasConnected = _isFullyConnected.value; bool wasConnected = _isFullyConnected.value;
@ -338,7 +338,7 @@ class HomeController extends GetxController {
if (deviceName == 'unknownEquipment'.tr) { if (deviceName == 'unknownEquipment'.tr) {
return DeviceType.unknown; return DeviceType.unknown;
} }
// 通过AppConfig获取产品信息 // 通过AppConfig获取产品信息
final product = AppConfig.getproduct(deviceName); final product = AppConfig.getproduct(deviceName);
if (product != null) { if (product != null) {
@ -358,7 +358,7 @@ class HomeController extends GetxController {
return DeviceType.unknown; return DeviceType.unknown;
} }
} }
return DeviceType.unknown; return DeviceType.unknown;
} catch (e) { } catch (e) {
Logger.e(_tag, '获取设备类型失败: $e'); Logger.e(_tag, '获取设备类型失败: $e');

10
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleConst.kt

@ -39,11 +39,11 @@ object BleConst {
const val FOREGROUND_ID = 0xBEE const val FOREGROUND_ID = 0xBEE
// ================== 连接状态 ================== // ================== 连接状态 ==================
const val STATE_DISCONNECTED = 0 const val STATE_DISCONNECTED = 0//未连接
const val STATE_CONNECTING = 1 const val STATE_CONNECTING = 1//已断开连接
const val STATE_CONNECTED = 2 const val STATE_CONNECTED = 2//已连接
const val STATE_DISCONNECTING = 3 const val STATE_DISCONNECTING = 3//连接中
const val STATE_ERROR = 4 const val STATE_ERROR = 4//连接错误
// ================== 广播厂商信息 ================== // ================== 广播厂商信息 ==================
/** 厂商ID - 文档中定义为0xABEF */ /** 厂商ID - 文档中定义为0xABEF */

52
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt

@ -586,6 +586,7 @@ object BleService {
* 断开当前连接 * 断开当前连接
*/ */
fun disconnect() { fun disconnect() {
Log.d(TAG, "主动断开当前连接")
bluetoothGatt?.disconnect() bluetoothGatt?.disconnect()
updateConnectionState(BleConst.STATE_DISCONNECTING) updateConnectionState(BleConst.STATE_DISCONNECTING)
} }
@ -616,6 +617,7 @@ object BleService {
* 更新连接状态并通知回调 * 更新连接状态并通知回调
*/ */
private fun updateConnectionState(state: Int) { private fun updateConnectionState(state: Int) {
Log.d(TAG, "fdp--------- 更新连接状态: $state")
connectionState.postValue(state) connectionState.postValue(state)
notifyConnectionStateChanged(state) notifyConnectionStateChanged(state)
} }
@ -648,17 +650,24 @@ object BleService {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try { try {
// 首先尝试读取当前PHY状态 // 首先尝试读取当前PHY状态
g.readPhy() val readResult = g.readPhy()
Log.d(TAG, "读取PHY状态请求结果: $readResult")
// 然后请求设置2M PHY // 延迟一段时间后再设置PHY,确保readPhy完成
g.setPreferredPhy( Handler(Looper.getMainLooper()).postDelayed({
BluetoothDevice.PHY_LE_2M_MASK, // TX PHY: 2M try {
BluetoothDevice.PHY_LE_2M_MASK, // RX PHY: 2M val setResult = g.setPreferredPhy(
BluetoothDevice.PHY_OPTION_NO_PREFERRED BluetoothDevice.PHY_LE_2M_MASK, // TX PHY: 2M
) BluetoothDevice.PHY_LE_2M_MASK, // RX PHY: 2M
Log.d(TAG, "已请求设置PHY为2M") BluetoothDevice.PHY_OPTION_NO_PREFERRED
)
Log.d(TAG, "设置PHY为2M请求结果: $setResult")
} catch (e: Exception) {
Log.w(TAG, "设置PHY失败: ${e.message}")
}
}, 500) // 延迟500ms
} catch (e: Exception) { } catch (e: Exception) {
Log.w(TAG, "设置PHY失败: ${e.message},将使用默认1M PHY") Log.w(TAG, "读取PHY失败: ${e.message},将使用默认1M PHY")
} }
} else { } else {
Log.w(TAG, "当前Android版本不支持PHY设置(需要API 26+),使用默认1M PHY") Log.w(TAG, "当前Android版本不支持PHY设置(需要API 26+),使用默认1M PHY")
@ -669,11 +678,13 @@ object BleService {
newState == BluetoothProfile.STATE_DISCONNECTED -> { newState == BluetoothProfile.STATE_DISCONNECTED -> {
updateConnectionState(BleConst.STATE_DISCONNECTED) updateConnectionState(BleConst.STATE_DISCONNECTED)
Log.d(TAG, "监听到已断开连接")
disconnectGatt() disconnectGatt()
} }
else -> { else -> {
updateConnectionState(BleConst.STATE_ERROR) updateConnectionState(BleConst.STATE_ERROR)
Log.d(TAG, "监听到连接错误")
disconnectGatt() disconnectGatt()
} }
} }
@ -699,6 +710,7 @@ object BleService {
*/ */
override fun onPhyUpdate(gatt: BluetoothGatt, txPhy: Int, rxPhy: Int, status: Int) { override fun onPhyUpdate(gatt: BluetoothGatt, txPhy: Int, rxPhy: Int, status: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Log.d(TAG, "PHY更新回调: status=$status, txPhy=$txPhy, rxPhy=$rxPhy")
when (status) { when (status) {
BluetoothGatt.GATT_SUCCESS -> { BluetoothGatt.GATT_SUCCESS -> {
val txPhyStr = getPhyString(txPhy) val txPhyStr = getPhyString(txPhy)
@ -712,7 +724,7 @@ object BleService {
Log.w(TAG, "PHY更新出现一般性错误,可能是设备兼容性问题") Log.w(TAG, "PHY更新出现一般性错误,可能是设备兼容性问题")
} }
else -> { else -> {
Log.w(TAG, "PHY更新失败: status=$status") Log.w(TAG, "PHY更新失败: status=$status,设备可能不支持2M PHY")
} }
} }
} }
@ -1497,39 +1509,39 @@ startBytesStatistics()
failureReason.append(" - 原因: BluetoothGatt为空") failureReason.append(" - 原因: BluetoothGatt为空")
} else { } else {
// 检查连接状态 // 检查连接状态
val connectionState = bluetoothManager.getConnectionState( val State = bluetoothManager.getConnectionState(
bluetoothGatt!!.device, bluetoothGatt!!.device,
BluetoothProfile.GATT BluetoothProfile.GATT
) )
when (connectionState) { when (State) {
BluetoothProfile.STATE_DISCONNECTED -> { BluetoothProfile.STATE_DISCONNECTED -> {
failureReason.append(" - 原因: 设备已断开连接") failureReason.append(" -发送失败 原因: 设备已断开连接")
} }
BluetoothProfile.STATE_CONNECTING -> { BluetoothProfile.STATE_CONNECTING -> {
failureReason.append(" - 原因: 设备正在连接中") failureReason.append(" -发送失败 原因: 设备正在连接中")
} }
BluetoothProfile.STATE_DISCONNECTING -> { BluetoothProfile.STATE_DISCONNECTING -> {
failureReason.append(" - 原因: 设备正在断开连接") failureReason.append(" -发送失败 原因: 设备正在断开连接")
} }
BluetoothProfile.STATE_CONNECTED -> { BluetoothProfile.STATE_CONNECTED -> {
// 连接正常,检查其他原因 // 连接正常,检查其他原因
if (callWriteChar == null) { if (callWriteChar == null) {
failureReason.append(" - 原因: 写入特征值为空") failureReason.append(" -发送失败 原因: 写入特征值为空")
} else { } else {
// 检查特征值属性 // 检查特征值属性
val properties = callWriteChar!!.properties val properties = callWriteChar!!.properties
if ((properties and BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 && if ((properties and BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 &&
(properties and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) { (properties and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) {
failureReason.append(" - 原因: 特征值不支持写入操作") failureReason.append(" -发送失败 原因: 特征值不支持写入操作")
} else if (chunk.size > 512) { // BLE MTU通常限制 } else if (chunk.size > 512) { // BLE MTU通常限制
failureReason.append(" - 原因: 数据块过大 (${chunk.size} > 512字节)") failureReason.append(" -发送失败 原因: 数据块过大 (${chunk.size} > 512字节)")
} else { } else {
failureReason.append(" - 原因: 未知错误,可能是设备忙碌或缓冲区满") failureReason.append(" -发送失败 原因: 未知错误,可能是设备忙碌或缓冲区满")
} }
} }
} }
else -> { else -> {
failureReason.append(" - 原因: 未知连接状态($connectionState)") failureReason.append(" -发送失败 原因: 未知连接状态($connectionState)")
} }
} }
} }

2
local_plugins/classic_bluetooth/android/build.gradle.kts

@ -34,4 +34,6 @@ android {
dependencies { dependencies {
add("implementation", "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10") add("implementation", "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10")
// 添加对 ble_service 模块的依赖
add("compileOnly", project(":ble_service"))
} }

24
local_plugins/classic_bluetooth/android/src/main/kotlin/com/yunqiinnovation/classic_bluetooth/ClassicBluetoothPlugin.kt

@ -15,6 +15,8 @@ import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result import io.flutter.plugin.common.MethodChannel.Result
// 添加BLE服务导入
import com.yunqiinnovation.ble_service.BleService
/** ClassicBluetoothPlugin */ /** ClassicBluetoothPlugin */
class ClassicBluetoothPlugin: FlutterPlugin, MethodCallHandler { class ClassicBluetoothPlugin: FlutterPlugin, MethodCallHandler {
@ -135,7 +137,15 @@ class ClassicBluetoothPlugin: FlutterPlugin, MethodCallHandler {
ClassicBluetoothHelper.BluetoothState.TURNING_OFF -> "turningOff" ClassicBluetoothHelper.BluetoothState.TURNING_OFF -> "turningOff"
ClassicBluetoothHelper.BluetoothState.UNKNOWN -> "unknown" ClassicBluetoothHelper.BluetoothState.UNKNOWN -> "unknown"
} }
if(state == ClassicBluetoothHelper.BluetoothState.OFF){
try {
BleService.disconnect()
Log.d(TAG, "经典蓝牙设备断开,已触发BLE强制断开连接")
} catch (e: Exception) {
Log.e(TAG, "调用BLE强制断开连接失败: ${e.message}", e)
}
}
// 发送状态变化事件 // 发送状态变化事件
val eventMap = mapOf( val eventMap = mapOf(
"type" to "stateChanged", "type" to "stateChanged",
@ -156,11 +166,19 @@ class ClassicBluetoothPlugin: FlutterPlugin, MethodCallHandler {
), ),
"timestamp" to System.currentTimeMillis() "timestamp" to System.currentTimeMillis()
) )
Log.d(TAG, "经典蓝牙设备连接")
sendEvent(eventMap) sendEvent(eventMap)
} }
override fun onDeviceDisconnected(device: Map<String, String>) { override fun onDeviceDisconnected(device: Map<String, String>) {
// 经典蓝牙设备断开时,同时断开BLE连接
try {
BleService.disconnect()
Log.d(TAG, "经典蓝牙设备断开,已触发BLE强制断开连接")
} catch (e: Exception) {
Log.e(TAG, "调用BLE强制断开连接失败: ${e.message}", e)
}
// 发送设备断开事件 // 发送设备断开事件
val eventMap = mapOf( val eventMap = mapOf(
"type" to "deviceDisconnected", "type" to "deviceDisconnected",
@ -190,4 +208,4 @@ class ClassicBluetoothPlugin: FlutterPlugin, MethodCallHandler {
Log.e(TAG, "事件发送失败", e) Log.e(TAG, "事件发送失败", e)
} }
} }
} }
Loading…
Cancel
Save