Ionic BLE Scanner项目:BLE设备列表重复及RSSI实时更新问题求助
Hey there! Let’s tackle that duplicate BLE device issue you’re facing in your Ionic project—super common when dealing with fluctuating RSSI values, so you’re not alone here. The core fix is to track devices by their unique identifier, updating existing entries instead of adding duplicates. Here’s a step-by-step solution tailored to your setup:
1. Define a Clear Device Data Structure
First, create an interface to standardize the device info we need—this keeps things organized and avoids confusion:
interface BleDevice { id: string; // Unique device ID (UUID/MAC address, varies by plugin) name: string; rssi: number; // Add other fields you need, like advertisingData, if required }
2. Use a Map to Track Unique Devices
Instead of a plain array, use a Map<string, BleDevice> to store devices. The map’s key will be the device’s unique ID, letting us quickly check for existing entries and update RSSI values:
// In your home.ts component private devicesMap = new Map<string, BleDevice>(); public devicesList: BleDevice[] = []; // Array bound to your template
3. Update Scan Logic to Avoid Duplicates
When your BLE plugin returns a scanned device, check if it’s already in the map:
- If it exists: Update its RSSI value
- If it’s new: Add it to the map
Then convert the map to an array for your template to render:
// Example using @capacitor-community/bluetooth-le (adjust for your plugin) import { BluetoothLe } from '@capacitor-community/bluetooth-le'; // Start BLE scan BluetoothLe.startScan({ services: [] }) // Empty array scans all devices .subscribe( (scannedDevice) => { const deviceId = scannedDevice.id; // Use the unique ID from your plugin if (this.devicesMap.has(deviceId)) { // Update existing device's RSSI const existingDevice = this.devicesMap.get(deviceId)!; existingDevice.rssi = scannedDevice.rssi; this.devicesMap.set(deviceId, existingDevice); } else { // Add new device to the map this.devicesMap.set(deviceId, { id: deviceId, name: scannedDevice.name || 'Unknown Device', rssi: scannedDevice.rssi }); } // Convert map to array for template rendering this.devicesList = Array.from(this.devicesMap.values()); }, (error) => console.error('Scan error:', error) );
4. Simplify Your Template (home.html)
Now you can safely loop through devicesList—no duplicates, and RSSI values update in real-time:
<ion-list> <ion-item *ngFor="let device of devicesList"> <ion-label> <h2>{{ device.name }}</h2> <p>Device ID: {{ device.id }}</p> <p>RSSI: {{ device.rssi }} dBm</p> </ion-label> </ion-item> </ion-list>
Quick Notes for Your Setup
- Plugin Differences: If you’re using
@ionic-native/bleinstead of the Capacitor plugin, the device object might useuuidinstead ofid—adjust the key field accordingly. - Performance Tip: If you notice lag with frequent RSSI updates, you can use Angular’s
ChangeDetectorRefto manually trigger UI updates, or add a small debounce to reduce array refresh frequency. - Cleanup Old Devices: If you want to remove devices that haven’t been scanned in a while, add a timestamp to the
BleDeviceinterface and a periodic check to delete stale entries.
This approach ensures each device only appears once, while keeping its RSSI value up-to-date as the scanner picks up new signals.
内容的提问来源于stack exchange,提问作者ken.ng

