更新Android版本后,新建工程出错

本文介绍了在Android开发中遇到的常见问题:每次创建项目时都会生成appcompat_v7工程,并可能出现错误。通过设置兼容的最小版本为4.0,可以避免生成该工程。此外,提供了详细的步骤来解决与appcompat_v7工程相关的错误,包括更新Android SDK和Tools,以及手动清理和构建项目。


最近初学android,版本是22.6.0的话,每次创建一个项目就会出现一个appcompat_v7工程;然后我升级到最新的版本23.0.4之后,创建第一个项目,也会出现一个appcompat_v7工程,但创建多个项目的话,appcompat_v7工程也仅有一个,但有错误;

 

 

上网查了一下,原来appcompat_v7是Google的一个兼容包,就是一个支持库,项目新建后之所以会生成appcomat_v7工程,是为了能兼容2.2以上的版本,eclipse在新建项目的时候自动关联了所需要的lib;

关联的方式是:项目 -> Properies -> Android ->Libary;

你会看到appcomat_v7被作为lib加载了进来,如果不想引用这个lib,把它删除了,关联就解除了,也就不能兼容以前的版本了;

如果不想让appcompat_v7自动生成,可以在创建项目时,将Minimum Required SDK(即兼容的最小版本)设置为4.0,那就不会有这个工程的出现了;

 

而出现归出现,这个错误还是要解决的,解决方式为:

(1)打开Android SDK Manager,把最新的Android SDK和Tools里对应的Android SDK Build-tools下载下来,截止到2014年11月,应该是Android 5.0(API 21);当然,Extras的Android Support Respository,Android Support Library和Google USB Driver也要下载下来;

 

 

(2)下载完成后,选中appcompat_v7工程,点击菜单栏里的Project ,把Build Automatically的勾去掉,即不要自动构建;

         然后clean一下整个项目:clean all projects,然后再build project;当然,这当中最好能重启一下;然后再clean;

         

         然后就应该没有错误了,然后再把Build Automatically选上,以后就可以新建项目了;

 

(3)新建项目时,为了兼容以前的版本,如果不想生成appcompat_v7工程的话,就要引入appcompat_v7的jar包作为支持;

<think>我们使用Flutter来创建一个蓝牙连接App的工程。这个工程将包含以下功能: 1. 扫描附近的蓝牙设备 2. 显示扫描到的设备列表 3. 连接选定的蓝牙设备 4. 展示设备提供的服务与特征 5. 读写特征值(可选) 我们将使用flutter_blue_plus库,它是Flutter中一个功能强大的蓝牙库。 步骤: 1. 创建一个新的Flutter工程 2. 添加必要的依赖 3. 配置平台权限(Android和iOS) 4. 编写代码实现上述功能 下面是详细步骤: ## 1. 创建Flutter工程 在终端运行: ```bash flutter create bluetooth_connect_app cd bluetooth_connect_app ``` ## 2. 添加依赖 打开`pubspec.yaml`文件,添加以下依赖: ```yaml dependencies: flutter: sdk: flutter flutter_blue_plus: ^1.8.3 permission_handler: ^11.3.1 # 用于权限请求 ``` 然后在终端运行: ```bash flutter pub get ``` ## 3. 配置平台权限 ### Android配置 打开`android/app/src/main/AndroidManifest.xml`,在`<manifest>`标签内添加以下权限: ```xml <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <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" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> ``` 在`<application>`标签内添加以下属性,以支持低版本Android: ```xml <application ... android:usesCleartextTraffic="true"> ``` 注意:在Android 12及以上版本中,还需要在`<application>`标签内添加: ```xml <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> ``` ### iOS配置 打开`ios/Runner/Info.plist`,添加以下权限描述: ```xml <dict> ... <key>NSBluetoothAlwaysUsageDescription</key> <string>需要蓝牙权限以连接设备</string> <key>NSBluetoothPeripheralUsageDescription</key> <string>需要蓝牙权限以连接设备</string> <key>NSLocationWhenInUseUsageDescription</key> <string>需要位置权限以发现蓝牙设备</string> </dict> ``` ## 4. 编写代码 我们将创建以下主要界面: - 主界面:扫描设备,显示设备列表 - 设备服务界面:连接设备后,显示设备提供的服务和特征 - 特征操作界面:读写特征值(可选) 下面是主界面的代码示例: ```dart import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:permission_handler/permission_handler.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: '蓝牙连接App', theme: ThemeData( primarySwatch: Colors.blue, ), home: const BluetoothApp(), ); } } class BluetoothApp extends StatefulWidget { const BluetoothApp({super.key}); @override State<BluetoothApp> createState() => _BluetoothAppState(); } class _BluetoothAppState extends State<BluetoothApp> { List<BluetoothDevice> _devicesList = []; bool _isScanning = false; StreamSubscription<List<ScanResult>>? _scanSubscription; @override void initState() { super.initState(); _checkPermissions(); } // 检查权限 Future<void> _checkPermissions() async { if (await Permission.bluetoothScan.request().isGranted && await Permission.bluetoothConnect.request().isGranted) { // 如果需要位置权限(Android 10以下) if (!(await Permission.location.isGranted)) { await Permission.location.request(); } } } // 开始扫描 void _startScan() { setState(() { _isScanning = true; _devicesList.clear(); }); // 先停止之前的扫描 FlutterBluePlus.stopScan(); // 开始新的扫描 _scanSubscription = FlutterBluePlus.scanResults.listen((results) { for (ScanResult result in results) { if (!_devicesList.contains(result.device)) { setState(() { _devicesList.add(result.device); }); } } }, onError: (e) { print("扫描出错: $e"); }); // 设置扫描超时 Future.delayed(const Duration(seconds: 15), () { if (_isScanning) { _stopScan(); } }); // 开始扫描 FlutterBluePlus.startScan(timeout: const Duration(seconds: 15)); } // 停止扫描 void _stopScan() { _scanSubscription?.cancel(); FlutterBluePlus.stopScan(); setState(() { _isScanning = false; }); } // 连接设备 void _connectToDevice(BluetoothDevice device) async { try { await device.connect(); Navigator.push(context, MaterialPageRoute(builder: (context) => DeviceScreen(device: device))); } catch (e) { print("连接失败: $e"); } } @override void dispose() { _scanSubscription?.cancel(); _stopScan(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('蓝牙设备扫描'), actions: [ IconButton( icon: Icon(_isScanning ? Icons.stop : Icons.search), onPressed: () { if (_isScanning) { _stopScan(); } else { _startScan(); } }, ) ], ), body: ListView.builder( itemCount: _devicesList.length, itemBuilder: (context, index) { BluetoothDevice device = _devicesList[index]; return ListTile( title: Text(device.platformName), subtitle: Text(device.remoteId.toString()), trailing: ElevatedButton( child: const Text('连接'), onPressed: () => _connectToDevice(device), ), ); }, ), ); } } // 设备服务界面 class DeviceScreen extends StatefulWidget { final BluetoothDevice device; const DeviceScreen({super.key, required this.device}); @override State<DeviceScreen> createState() => _DeviceScreenState(); } class _DeviceScreenState extends State<DeviceScreen> { List<BluetoothService> _services = []; bool _isConnecting = true; @override void initState() { super.initState(); _discoverServices(); } // 发现服务 Future<void> _discoverServices() async { try { List<BluetoothService> services = await widget.device.discoverServices(); setState(() { _services = services; _isConnecting = false; }); } catch (e) { print("发现服务失败: $e"); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.device.platformName), ), body: _isConnecting ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: _services.length, itemBuilder: (context, index) { BluetoothService service = _services[index]; return ExpansionTile( title: Text(service.uuid.toString()), children: service.characteristics.map((characteristic) { return ListTile( title: Text(characteristic.uuid.toString()), subtitle: Text('特性: ${characteristic.properties}'), trailing: IconButton( icon: const Icon(Icons.edit), onPressed: () { // 进入特征操作界面 Navigator.push( context, MaterialPageRoute( builder: (context) => CharacteristicScreen(characteristic: characteristic), ), ); }, ), ); }).toList(), ); }, ), ); } } // 特征操作界面(可选) class CharacteristicScreen extends StatefulWidget { final BluetoothCharacteristic characteristic; const CharacteristicScreen({super.key, required this.characteristic}); @override State<CharacteristicScreen> createState() => _CharacteristicScreenState(); } class _CharacteristicScreenState extends State<CharacteristicScreen> { List<int>? _value; bool _isReading = false; bool _isWriting = false; // 读取特征值 Future<void> _readValue() async { setState(() { _isReading = true; }); try { List<int> value = await widget.characteristic.read(); setState(() { _value = value; _isReading = false; }); } catch (e) { print("读取失败: $e"); setState(() { _isReading = false; }); } } // 写入特征值(示例:写入0x01) Future<void> _writeValue() async { setState(() { _isWriting = true; }); try { await widget.characteristic.write([0x01]); setState(() { _isWriting = false; }); } catch (e) { print("写入失败: $e"); setState(() { _isWriting = false; }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('特征操作'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('特征值: ${_value?.map((e) => e.toRadixString(16)).join(', ') ?? '未读取'}'), const SizedBox(height: 20), ElevatedButton( onPressed: _isReading ? null : _readValue, child: _isReading ? const CircularProgressIndicator() : const Text('读取特征值'), ), const SizedBox(height: 20), ElevatedButton( onPressed: _isWriting ? null : _writeValue, child: _isWriting ? const CircularProgressIndicator() : const Text('写入[0x01]'), ), ], ), ), ); } } ``` ## 代码解释 1. **权限检查**:在应用启动时检查并请求蓝牙和位置权限(Android需要位置权限来扫描BLE设备)。 2. **扫描设备**:使用`FlutterBluePlus.startScan()`开始扫描,通过监听`FlutterBluePlus.scanResults`来获取扫描结果。 3. **设备连接**:点击设备列表中的设备,通过`device.connect()`进行连接。 4. **发现服务**:连接设备后,调用`device.discoverServices()`获取设备提供的服务。 5. **服务和特征展示**:以可展开的列表展示服务及其包含的特征。 6. **特征操作**:在特征操作界面,可以读取和写入特征值。 ## 运行应用 连接物理设备(Android或iOS),确保设备支持蓝牙,然后运行: ```bash flutter run ``` ## 注意事项 - 在真实设备上运行,模拟器可能不支持蓝牙。 - 确保设备蓝牙已开启。 - 不同平台的权限处理可能不同,需要仔细测试。 --- ### §§相关问题§§: 1. 如何实现蓝牙设备的断线自动重连? 2. 如何监听蓝牙设备发送的通知(notify)? 3. 在Android和iOS上处理蓝牙权限有哪些不同? 4. 如何优化蓝牙扫描的能耗? </think># 创建蓝牙连接App工程:完整指南与示例代码 下面我将详细介绍如何从零开始创建一个功能完整的蓝牙连接App工程,使用Flutter框架来实现跨平台兼容性。 ## 📱 工程结构概述 ``` bluetooth_connect_app/ ├── lib/ │ ├── main.dart # 应用入口 │ ├── screens/ │ │ ├── home_screen.dart # 主界面 │ │ ├── scan_screen.dart # 扫描界面 │ │ └── device_screen.dart# 设备控制界面 │ ├── widgets/ │ │ └── device_card.dart # 设备卡片组件 │ └── bluetooth/ │ └── bluetooth_service.dart # 蓝牙服务封装 ├── android/ # Android平台配置 ├── ios/ # iOS平台配置 └── pubspec.yaml # 依赖管理 ``` ## 📦 依赖配置(pubspec.yaml) ```yaml name: bluetooth_connect_app description: A complete Bluetooth connection application environment: sdk: ">=3.0.0 <4.0.0" flutter: ">=3.0.0" dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.6 flutter_blue_plus: ^1.8.3 # 蓝牙核心库 permission_handler: ^11.3.1 # 权限管理 provider: ^6.0.5 # 状态管理 auto_size_text: ^3.0.0 # 自适应文本 flutter_spinkit: ^5.2.0 # 加载动画 dev_dependencies: flutter_lints: ^3.0.0 flutter_test: sdk: flutter flutter: uses-material-design: true assets: - assets/ # 图标资源 ``` ## 核心代码实现 ### 1. 主入口文件 (lib/main.dart) ```dart import 'package:flutter/material.dart'; import 'package:bluetooth_connect_app/screens/home_screen.dart'; import 'package:bluetooth_connect_app/bluetooth/bluetooth_service.dart'; import 'package:provider/provider.dart'; void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => BluetoothService()), ], child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: '蓝牙连接助手', theme: ThemeData( primarySwatch: Colors.blue, appBarTheme: const AppBarTheme( backgroundColor: Colors.white, foregroundColor: Colors.black, elevation: 0, ), scaffoldBackgroundColor: Colors.white, ), home: const HomeScreen(), debugShowCheckedModeBanner: false, ); } } ``` ### 2. 蓝牙服务封装 (lib/bluetooth/bluetooth_service.dart) ```dart import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; class BluetoothService with ChangeNotifier { // 状态变量 bool _isScanning = false; bool _isConnected = false; BluetoothDevice? _connectedDevice; List<BluetoothService> _services = []; List<BluetoothDevice> _discoveredDevices = []; String _connectionStatus = "未连接"; StreamSubscription<List<ScanResult>>? _scanSubscription; // 获取器 bool get isScanning => _isScanning; bool get isConnected => _isConnected; BluetoothDevice? get connectedDevice => _connectedDevice; List<BluetoothDevice> get discoveredDevices => _discoveredDevices; String get connectionStatus => _connectionStatus; List<BluetoothService> get services => _services; // 检查权限 Future<bool> checkPermissions() async { try { if (await FlutterBluePlus.isSupported == false) { _connectionStatus = "设备不支持蓝牙"; notifyListeners(); return false; } // 请求权限 final statuses = await [ Permission.bluetoothScan, Permission.bluetoothConnect, Permission.locationWhenInUse, ].request(); if (statuses[Permission.bluetoothScan]!.isGranted && statuses[Permission.bluetoothConnect]!.isGranted) { return true; } else { _connectionStatus = "缺少必要权限"; notifyListeners(); return false; } } catch (e) { _connectionStatus = "权限错误: $e"; notifyListeners(); return false; } } // 开始扫描设备 Future<void> startScan({int timeout = 15}) async { if (_isScanning) return; if (await checkPermissions() == false) return; // 重置设备列表 _discoveredDevices.clear(); _isScanning = true; _connectionStatus = "扫描中..."; notifyListeners(); try { // 设置扫描配置 await FlutterBluePlus.startScan( timeout: Duration(seconds: timeout), scanMode: ScanMode.lowLatency, ); // 监听扫描结果 _scanSubscription = FlutterBluePlus.scanResults.listen((results) { for (ScanResult result in results) { final device = result.device; // 过滤掉无效设备 if (device.platformName.isNotEmpty && !_discoveredDevices.contains(device)) { _discoveredDevices.add(device); notifyListeners(); } } }, onError: (e) { _connectionStatus = "扫描错误: $e"; _isScanning = false; notifyListeners(); }); // 超时停止扫描 Timer(Duration(seconds: timeout), () { if (_isScanning) stopScan(); }); } catch (e) { _connectionStatus = "扫描失败: $e"; _isScanning = false; notifyListeners(); } } // 停止扫描 void stopScan() { if (!_isScanning) return; _scanSubscription?.cancel(); FlutterBluePlus.stopScan(); _isScanning = false; _connectionStatus = "扫描完成"; notifyListeners(); } // 连接设备 Future<void> connectToDevice(BluetoothDevice device) async { if (_isConnected) return; try { _connectionStatus = "正在连接..."; notifyListeners(); await device.connect(autoConnect: false, timeout: Duration(seconds: 10)); _connectedDevice = device; _isConnected = true; _connectionStatus = "已连接"; // 发现服务 _services = await device.discoverServices(); notifyListeners(); } catch (e) { _connectionStatus = "连接失败: $e"; notifyListeners(); } } // 断开连接 Future<void> disconnectDevice() async { if (!_isConnected || _connectedDevice == null) return; try { await _connectedDevice!.disconnect(); _isConnected = false; _connectedDevice = null; _services.clear(); _connectionStatus = "已断开"; notifyListeners(); } catch (e) { _connectionStatus = "断开失败: $e"; notifyListeners(); } } // 写入特征值 Future<void> writeCharacteristic(BluetoothCharacteristic characteristic, List<int> value) async { try { await characteristic.write(value); } catch (e) { _connectionStatus = "写入失败: $e"; notifyListeners(); } } // 读取特征值 Future<List<int>> readCharacteristic(BluetoothCharacteristic characteristic) async { try { return await characteristic.read(); } catch (e) { _connectionStatus = "读取失败: $e"; notifyListeners(); return []; } } @override void dispose() { _scanSubscription?.cancel(); disconnectDevice(); super.dispose(); } } ``` ### 3. 主界面 (lib/screens/home_screen.dart) ```dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:bluetooth_connect_app/bluetooth/bluetooth_service.dart'; import 'package:bluetooth_connect_app/screens/scan_screen.dart'; import 'package:bluetooth_connect_app/widgets/device_card.dart'; class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context) { final bluetoothService = Provider.of<BluetoothService>(context); return Scaffold( appBar: AppBar( title: const Text('蓝牙连接助手'), actions: [ IconButton( icon: Icon(bluetoothService.isScanning ? Icons.stop : Icons.search), onPressed: () { if (bluetoothService.isScanning) { bluetoothService.stopScan(); } else { Navigator.push( context, MaterialPageRoute(builder: (context) => const ScanScreen()), ); } }, ), ], ), body: Column( children: [ // 状态显示 Container( padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20), color: Colors.grey[50], child: Row( children: [ Icon( bluetoothService.isConnected ? Icons.bluetooth_connected : Icons.bluetooth_disabled, color: bluetoothService.isConnected ? Colors.blue : Colors.grey, ), const SizedBox(width: 10), Expanded( child: Text( bluetoothService.connectionStatus, style: const TextStyle(fontSize: 16), ), ), ], ), ), // 已连接设备 if (bluetoothService.isConnected) Padding( padding: const EdgeInsets.all(16.0), child: DeviceCard(device: bluetoothService.connectedDevice!), ), // 设备操作区域 if (bluetoothService.isConnected) Expanded( child: ListView.builder( itemCount: bluetoothService.services.length, itemBuilder: (context, index) { final service = bluetoothService.services[index]; return ExpansionTile( title: Text(service.uuid.toString()), subtitle: Text('服务'), children: service.characteristics.map((characteristic) { return ListTile( title: Text(characteristic.uuid.toString()), subtitle: Text( '特性: ${characteristic.properties.toString().replaceAll("BluetoothCharacteristicProperty.", "")}' ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ if (characteristic.properties.read) IconButton( icon: const Icon(Icons.download), onPressed: () async { final value = await bluetoothService.readCharacteristic(characteristic); // 处理读取的值 }, ), if (characteristic.properties.write) IconButton( icon: const Icon(Icons.upload), onPressed: () { // 写入示例值 bluetoothService.writeCharacteristic(characteristic, [0x01]); }, ), ], ), ); }).toList(), ); }, ), ), // 未连接时的提示 if (!bluetoothService.isConnected) const Expanded( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.bluetooth, size: 80, color: Colors.grey), SizedBox(height: 20), Text('未连接任何设备', style: TextStyle(fontSize: 18)), Text('请点击右上角扫描按钮查找设备', style: TextStyle(color: Colors.grey)), ], ), ), ), ], ), // 断开连接按钮 if (bluetoothService.isConnected) Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton.icon( icon: const Icon(Icons.link_off), label: const Text('断开连接'), style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, minimumSize: const Size(double.infinity, 50), ), onPressed: bluetoothService.disconnectDevice, ), ), ); } } ``` ### 4. 扫描界面 (lib/screens/scan_screen.dart) ```dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:bluetooth_connect_app/bluetooth/bluetooth_service.dart'; import 'package:bluetooth_connect_app/widgets/device_card.dart'; class ScanScreen extends StatefulWidget { const ScanScreen({super.key}); @override State<ScanScreen> createState() => _ScanScreenState(); } class _ScanScreenState extends State<ScanScreen> { @override void initState() { super.initState(); // 进入页面后开始扫描 WidgetsBinding.instance.addPostFrameCallback((_) { Provider.of<BluetoothService>(context, listen: false).startScan(); }); } @override void dispose() { // 离开页面时停止扫描 Provider.of<BluetoothService>(context, listen: false).stopScan(); super.dispose(); } @override Widget build(BuildContext context) { final bluetoothService = Provider.of<BluetoothService>(context); return Scaffold( appBar: AppBar( title: const Text('扫描蓝牙设备'), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => Navigator.pop(context), ), actions: [ IconButton( icon: Icon(bluetoothService.isScanning ? Icons.stop : Icons.refresh), onPressed: () { if (bluetoothService.isScanning) { bluetoothService.stopScan(); } else { bluetoothService.startScan(); } }, ), ], ), body: Column( children: [ // 扫描状态 Container( padding: const EdgeInsets.all(16), color: Colors.grey[50], child: Row( children: [ if (bluetoothService.isScanning) const SizedBox( width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2), ) else const Icon(Icons.info, color: Colors.blue), const SizedBox(width: 10), Text( bluetoothService.isScanning ? "正在扫描附近设备..." : "扫描完成,发现${bluetoothService.discoveredDevices.length}个设备", ), ], ), ), // 设备列表 Expanded( child: bluetoothService.discoveredDevices.isEmpty ? const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.devices_other, size: 80, color: Colors.grey), SizedBox(height: 20), Text('未发现任何设备', style: TextStyle(fontSize: 18)), Text('请确保蓝牙开启且设备处于可发现状态', style: TextStyle(color: Colors.grey)), ], ), ) : ListView.builder( itemCount: bluetoothService.discoveredDevices.length, itemBuilder: (context, index) { final device = bluetoothService.discoveredDevices[index]; return DeviceCard( device: device, onTap: () { bluetoothService.connectToDevice(device); Navigator.pop(context); }, ); }, ), ), ], ), ); } } ``` ### 5. 设备卡片组件 (lib/widgets/device_card.dart) ```dart import 'package:flutter/material.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; class DeviceCard extends StatelessWidget { final BluetoothDevice device; final VoidCallback? onTap; const DeviceCard({ super.key, required this.device, this.onTap, }); @override Widget build(BuildContext context) { return Card( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: ListTile( leading: const Icon(Icons.devices, size: 36), title: Text( device.platformName, style: const TextStyle(fontWeight: FontWeight.bold), overflow: TextOverflow.ellipsis, ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('MAC: ${device.remoteId}'), Text('信号强度: ${device.rssi} dBm'), ], ), trailing: onTap != null ? IconButton( icon: const Icon(Icons.link), onPressed: onTap, ) : const Icon(Icons.check_circle, color: Colors.green), onTap: onTap, ), ); } } ``` ## 🔧 平台特定配置 ### Android配置 (android/app/src/main/AndroidManifest.xml) ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <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" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <application android:label="bluetooth_connect_app" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> <activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layout
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值