AIR版的功能添加
This commit is contained in:
@@ -173,11 +173,13 @@ class BleProtocolDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String obstacleText(String v) {
|
String obstacleText(String v) {
|
||||||
final o = int.tryParse(v) ?? -1;
|
// 障碍物只有 0/1 两种状态;无法识别为数字时一律显示 '--',
|
||||||
|
// 绝不回吐原始值,避免数据包尾字节导致的乱码显示。
|
||||||
|
final o = int.tryParse(v.trim());
|
||||||
return switch (o) {
|
return switch (o) {
|
||||||
0 => '无障碍',
|
0 => '无障碍',
|
||||||
1 => '有障碍',
|
1 => '有障碍',
|
||||||
_ => v.isNotEmpty ? v : '--',
|
_ => '--',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,16 @@ class BleDeviceDetailPage extends StatefulWidget {
|
|||||||
final BluetoothDevice device;
|
final BluetoothDevice device;
|
||||||
final ScanResult? scanResult;
|
final ScanResult? scanResult;
|
||||||
|
|
||||||
const BleDeviceDetailPage({super.key, required this.device, this.scanResult});
|
/// 后端设备长名称(如 MC700PLUS-CN-JS-1760408682847-0000002A-A9),
|
||||||
|
/// 由列表页跳转时传入;为空时回退到蓝牙广播名
|
||||||
|
final String? displayName;
|
||||||
|
|
||||||
|
const BleDeviceDetailPage({
|
||||||
|
super.key,
|
||||||
|
required this.device,
|
||||||
|
this.scanResult,
|
||||||
|
this.displayName,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<BleDeviceDetailPage> createState() => _BleDeviceDetailPageState();
|
State<BleDeviceDetailPage> createState() => _BleDeviceDetailPageState();
|
||||||
@@ -408,7 +417,9 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
|||||||
final advData = widget.scanResult?.advertisementData;
|
final advData = widget.scanResult?.advertisementData;
|
||||||
// 优先使用广告数据中的名称(含扫描响应),手机蓝牙列表也是这样显示的
|
// 优先使用广告数据中的名称(含扫描响应),手机蓝牙列表也是这样显示的
|
||||||
final name =
|
final name =
|
||||||
_resolvedName ??
|
(widget.displayName?.isNotEmpty == true
|
||||||
|
? widget.displayName!
|
||||||
|
: _resolvedName) ??
|
||||||
(advData?.advName.isNotEmpty == true
|
(advData?.advName.isNotEmpty == true
|
||||||
? advData!.advName
|
? advData!.advName
|
||||||
: (device.platformName.isNotEmpty
|
: (device.platformName.isNotEmpty
|
||||||
@@ -445,8 +456,6 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
|||||||
_buildServicesList(),
|
_buildServicesList(),
|
||||||
],
|
],
|
||||||
if (_isConnected) ...[
|
if (_isConnected) ...[
|
||||||
const SizedBox(height: 16),
|
|
||||||
_buildCommandSection(),
|
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_buildDeviceConfigCard(),
|
_buildDeviceConfigCard(),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
@@ -502,14 +511,6 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
|||||||
color: Color(0xFF1D2129),
|
color: Color(0xFF1D2129),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
'${widget.device.remoteId}',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: Color(0xFF86909C),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -520,7 +521,6 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
|||||||
const Divider(height: 1, color: Color(0xFFE5E6EB)),
|
const Divider(height: 1, color: Color(0xFFE5E6EB)),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_buildInfoRow('设备名称', name),
|
_buildInfoRow('设备名称', name),
|
||||||
_buildInfoRow('设备ID', '${widget.device.remoteId}'),
|
|
||||||
if (scanResult != null) ...[
|
if (scanResult != null) ...[
|
||||||
_buildInfoRow('信号强度', '${scanResult.rssi} dBm'),
|
_buildInfoRow('信号强度', '${scanResult.rssi} dBm'),
|
||||||
_buildInfoRow(
|
_buildInfoRow(
|
||||||
@@ -661,6 +661,25 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
|||||||
: Text(_isConnected ? '断开连接' : '连接设备'),
|
: Text(_isConnected ? '断开连接' : '连接设备'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (_isConnected) ...[
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: ElevatedButton.icon(
|
||||||
|
onPressed: _sendReadConfig,
|
||||||
|
icon: const Icon(Icons.settings, size: 18),
|
||||||
|
label: const Text('读配置'),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: const Color(0xFF165DFF),
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -680,21 +699,21 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Column(
|
// child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
// children: [
|
||||||
const Text(
|
// const Text(
|
||||||
'服务列表',
|
// '服务列表',
|
||||||
style: TextStyle(
|
// style: TextStyle(
|
||||||
fontSize: 15,
|
// fontSize: 15,
|
||||||
fontWeight: FontWeight.bold,
|
// fontWeight: FontWeight.bold,
|
||||||
color: Color(0xFF1D2129),
|
// color: Color(0xFF1D2129),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
const SizedBox(height: 12),
|
// const SizedBox(height: 12),
|
||||||
..._services.map((service) => _buildServiceTile(service)),
|
// ..._services.map((service) => _buildServiceTile(service)),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,55 +819,11 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCommandSection() {
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black.withOpacity(0.05),
|
|
||||||
blurRadius: 8,
|
|
||||||
offset: const Offset(0, 2),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const Text(
|
|
||||||
'发送指令',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Color(0xFF1D2129),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
child: ElevatedButton.icon(
|
|
||||||
onPressed: _sendReadConfig,
|
|
||||||
icon: const Icon(Icons.settings, size: 18),
|
|
||||||
label: const Text('读配置'),
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: const Color(0xFF165DFF),
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCommLogSection() {
|
Widget _buildCommLogSection() {
|
||||||
final pushes = _latestPushByCommand.values.toList();
|
// 数据推送栏只展示 0x02 状态信息;其余命令(如 0x00 远程遥控、0x05 读配置等)不在此栏渲染。
|
||||||
|
final pushes = _latestPushByCommand.values
|
||||||
|
.where((p) => p.command == MachineProtocolConstants.cmdStatusInfo)
|
||||||
|
.toList();
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -1063,7 +1038,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
|||||||
children: [
|
children: [
|
||||||
const Expanded(
|
const Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'设备配置 (0x05)',
|
'设备配置',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
|
|||||||
Reference in New Issue
Block a user