You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
304 lines
9.1 KiB
304 lines
9.1 KiB
import 'package:get/get.dart';
|
|
import '../../../routes/app_routes.dart';
|
|
import '../../../data/services/bluetooth_service.dart';
|
|
import 'package:flutter_blue_plus/flutter_blue_plus.dart' hide BluetoothService;
|
|
import '../../../core/utils/logger.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
/// 简化的配对控制器,仅用于显示已连接或配对的蓝牙耳机信息
|
|
class PairingController extends GetxController {
|
|
// 蓝牙服务
|
|
late BluetoothService _bluetoothService;
|
|
|
|
// 设备信息
|
|
final _deviceInfo = Rx<Map<String, dynamic>>({});
|
|
Map<String, dynamic> get deviceInfo => _deviceInfo.value;
|
|
|
|
// 蓝牙状态
|
|
final _isBluetoothAvailable = false.obs;
|
|
final _isBluetoothOn = false.obs;
|
|
bool get isBluetoothAvailable => _isBluetoothAvailable.value;
|
|
bool get isBluetoothOn => _isBluetoothOn.value;
|
|
|
|
// 错误消息
|
|
final _errorMessage = ''.obs;
|
|
String get errorMessage => _errorMessage.value;
|
|
|
|
// 已连接的设备列表
|
|
final _connectedDevices = <BluetoothDevice>[].obs;
|
|
List<BluetoothDevice> get connectedDevices => _connectedDevices;
|
|
|
|
// 已配对的设备列表
|
|
final _pairedDevices = <BluetoothDevice>[].obs;
|
|
List<BluetoothDevice> get pairedDevices => _pairedDevices;
|
|
|
|
// 状态描述(用于UI显示)
|
|
final _statusDescription = ''.obs;
|
|
String get statusDescription => _statusDescription.value;
|
|
|
|
// 防止重复刷新的标志
|
|
bool _isRefreshing = false;
|
|
|
|
// 上次刷新时间
|
|
DateTime? _lastRefreshTime;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
_initializeProcess();
|
|
}
|
|
|
|
// 初始化流程
|
|
Future<void> _initializeProcess() async {
|
|
_updateStatus('正在初始化...');
|
|
|
|
try {
|
|
// 获取或初始化蓝牙服务
|
|
await _getBluetoothService();
|
|
|
|
// 检查权限并获取设备信息
|
|
await _checkAndRequestPermissions();
|
|
} catch (e) {
|
|
Logger.error('初始化过程失败: $e');
|
|
_updateStatus('初始化失败');
|
|
_setError('初始化蓝牙服务失败,请重试');
|
|
}
|
|
}
|
|
|
|
// 获取蓝牙服务
|
|
Future<void> _getBluetoothService() async {
|
|
try {
|
|
// 检查是否已注册
|
|
if (Get.isRegistered<BluetoothService>()) {
|
|
_bluetoothService = Get.find<BluetoothService>();
|
|
} else {
|
|
// 初始化并注册服务
|
|
_bluetoothService = await Get.put(BluetoothService()).init();
|
|
}
|
|
|
|
// 设置蓝牙状态监听
|
|
_setupBluetoothListeners();
|
|
|
|
// 获取设备信息
|
|
_refreshDeviceInfo();
|
|
} catch (e) {
|
|
Logger.error('获取蓝牙服务失败: $e');
|
|
throw Exception('获取蓝牙服务失败: $e');
|
|
}
|
|
}
|
|
|
|
// 设置蓝牙状态监听
|
|
void _setupBluetoothListeners() {
|
|
// 监听蓝牙可用性
|
|
_isBluetoothAvailable.value = _bluetoothService.isAvailable;
|
|
ever(_bluetoothService.isAvailableObs, (bool available) {
|
|
_isBluetoothAvailable.value = available;
|
|
|
|
if (!available) {
|
|
_updateStatus('蓝牙不可用');
|
|
_setError('蓝牙不可用,请检查设备是否支持蓝牙功能');
|
|
}
|
|
});
|
|
|
|
// 监听蓝牙开关状态
|
|
_isBluetoothOn.value = _bluetoothService.isOn;
|
|
ever(_bluetoothService.isOnObs, (bool on) {
|
|
_isBluetoothOn.value = on;
|
|
|
|
if (on) {
|
|
// 蓝牙开启时,延迟一下再刷新设备信息,避免频繁刷新
|
|
Future.delayed(const Duration(milliseconds: 500), () {
|
|
_refreshDeviceInfo();
|
|
});
|
|
} else {
|
|
_updateStatus('蓝牙已关闭');
|
|
_setError('蓝牙已关闭,请开启蓝牙后再试');
|
|
}
|
|
});
|
|
|
|
// 监听已连接设备变化
|
|
_connectedDevices.value = _bluetoothService.connectedDevices;
|
|
ever(_bluetoothService.connectedDevicesObs, (List<BluetoothDevice> devices) {
|
|
_connectedDevices.value = devices;
|
|
|
|
// 只有当设备列表不为空时才刷新设备信息
|
|
if (devices.isNotEmpty) {
|
|
// 延迟一下再刷新,避免频繁刷新
|
|
Future.delayed(const Duration(milliseconds: 500), () {
|
|
_refreshDeviceInfo();
|
|
});
|
|
}
|
|
});
|
|
|
|
// 监听已配对设备变化
|
|
_pairedDevices.value = _bluetoothService.systemPairedDevices;
|
|
}
|
|
|
|
// 检查并请求权限
|
|
Future<void> _checkAndRequestPermissions() async {
|
|
_updateStatus('正在请求权限...');
|
|
|
|
try {
|
|
bool hasPermissions = await _bluetoothService.requestPermissions();
|
|
|
|
if (!hasPermissions) {
|
|
// 权限被拒绝
|
|
_handlePermissionDenied();
|
|
return;
|
|
}
|
|
|
|
// 权限已授予,检查蓝牙状态
|
|
if (!_bluetoothService.isOn) {
|
|
_updateStatus('蓝牙已关闭');
|
|
_setError('蓝牙已关闭,请开启蓝牙后再试');
|
|
return;
|
|
}
|
|
|
|
// 刷新设备信息
|
|
_refreshDeviceInfo();
|
|
} catch (e) {
|
|
Logger.error('权限请求失败: $e');
|
|
_updateStatus('权限请求失败');
|
|
_setError('权限请求失败,请手动授予蓝牙和位置权限');
|
|
}
|
|
}
|
|
|
|
// 处理权限被拒绝的情况
|
|
void _handlePermissionDenied() async {
|
|
// 检查是否永久拒绝
|
|
bool isPermanentlyDenied = false;
|
|
|
|
if (GetPlatform.isAndroid) {
|
|
PermissionStatus bluetoothScan = await Permission.bluetoothScan.status;
|
|
PermissionStatus bluetoothConnect = await Permission.bluetoothConnect.status;
|
|
PermissionStatus location = await Permission.location.status;
|
|
|
|
// 如果任一权限被永久拒绝
|
|
isPermanentlyDenied =
|
|
bluetoothScan.isPermanentlyDenied ||
|
|
bluetoothConnect.isPermanentlyDenied ||
|
|
location.isPermanentlyDenied;
|
|
}
|
|
|
|
_updateStatus('缺少必要权限');
|
|
|
|
if (isPermanentlyDenied) {
|
|
_setError('缺少必要权限,您已永久拒绝权限,请前往系统设置中手动开启');
|
|
// 显示前往设置的提示
|
|
_showGoToSettingsDialog();
|
|
} else {
|
|
_setError('缺少必要权限,请授予蓝牙和位置权限以继续');
|
|
}
|
|
}
|
|
|
|
// 显示前往设置的对话框
|
|
void _showGoToSettingsDialog() {
|
|
Get.dialog(
|
|
AlertDialog(
|
|
title: const Text('需要权限'),
|
|
content: const Text('蓝牙搜索需要特定权限,请前往系统设置开启'),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Get.back(),
|
|
child: const Text('稍后'),
|
|
),
|
|
TextButton(
|
|
onPressed: () {
|
|
Get.back();
|
|
openAppSettings();
|
|
},
|
|
child: const Text('前往设置'),
|
|
),
|
|
],
|
|
),
|
|
barrierDismissible: false,
|
|
);
|
|
}
|
|
|
|
// 刷新设备信息
|
|
Future<void> _refreshDeviceInfo() async {
|
|
// 防止重复刷新
|
|
if (_isRefreshing) return;
|
|
|
|
_isRefreshing = true;
|
|
|
|
if (!_isBluetoothOn.value) {
|
|
_updateStatus('蓝牙已关闭');
|
|
_deviceInfo.value = {};
|
|
_isRefreshing = false;
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// 更新已配对设备列表
|
|
_pairedDevices.value = _bluetoothService.systemPairedDevices;
|
|
|
|
// 查找系统已连接设备
|
|
BluetoothDevice? device = await _bluetoothService.findConnectedSystemDevice();
|
|
|
|
if (device != null) {
|
|
// 已连接设备
|
|
_deviceInfo.value = _bluetoothService.getConnectedDeviceInfo();
|
|
_updateStatus('已连接到蓝牙设备');
|
|
_goToHomePage();
|
|
} else if (_bluetoothService.lastConnectedDeviceInfo.isNotEmpty) {
|
|
// 使用上次连接的设备信息
|
|
_deviceInfo.value = _bluetoothService.lastConnectedDeviceInfo;
|
|
_updateStatus('使用上次连接的设备信息');
|
|
_goToHomePage();
|
|
} else if (_pairedDevices.isNotEmpty) {
|
|
// 使用已配对设备
|
|
BluetoothDevice pairedDevice = _pairedDevices.first;
|
|
_deviceInfo.value = _bluetoothService.getPairedDeviceInfo(pairedDevice);
|
|
_bluetoothService.setSelectedDevice(pairedDevice);
|
|
_updateStatus('已找到配对设备');
|
|
_goToHomePage();
|
|
} else {
|
|
// 没有找到任何设备
|
|
_deviceInfo.value = {};
|
|
_updateStatus('未找到已连接或配对的蓝牙设备');
|
|
}
|
|
} catch (e) {
|
|
Logger.error('刷新设备信息失败: $e');
|
|
_updateStatus('获取设备信息失败');
|
|
} finally {
|
|
_isRefreshing = false;
|
|
}
|
|
}
|
|
|
|
// 更新状态描述
|
|
void _updateStatus(String description) {
|
|
_statusDescription.value = description;
|
|
Logger.info('状态更新: $description');
|
|
}
|
|
|
|
// 设置错误信息
|
|
void _setError(String message) {
|
|
_errorMessage.value = message;
|
|
Logger.warning('错误: $message');
|
|
}
|
|
|
|
// 跳转到主页
|
|
void _goToHomePage() {
|
|
Get.offAllNamed(Routes.home, arguments: _deviceInfo.value);
|
|
}
|
|
|
|
// 刷新搜索
|
|
void refreshSearch() {
|
|
// 防止频繁刷新,限制最小刷新间隔为2秒
|
|
final now = DateTime.now();
|
|
if (_lastRefreshTime != null &&
|
|
now.difference(_lastRefreshTime!).inSeconds < 2) {
|
|
return;
|
|
}
|
|
|
|
_lastRefreshTime = now;
|
|
_refreshDeviceInfo();
|
|
}
|
|
|
|
// 跳过连接
|
|
void skipConnecting() {
|
|
Get.offAllNamed(Routes.home);
|
|
}
|
|
}
|