Browse Source

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

newdev_shunjiawei
fdp 1 year ago
parent
commit
ca4d5e2410
  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
void onClose() {
print("蓝牙服务关闭");
_bluetoothSubscription?.cancel();
super.onClose();
}

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

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

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

@ -34,4 +34,6 @@ android {
dependencies {
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.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
// 添加BLE服务导入
import com.yunqiinnovation.ble_service.BleService
/** ClassicBluetoothPlugin */
class ClassicBluetoothPlugin: FlutterPlugin, MethodCallHandler {
@ -135,7 +137,15 @@ class ClassicBluetoothPlugin: FlutterPlugin, MethodCallHandler {
ClassicBluetoothHelper.BluetoothState.TURNING_OFF -> "turningOff"
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(
"type" to "stateChanged",
@ -156,11 +166,19 @@ class ClassicBluetoothPlugin: FlutterPlugin, MethodCallHandler {
),
"timestamp" to System.currentTimeMillis()
)
Log.d(TAG, "经典蓝牙设备连接")
sendEvent(eventMap)
}
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(
"type" to "deviceDisconnected",
@ -190,4 +208,4 @@ class ClassicBluetoothPlugin: FlutterPlugin, MethodCallHandler {
Log.e(TAG, "事件发送失败", e)
}
}
}
}
Loading…
Cancel
Save