uniapp蓝牙搜索连接展示蓝牙设备包含信号显示

发布时间:2026/10/28 1:33:22
uniapp蓝牙搜索连接展示蓝牙设备包含信号显示 参考界面注意在manifest.json里在 安卓打包配置里permissions里配置蓝牙模块uses-permission android:name\android.permission.BLUETOOTH\/, //蓝牙管理权限 uses-permission android:name\android.permission.BLUETOOTH_ADMIN\/, // 蓝牙配对权限 uses-permission android:name\android.permission.BLUETOOTH_PRIVILEGED\/, uses-permission android:name\android.permission.ACCESS_FINE_LOCATION\/, uses-permission android:name\android.permission.ACCESS_COARSE_LOCATION\/, //用于使用蓝牙扫描附件其他的蓝牙设备 Android 12 uses-permission android:name\android.permission.BLUETOOTH_SCAN\/, //用于允许当前的设备被其他的蓝牙设备所发现 Android 12 uses-permission android:name\android.permission.BLUETOOTH_ADVERTISE\/, //用于连接之前已经配对过的蓝牙设备 Android 12 uses-permission android:name\android.permission.BLUETOOTH_CONNECT\/以下是参考代码template view classcontent :class{ landscape: isLandscape } view classtext-area text classtitle{{title}}/text /view !-- 蓝牙状态显示 -- view classbluetooth-section view classstatus-card view classstatus-header text classstatus-title蓝牙连接状态/text view classstatus-indicator :classbluetoothStatus {{ getStatusText(bluetoothStatus) }} /view /view view classdevice-info v-ifconnectedDevice text classinfo-label已连接设备:/text text classinfo-value{{ connectedDevice.name }}/text text classinfo-label设备ID:/text text classinfo-value{{ connectedDevice.deviceId }}/text /view view classno-device v-else text classno-device-text未连接任何设备/text /view /view !-- 操作按钮 -- view classaction-buttons :class{ landscape-buttons: isLandscape } button classbtn clickinitBluetooth :disabledloading {{ loading ? 操作中... : 初始化蓝牙 }} /button button classbtn clickstartBluetoothDiscovery :disabled!bluetoothAvailable 搜索设备 /button button classbtn btn-secondary clickstopBluetoothDiscovery :disabled!isDiscovering 停止搜索 /button !-- 添加刷新按钮 -- button classbtn btn-refresh clickrefreshDevices :disabledloading 刷新设备列表 /button !-- button classbtn btn-danger clickcloseBluetooth :disabled!bluetoothAvailable 关闭蓝牙 /button -- /view !-- 服务信息 -- view classservice-section v-ifservices.length 0 view classservice-card text classsection-title设备服务信息/text view classservice-info text classinfo-label服务数量:/text text classinfo-value{{ services.length }} 个/text text classinfo-label当前服务:/text text classinfo-value{{ currentServiceId }}/text text classinfo-label特征值数量:/text text classinfo-value{{ characteristics.length }} 个/text /view /view /view !-- 数据通信 -- view classcommunication-section v-ifdeviceConnected view classcommunication-card text classsection-title数据通信/text !-- 发送数据 -- view classsend-section text classinput-label发送数据:/text view classinput-group input classdata-input v-modelsendData placeholder输入要发送的数据 / button classbtn btn-send clicksendDataToDevice发送/button /view /view !-- 接收数据 -- view classreceive-section view classreceive-header text classreceive-title接收数据 (最近50条)/text text classreceive-count{{ receivedData.length }} 条/text /view scroll-view classreceive-scroll scroll-y view v-for(item, index) in receivedData :keyindex classdata-item text classdata-time{{ item.timestamp }}/text text classdata-content{{ item.data }}/text /view /scroll-view /view /view /view !-- 设备列表 -- !-- 设备列表 -- view classdevices-list v-ifdevices.length 0 text classlist-title可用设备 ({{ devices.length }})/text view classsort-info text classsort-text按信号强度排序 ▼/text /view scroll-view classdevices-scroll scroll-y view v-fordevice in devices :keydevice.deviceId classdevice-item clickconnectToDevice(device) view classdevice-main text classdevice-name{{ device.name || 未知设备 }}/text text classdevice-id{{ device.deviceId }}/text /view view classdevice-rssi view classrssi-indicator :classgetRSSILevel(device.RSSI)/view text classrssi-text{{ getRSSIDisplay(device.RSSI) }}/text /view view classconnect-indicator :class{ connected: device.connected } {{ device.connected ? 已连接 : 点击连接 }} /view /view /scroll-view /view !-- 连接状态提示 -- view classconnection-status v-ifconnectionStatus text :class[status-text, connectionStatus.type] {{ connectionStatus.message }} /text /view /view /view /template script export default { data() { return { bluetoothStatus: unavailable, bluetoothAvailable: false, isDiscovering: false, devices: [], connectedDevice: null, loading: false, connectionStatus: null, isLandscape: false, // 添加横屏状态 windowHeight: 0, windowWidth: 0, // 新增蓝牙服务相关数据 services: [], // 设备服务列表 characteristics: [], // 特征值列表 currentServiceId: , // 当前选择的服务ID currentCharacteristicId: , // 当前选择的特征值ID notifyEnabled: false, // 是否开启通知 deviceConnected: false, // 设备连接状态 receivedData: [], // 接收到的数据 sendData: // 要发送的数据 } }, onLoad() { this.initBluetooth(); this.checkBluetoothStatus(); this.checkScreenOrientation(); // 检查初始屏幕方向 this.startOrientationListener(); // 开始监听屏幕方向变化 // 添加权限检查 this.checkAndRequestPermissions(); }, onUnload() { // 页面卸载时关闭蓝牙 this.closeBluetooth(); }, methods: { // 获取信号强度显示文本 getRSSIDisplay(rssi) { if (rssi null || rssi undefined) return 未知; return ${rssi} dBm; }, // 获取信号强度等级 getRSSILevel(rssi) { if (rssi null || rssi undefined) return unknown; if (rssi -50) return excellent; // 优秀 if (rssi -60) return good; // 良好 if (rssi -70) return fair; // 一般 if (rssi -80) return weak; // 较弱 return very-weak; // 很弱 }, // 刷新设备列表 async refreshDevices() { this.loading true; try { // 清空当前列表 this.devices []; // 重新获取已配对设备 await this.getPairedDevices(); // 重新开始搜索 if (this.bluetoothAvailable !this.isDiscovering) { await this.startBluetoothDiscovery(); } this.connectionStatus { message: 设备列表已刷新, type: success }; } catch (error) { console.error(刷新设备列表失败:, error); } finally { this.loading false; } }, // 检查并请求权限 async checkAndRequestPermissions() { try { // 检查位置权限蓝牙扫描需要 const result await uni.authorize({ scope: scope.location }); console.log(位置权限授权结果:, result); // 对于 Android 12还需要蓝牙扫描权限 // if (uni.getSystemInfoSync().platform android) { // // 尝试请求蓝牙相关权限 // await this.requestBluetoothPermissions(); // } } catch (error) { console.log(权限授权失败或用户拒绝:, error); // 可以在这里引导用户去设置页面开启权限 // this.showPermissionGuide(); } }, // 请求蓝牙权限 async requestBluetoothPermissions() { return new Promise((resolve, reject) { // 这里可以使用原生插件或自定义方式请求权限 // 暂时使用提示方式 uni.showModal({ title: 蓝牙权限提示, content: 应用需要蓝牙权限来扫描和连接设备请确保已授予相关权限, showCancel: false, success: resolve, fail: reject }); }); }, async getConnectedDevices() { try { const res await uni.getConnectedBluetoothDevices({ services: [] // 空数组表示获取所有已连接设备 }); console.log(已连接的蓝牙设备:, res.devices); if (res.devices res.devices.length 0) { // 处理已连接的设备 res.devices.forEach(device { // 更新设备列表中的连接状态 this.devices this.devices.map(d { if (d.deviceId device.deviceId) { return { ...d, connected: true }; } return d; }); // 设置当前连接设备 this.connectedDevice { name: device.name, deviceId: device.deviceId }; }); // 排序设备列表 this.sortDevicesByRSSI(); } else { console.log(没有已连接的设备); this.connectedDevice null; } } catch (err) { console.error(获取已连接设备失败:, err); // 如果API不支持尝试使用其他方法 this.fallbackGetConnectedDevices(); } }, // 备选方法通过设备列表筛选已连接设备 fallbackGetConnectedDevices() { uni.getBluetoothDevices({ success: (res) { const connectedDevices res.devices.filter(device { // 这里可以根据实际需求判断设备是否已连接 // 有些平台可能没有明确的连接状态标识 return device.connected || this.isDeviceConnected(device.deviceId); }); if (connectedDevices.length 0) { const device connectedDevices[0]; this.connectedDevice { name: device.name, deviceId: device.deviceId }; // 更新设备列表连接状态 this.devices this.devices.map(d { if (d.deviceId device.deviceId) { return { ...d, connected: true }; } return d; }); // 排序设备列表 this.sortDevicesByRSSI(); } } }); }, // 检查设备是否已连接 isDeviceConnected(deviceId) { // 这里可以添加您的设备连接判断逻辑 return this.connectedDevice this.connectedDevice.deviceId deviceId; }, // 检查屏幕方向 checkScreenOrientation() { const res uni.getSystemInfoSync(); this.windowHeight res.windowHeight; this.windowWidth res.windowWidth; this.isLandscape res.windowWidth res.windowHeight; }, // 监听屏幕方向变化 startOrientationListener() { uni.onWindowResize((res) { this.windowHeight res.size.windowHeight; this.windowWidth res.size.windowWidth; this.isLandscape res.size.windowWidth res.size.windowHeight; }); }, // 在页面卸载时取消监听 beforeDestroy() { uni.offWindowResize(); }, // 检查蓝牙状态 async checkBluetoothStatus() { try { const res await uni.getBluetoothAdapterState(); console.log(蓝牙适配器状态:, res); this.bluetoothStatus res.available ? enabled : disabled; this.bluetoothAvailable res.available; this.isDiscovering res.discovering; } catch (error) { console.error(获取蓝牙状态失败:, error); this.bluetoothStatus unavailable; this.bluetoothAvailable false; } }, // 初始化蓝牙 async initBluetooth() { this.loading true; this.connectionStatus { message: 正在初始化蓝牙..., type: info }; try { // 先检查权限 await this.checkAndRequestPermissions(); // 打开蓝牙适配器 await uni.openBluetoothAdapter(); this.connectionStatus { message: 蓝牙初始化成功, type: success }; this.bluetoothStatus enabled; this.bluetoothAvailable true; // 开始监听蓝牙状态变化 this.startBluetoothListeners(); // 先获取已连接设备再开始搜索 await this.getConnectedDevices(); // 如果已经有连接设备就不需要搜索了 if (!this.connectedDevice) { setTimeout(() { this.startBluetoothDiscovery(); }, 1000); } } catch (error) { console.error(蓝牙初始化失败:, error); this.handleBluetoothError(error); // 如果是权限问题提示用户 if (error.errCode 10013) { this.showPermissionGuide(); } } finally { this.loading false; } }, // 开始监听蓝牙事件 startBluetoothListeners() { // 蓝牙适配器状态变化 uni.onBluetoothAdapterStateChange((res) { console.log(蓝牙适配器状态变化:, res); this.bluetoothAvailable res.available; this.isDiscovering res.discovering; this.bluetoothStatus res.available ? enabled : disabled; this.getConnectedDevices(); }); // 发现新设备 - 增强日志 uni.onBluetoothDeviceFound((res) { // console.log(发现新设备详情:, res.devices); // 过滤设备包括经典蓝牙设备 const filteredDevices res.devices.filter(device { return device.deviceId (device.name || device.localName); }); // console.log(过滤后的设备:, filteredDevices); this.addOrUpdateDevices(filteredDevices); }); // 蓝牙连接状态变化 uni.onBLEConnectionStateChange((res) { console.log(蓝牙连接状态变化:, res); this.handleConnectionStateChange(res); }); }, // 添加或更新设备列表并按信号强度排序 addOrUpdateDevices(newDevices) { newDevices.forEach(newDevice { const existingIndex this.devices.findIndex(d d.deviceId newDevice.deviceId); if (existingIndex -1) { // 更新现有设备信息保留连接状态 this.devices[existingIndex] { ...this.devices[existingIndex], ...newDevice }; } else { // 添加新设备 this.devices.push({ ...newDevice, connected: false }); } }); // 按信号强度排序信号最强的排在最上面 this.sortDevicesByRSSI(); }, // 按信号强度排序设备 sortDevicesByRSSI() { this.devices.sort((a, b) { // 处理 RSSI 值为 null 或 undefined 的情况 const rssiA a.RSSI ! null a.RSSI ! undefined ? a.RSSI : -999; const rssiB b.RSSI ! null b.RSSI ! undefined ? b.RSSI : -999; // RSSI 值越大表示信号越强所以降序排列 return rssiB - rssiA; }); }, // 开始搜索设备 async startBluetoothDiscovery() { if (!this.bluetoothAvailable) { this.connectionStatus { message: 蓝牙未初始化或不可用, type: error }; return; } try { // 清空设备列表 this.devices []; this.connectionStatus { message: 正在搜索蓝牙设备..., type: info }; // 先获取已配对设备 await this.getPairedDevices(); // 开始搜索新设备 await uni.startBluetoothDevicesDiscovery({ allowDuplicatesKey: true, // 改为 true 以获取更多设备 interval: 1000, // 缩短间隔 powerLevel: high // 高功率扫描 }); this.isDiscovering true; this.connectionStatus { message: 正在搜索蓝牙设备..., type: info }; // 30秒后自动停止搜索给更多时间 setTimeout(() { this.stopBluetoothDiscovery(); }, 30000); } catch (error) { console.error(开始搜索失败:, error); this.connectionStatus { message: 搜索失败: ${error.errMsg || error.message}, type: error }; } }, // 获取已配对设备 async getPairedDevices() { return new Promise((resolve) { uni.getBluetoothDevices({ success: (res) { console.log(已配对设备:, res.devices); if (res.devices res.devices.length 0) { // 过滤出有效的设备 const validDevices res.devices.filter(device device.name device.deviceId ); this.addOrUpdateDevices(validDevices); } resolve(); }, fail: (err) { console.error(获取已配对设备失败:, err); resolve(); } }); }); }, // 停止搜索设备 async stopBluetoothDiscovery() { try { await uni.stopBluetoothDevicesDiscovery(); this.isDiscovering false; this.connectionStatus { message: 已停止搜索设备, type: info }; } catch (error) { console.error(停止搜索失败:, error); } }, // 连接到设备 async connectToDevice(device) { if (device.connected) { this.connectionStatus { message: 设备已连接, type: info }; return; } this.loading true; this.connectionStatus { message: 正在连接 ${device.name || 设备}..., type: info }; try { // 创建蓝牙连接 await uni.createBLEConnection({ deviceId: device.deviceId, timeout: 10000 }); this.connectionStatus { message: 连接成功正在发现服务..., type: info }; // 等待一段时间让连接稳定 await new Promise(resolve setTimeout(resolve, 500)); // 获取蓝牙设备服务 await this.getBLEDeviceServices(device.deviceId); this.deviceConnected true; // 更新设备连接状态 this.updateDeviceConnectionStatus(device.deviceId, true); } catch (error) { console.error(连接设备失败:, error); this.connectionStatus { message: 连接失败: ${error.errMsg || error.message}, type: error }; this.updateDeviceConnectionStatus(device.deviceId, false); } finally { this.loading false; } }, // 获取蓝牙设备服务 async getBLEDeviceServices(deviceId) { try { const res await uni.getBLEDeviceServices({ deviceId: deviceId }); console.log(获取设备服务成功:, res.services); this.services res.services; if (res.services res.services.length 0) { // 默认选择第一个服务 this.currentServiceId res.services[0].uuid; this.connectionStatus { message: 发现 ${res.services.length} 个服务正在获取特征值..., type: info }; // 获取该服务的特征值 await this.getBLEDeviceCharacteristics(deviceId, this.currentServiceId); } else { this.connectionStatus { message: 未发现任何服务, type: warning }; } } catch (error) { console.error(获取设备服务失败:, error); this.connectionStatus { message: 获取服务失败: ${error.errMsg || error.message}, type: error }; } }, // 获取蓝牙设备特征值 async getBLEDeviceCharacteristics(deviceId, serviceId) { try { const res await uni.getBLEDeviceCharacteristics({ deviceId: deviceId, serviceId: serviceId }); console.log(获取特征值成功:, res.characteristics); this.characteristics res.characteristics; if (res.characteristics res.characteristics.length 0) { this.connectionStatus { message: 发现 ${res.characteristics.length} 个特征值, type: success }; // 自动寻找可读写的特征值 await this.setupCharacteristic(deviceId, serviceId, res.characteristics); } else { this.connectionStatus { message: 未发现任何特征值, type: warning }; } } catch (error) { console.error(获取特征值失败:, error); this.connectionStatus { message: 获取特征值失败: ${error.errMsg || error.message}, type: error }; } }, // 设置特征值自动寻找合适的特征值并开启通知 async setupCharacteristic(deviceId, serviceId, characteristics) { // 优先寻找支持 notify 和 write 的特征值 const suitableChar characteristics.find(char { return char.properties.notify char.properties.write; }); if (suitableChar) { this.currentCharacteristicId suitableChar.uuid; // 开启通知 await this.enableBLECharacteristicNotification(deviceId, serviceId, suitableChar.uuid); this.connectionStatus { message: 已开启数据通知可以通信了, type: success }; } else { // 如果没有同时支持 notify 和 write 的特征值寻找其他可用特征值 const notifyChar characteristics.find(char char.properties.notify); const writeChar characteristics.find(char char.properties.write); if (notifyChar) { await this.enableBLECharacteristicNotification(deviceId, serviceId, notifyChar.uuid); } if (writeChar) { this.currentCharacteristicId writeChar.uuid; } this.connectionStatus { message: 已配置可用特征值, type: info }; } }, // 开启特征值通知 async enableBLECharacteristicNotification(deviceId, serviceId, characteristicId) { try { await uni.notifyBLECharacteristicValueChange({ deviceId: deviceId, serviceId: serviceId, characteristicId: characteristicId, state: true }); this.notifyEnabled true; console.log(开启通知成功); // 监听特征值变化 uni.onBLECharacteristicValueChange((res) { this.onBLECharacteristicValueChange(res); }); } catch (error) { console.error(开启通知失败:, error); this.connectionStatus { message: 开启通知失败: ${error.errMsg || error.message}, type: error }; } }, // 接收到蓝牙设备数据 onBLECharacteristicValueChange(res) { console.log(接收到蓝牙数据:, res); // 将 ArrayBuffer 转换为十六进制字符串 const hexString this.ab2hex(res.value); const timestamp new Date().toLocaleTimeString(); this.receivedData.unshift({ timestamp: timestamp, data: hexString, raw: res.value }); // 限制接收数据条数 if (this.receivedData.length 50) { this.receivedData this.receivedData.slice(0, 50); } console.log([${timestamp}] 接收数据: ${hexString}); }, // 向蓝牙设备发送数据 async sendDataToDevice() { if (!this.deviceConnected || !this.currentCharacteristicId || !this.sendData) { this.connectionStatus { message: 请先连接设备并输入要发送的数据, type: warning }; return; } try { // 将字符串转换为 ArrayBuffer const buffer this.str2ab(this.sendData); await uni.writeBLECharacteristicValue({ deviceId: this.connectedDevice.deviceId, serviceId: this.currentServiceId, characteristicId: this.currentCharacteristicId, value: buffer }); const timestamp new Date().toLocaleTimeString(); this.connectionStatus { message: 数据发送成功: ${this.sendData}, type: success }; console.log([${timestamp}] 发送数据: ${this.sendData}); // 清空发送数据 this.sendData ; } catch (error) { console.error(发送数据失败:, error); this.connectionStatus { message: 发送失败: ${error.errMsg || error.message}, type: error }; } }, // ArrayBuffer 转十六进制字符串 ab2hex(buffer) { const hexArr Array.prototype.map.call( new Uint8Array(buffer), bit (00 bit.toString(16)).slice(-2) ); return hexArr.join( ); }, // 字符串转 ArrayBuffer str2ab(str) { const buf new ArrayBuffer(str.length); const bufView new Uint8Array(buf); for (let i 0; i str.length; i) { bufView[i] str.charCodeAt(i); } return buf; }, // 更新设备连接状态 updateDeviceConnectionStatus(deviceId, connected) { this.devices this.devices.map(device { if (device.deviceId deviceId) { return { ...device, connected }; } return device; }); if (connected) { const device this.devices.find(d d.deviceId deviceId); if (device) { this.connectedDevice { ...device }; } } else { this.connectedDevice null; } // 更新连接状态后重新排序 this.sortDevicesByRSSI(); }, // 断开设备连接 async disconnectDevice() { if (!this.connectedDevice) return; try { // 关闭通知 if (this.notifyEnabled) { await uni.notifyBLECharacteristicValueChange({ deviceId: this.connectedDevice.deviceId, serviceId: this.currentServiceId, characteristicId: this.currentCharacteristicId, state: false }); this.notifyEnabled false; } // 断开连接 await uni.closeBLEConnection({ deviceId: this.connectedDevice.deviceId }); // 重置状态 this.updateDeviceConnectionStatus(this.connectedDevice.deviceId, false); this.deviceConnected false; this.services []; this.characteristics []; this.receivedData []; this.connectionStatus { message: 设备已断开连接, type: info }; } catch (error) { console.error(断开连接失败:, error); } }, // 关闭蓝牙 async closeBluetooth() { try { // 停止搜索 if (this.isDiscovering) { await this.stopBluetoothDiscovery(); } // 断开已连接的设备 if (this.connectedDevice) { await uni.closeBLEConnection({ deviceId: this.connectedDevice.deviceId }); } // 关闭蓝牙适配器 await uni.closeBluetoothAdapter(); this.bluetoothStatus disabled; this.bluetoothAvailable false; this.devices []; this.connectedDevice null; this.connectionStatus { message: 蓝牙已关闭, type: info }; } catch (error) { console.error(关闭蓝牙失败:, error); } }, // 获取状态文本 getStatusText(status) { const statusMap { unavailable: 不可用, available: 可用, enabled: 已开启, disabled: 已关闭 }; return statusMap[status] || 未知; }, // 处理蓝牙错误 handleBluetoothError(error) { let errorMessage 蓝牙操作失败; if (error.errCode 10001) { errorMessage 蓝牙适配器不可用请检查手机蓝牙是否开启; } else if (error.errCode 10002) { errorMessage 没有找到指定设备; } else if (error.errCode 10003) { errorMessage 连接失败请重试; } else if (error.errCode 10004) { errorMessage 没有找到指定服务; } else if (error.errCode 10005) { errorMessage 没有找到指定特征值; } else if (error.errCode 10006) { errorMessage 当前连接已断开; } else if (error.errCode 10007) { errorMessage 当前特征值不支持此操作; } else if (error.errCode 10008) { errorMessage 其余所有系统上报的异常; } else if (error.errCode 10009) { errorMessage Android 系统特有系统版本低于 4.3 不支持 BLE; } else if (error.errCode 10012) { errorMessage 连接超时; } else if (error.errCode 10013) { errorMessage 未授权位置权限; } this.connectionStatus { message: errorMessage, type: error }; } } } /script style .content { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; padding: 20rpx; } .logo { height: 120rpx; width: 120rpx; margin-top: 40rpx; margin-bottom: 30rpx; } .text-area { display: flex; justify-content: center; margin-bottom: 40rpx; } .title { font-size: 36rpx; color: #8f8f94; } /* 蓝牙相关样式 */ .bluetooth-section { width: 100%; max-width: 700rpx; } .status-card { background: white; border-radius: 16rpx; padding: 30rpx; margin-bottom: 30rpx; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); position: fixed; width: 90%; z-index: 10000; } .status-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20rpx; } .status-title { font-size: 32rpx; font-weight: bold; color: #333; } .status-indicator { padding: 8rpx 16rpx; border-radius: 20rpx; font-size: 24rpx; color: white; } .status-indicator.enabled { background-color: #34C759; } .status-indicator.disabled { background-color: #FF3B30; } .status-indicator.unavailable { background-color: #FF9500; } .status-indicator.available { background-color: #007AFF; } .device-info { margin-top: 20rpx; } .info-label { display: block; font-size: 26rpx; color: #666; margin-bottom: 8rpx; } .info-value { display: block; font-size: 28rpx; color: #333; font-weight: 500; margin-bottom: 16rpx; word-break: break-all; } .no-device { text-align: center; padding: 40rpx 0; } .no-device-text { font-size: 28rpx; color: #999; } .action-buttons { margin-bottom: 30rpx; margin-top: 300rpx; text-align: center; /* 可选居中显示按钮 */ } .btn { background-color: #007AFF; color: white; border: none; border-radius: 12rpx; padding: 24rpx; font-size: 28rpx; display: inline-block; margin: 10rpx; /* 添加间距 */ min-width: 150rpx; /* 控制按钮最小宽度 */ } .btn:disabled { background-color: #cccccc; } .btn-secondary { background-color: #34C759; } .btn-danger { background-color: #FF3B30; } .devices-list { background: white; border-radius: 16rpx; padding: 30rpx; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); } .list-title { font-size: 30rpx; font-weight: bold; color: #333; margin-bottom: 20rpx; display: block; } .devices-scroll { max-height: 500rpx; } .device-item { display: flex; justify-content: space-between; align-items: center; padding: 24rpx; border-bottom: 1rpx solid #f0f0f0; background: #fafafa; border-radius: 12rpx; margin-bottom: 16rpx; transition: all 0.3s ease; } .device-item:active { background: #f0f0f0; transform: scale(0.98); } .device-main { flex: 1; min-width: 0; /* 防止内容溢出 */ } .device-name { display: block; font-size: 28rpx; color: #333; font-weight: 500; margin-bottom: 8rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .device-id { display: block; font-size: 22rpx; color: #666; word-break: break-all; font-family: monospace; } .device-rssi { margin: 0 20rpx; } .rssi-text { font-size: 24rpx; color: #999; } .connect-indicator { padding: 8rpx 16rpx; border-radius: 12rpx; font-size: 22rpx; color: white; background-color: #007AFF; } .connect-indicator.connected { background-color: #34C759; } .connection-status { margin-top: 20rpx; padding: 20rpx; border-radius: 12rpx; text-align: center; } .status-text { font-size: 26rpx; font-weight: 500; } .status-text.success { color: #34C759; } .status-text.error { color: #FF3B30; } .status-text.warning { color: #FF9500; } .status-text.info { color: #007AFF; } /* 横屏样式 */ .landscape { flex-direction: row; flex-wrap: wrap; } .landscape .text-area { width: 100%; margin-bottom: 20rpx; } .landscape .bluetooth-section { display: flex; flex-direction: row; flex-wrap: wrap; width: 100%; } .landscape .status-card { flex: 1; min-width: 400rpx; margin-right: 20rpx; } .landscape .action-buttons { flex: 1; min-width: 300rpx; display: flex; flex-direction: column; justify-content: flex-start; } .landscape .action-buttons.landscape-buttons { flex-direction: row; flex-wrap: wrap; } .landscape .action-buttons.landscape-buttons .btn { flex: 1; min-width: 200rpx; margin-right: 10rpx; margin-bottom: 10rpx; } .landscape .devices-list { width: 100%; margin-top: 20rpx; } /* 平板大屏适配 */ media screen and (min-width: 768px) { .bluetooth-section { max-width: 1200rpx; } .landscape .status-card, .landscape .action-buttons { min-width: 500rpx; } } .service-section, .communication-section { width: 100%; margin-top: 30rpx; } .service-card, .communication-card { background: white; border-radius: 16rpx; padding: 30rpx; margin-bottom: 30rpx; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); } .section-title { font-size: 30rpx; font-weight: bold; color: #333; margin-bottom: 20rpx; display: block; } .send-section { margin-bottom: 30rpx; } .input-label { font-size: 26rpx; color: #666; margin-bottom: 10rpx; display: block; } .input-group { display: flex; gap: 20rpx; } .data-input { flex: 1; border: 1rpx solid #ddd; border-radius: 8rpx; padding: 20rpx; font-size: 26rpx; } .btn-send { background-color: #34C759; min-width: 120rpx; } .receive-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15rpx; } .receive-title { font-size: 26rpx; color: #333; font-weight: 500; } .receive-count { font-size: 24rpx; color: #666; } .receive-scroll { max-height: 400rpx; border: 1rpx solid #f0f0f0; border-radius: 8rpx; padding: 15rpx; } .data-item { padding: 15rpx 0; border-bottom: 1rpx solid #f5f5f5; } .data-item:last-child { border-bottom: none; } .data-time { font-size: 22rpx; color: #999; margin-right: 15rpx; } .data-content { font-size: 24rpx; color: #333; word-break: break-all; } .sort-info { margin-bottom: 15rpx; text-align: center; } .sort-text { font-size: 24rpx; color: #007AFF; background: rgba(0, 122, 255, 0.1); padding: 8rpx 16rpx; border-radius: 20rpx; } .device-rssi { margin: 0 20rpx; display: flex; flex-direction: column; align-items: center; min-width: 120rpx; } .rssi-indicator { width: 60rpx; height: 8rpx; border-radius: 4rpx; margin-bottom: 8rpx; transition: all 0.3s ease; } .rssi-indicator.excellent { width: 80rpx; background: linear-gradient(90deg, #34C759, #34C759); box-shadow: 0 0 8rpx rgba(52, 199, 89, 0.5); } .rssi-indicator.good { width: 70rpx; background: linear-gradient(90deg, #34C759 70%, #FFD60A 100%); } .rssi-indicator.fair { width: 60rpx; background: linear-gradient(90deg, #FFD60A 50%, #FF9500 100%); } .rssi-indicator.weak { width: 50rpx; background: linear-gradient(90deg, #FF9500 30%, #FF3B30 100%); } .rssi-indicator.very-weak { width: 40rpx; background: #FF3B30; } .rssi-indicator.unknown { width: 40rpx; background: #8E8E93; } .rssi-text { font-size: 22rpx; color: #666; text-align: center; } .btn-refresh { background-color: #FF9500; } /style需要注意的是如果要实现整正的与蓝牙设备连接通信手机需要开启定位服务和蓝牙服务同时app需要申请位置授权主要针对安卓12版本下一篇博文我将进入具体实战demo中

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询