You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改蓝牙扫描间隔?实现100ms周期采集RSSI数据

调整BLE扫描周期到100毫秒的解决方案

Alright, let's get your BLE RSSI collection app running at that 100ms interval. The main issue with your current setup is how you're scheduling scans—we need to swap out the 5-second delay with a tighter, more reliable 100ms loop, while also making sure we don't block the main thread or run into scan overlap issues.

Here's the refactored code with explanations of the key changes:

Step 1: Set Up Global Variables

First, we'll define our interval constant and add a handler/runnable to manage scan scheduling:

private ScanCallback leScanCallback;
private BluetoothLeScanner bluetoothLeScanner;
private Handler scanHandler = new Handler(Looper.getMainLooper());
private static final long SCAN_INTERVAL_MS = 100; // 目标100毫秒间隔
private Runnable scanRunnable;

Step 2: Update the Scan Callback

We'll modify the callback to handle results efficiently, stop the current scan once a result is received, and schedule the next scan immediately:

// 初始化扫描回调
leScanCallback = new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, final ScanResult result) {
        // 把文件写入操作放到子线程,避免阻塞主线程(原来的主线程post会导致UI卡顿)
        new Thread(() -> {
            // 这里替换成你实际的文件写入逻辑
            String rssiData = String.format("Device: %s, RSSI: %d, Timestamp: %d\n",
                    result.getDevice().getAddress(),
                    result.getRssi(),
                    System.currentTimeMillis());
            // writeToFile(rssiData); // 调用你的文件写入方法
        }).start();

        // 停止当前扫描,准备下一轮
        bluetoothLeScanner.stopScan(leScanCallback);
        // 调度100毫秒后的下一次扫描
        scanHandler.postDelayed(scanRunnable, SCAN_INTERVAL_MS);
    }

    @Override
    public void onScanFailed(int errorCode) {
        super.onScanFailed(errorCode);
        // 扫描失败也要继续调度下一次,避免采集中断
        scanHandler.postDelayed(scanRunnable, SCAN_INTERVAL_MS);
    }
};

Step 3: Create the Scan Scheduler Runnable

This runnable handles initializing the BLE scanner (if needed) and starting each scan:

scanRunnable = () -> {
    // 初始化BLE扫描器(仅第一次执行时)
    if (bluetoothLeScanner == null) {
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            // 这里可以添加蓝牙未启用的提示逻辑
            return;
        }
        bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
    }

    // 启动单次扫描(确保每次扫描完成后再进行下一次,避免重叠)
    bluetoothLeScanner.startScan(leScanCallback);
};

Step 4: Manage Scan Lifecycle

Make sure to start and stop scans properly to avoid memory leaks and unnecessary battery drain:

@Override
protected void onResume() {
    super.onResume();
    // 启动第一次扫描
    scanHandler.post(scanRunnable);
}

@Override
protected void onPause() {
    super.onPause();
    // 停止所有待执行的扫描任务
    scanHandler.removeCallbacks(scanRunnable);
    // 停止当前正在进行的扫描
    if (bluetoothLeScanner != null) {
        bluetoothLeScanner.stopScan(leScanCallback);
    }
}

Key Notes to Keep in Mind:

  • Threading: I moved the file write operation to a background thread—never do IO on the main thread, especially with a tight 100ms interval.
  • Scan Overlap: Using single scans (instead of continuous) ensures we don't have overlapping scan sessions, which can cause inconsistent results.
  • System Limits: Some Android devices might throttle frequent BLE scans to save battery. Test on your target devices to ensure reliability.
  • Permissions: Double-check you have the required permissions (BLUETOOTH_SCAN, BLUETOOTH_CONNECT, and location permissions for Android 10+).

内容的提问来源于stack exchange,提问作者AmAn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:03:59