【问题标题】:how to do continuous starting and stopping of scanning ble in android如何在android中连续启动和停止扫描ble
【发布时间】:2020-05-23 14:49:57
【问题描述】:

为了连续扫描广告数据,我尝试启动和停止 mBluetoothAdapter.stopLeScan(mLeScanCallback) 函数,但它仍然只发生一次。当我尝试调用扫描两次时,在 logcat 中我可以看到 LE 扫描已经开始,因为第二个调用没有执行。此处如何调用重复扫描和停止。

private void scanLeDevice(final boolean enable) {

    if (enable){
        // Stops scanning after a pre-defined scan period.
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mScanning = false;
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
                System.out.println("hello");

                invalidateOptionsMenu();
            }
        }, SCAN_PERIOD);
        System.out.println(SCAN_PERIOD);
        mScanning = true;

        System.out.println("starttt 1!");
        mBluetoothAdapter.startLeScan(mLeScanCallback);
        //////

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mScanning = false;
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
                System.out.println("hello");

                invalidateOptionsMenu();
            }
        }, SCAN_PERIOD);
        System.out.println(SCAN_PERIOD);
        mScanning = true;

        System.out.println("starttt 1!");
        mBluetoothAdapter.startLeScan(mLeScanCallback);
                    //////////


    }
    else
    {
        mScanning = false;
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }
    invalidateOptionsMenu();
}

【问题讨论】:

    标签: android


    【解决方案1】:

    这对我来说效果很好,

    我有一个方法叫discoverBLEdevices,在onCreate中调用。

    @SuppressLint("NewApi")
    private void discoverBLEDevices() {
        // TODO Auto-generated method stub
         startScan.run();
         Log.e("BLE_Scanner", "DiscoverBLE");
    }
    

    我有一个startScanRunnable,我在其中启动扫描并调用另一个runnable来停止扫描,如下所示:

    private Runnable startScan = new Runnable() {
        @Override
        public void run() {
            scanHandler.postDelayed(stopScan, 500);
            mBLEAdapter.startLeScan(mLeScanCallback);
            Log.e("BLE_Scanner", "Start Scan");
        }
    };
    

    500 毫秒后,我调用了一个名为 stopScan 的可运行对象,它会停止扫描并再次调用 startScan 可运行对象。

    private Runnable stopScan = new Runnable() {
        @Override
        public void run() {
            mBLEAdapter.stopLeScan(mLeScanCallback);
            scanHandler.postDelayed(startScan, 10);
            Log.e("BLE_Scanner", "Stop Scan");
        }
    };
    

    我的回调如下:

    // Device scan callback.
    @SuppressLint("NewApi")
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
    
            @SuppressLint("NewApi")
            public void onLeScan(final BluetoothDevice device, int rssi,
                    byte[] scanRecord) {
    
                String Address = device.getAddress();
                String Name = device.getName();
                Log.e("mLeScanCallback",""+Address +" : "+Name);
            }
        };
    

    整个代码:

    import android.annotation.SuppressLint;
    import android.app.Service;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothManager;
    import android.content.Intent;
    import android.os.Handler;
    import android.os.IBinder;
    import android.util.Log;
    import android.widget.Toast;
    
    @SuppressLint("NewApi")
    public class BluetoothLE extends Service {
    
    private BluetoothAdapter mBLEAdapter;
    private BluetoothManager manager;
    private Handler scanHandler = new Handler();
    
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
    
    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        turnonBLE();
        discoverBLEDevices();
     }
    
    @SuppressLint("NewApi")
    private void turnonBLE() {
        // TODO Auto-generated method stub
        manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
        mBLEAdapter = manager.getAdapter();
        mBLEAdapter.enable();
        Toast.makeText(getApplicationContext(), "BTLE ON Service",
                Toast.LENGTH_LONG).show();
        Log.e("BLE_Scanner", "TurnOnBLE");}
    
    @SuppressLint("NewApi")
    private void discoverBLEDevices() {
        // TODO Auto-generated method stub
        startScan.run();
        Log.e("BLE_Scanner", "DiscoverBLE");
    }
    
    
    private Runnable startScan = new Runnable() {
        @Override
        public void run() {
            scanHandler.postDelayed(stopScan, 500);
            mBLEAdapter.startLeScan(mLeScanCallback);
        }
    };
    
    
    // Device scan callback.
    @SuppressLint("NewApi")
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
    
            @SuppressLint("NewApi")
            public void onLeScan(final BluetoothDevice device, int rssi,
                    byte[] scanRecord) {
    
                String Address = device.getAddress();
                String Name = device.getName();
                Log.e("mLeScanCallback",""+Address +" : "+Name);
                }
        };
    
    
    private Runnable stopScan = new Runnable() {
        @Override
        public void run() {
            mBLEAdapter.stopLeScan(mLeScanCallback);
            scanHandler.postDelayed(startScan, 10);
        }
    };
    }
    

    【讨论】:

    • 我知道这已经过时了,但是否有理由像这样开始和停止扫描而不是连续运行扫描?
    【解决方案2】:

    如果它没有更新,我通过打开/关闭蓝牙适配器添加了几行。在我的情况下工作正常。

    fun discoverBLEDevices(){
        startScan.run()
        Log.d("Scan", " Discover BLE")
    }
    
    private val startScan:Runnable = Runnable {
        scanHandler.postDelayed(stopScan,10000)
        bluetoothLeScanner.startScan(bleScanner)
        // bluetoothAdapter.enable()
        Log.e("BLE_Scanner", "Start Scan")
    }
    
    private val stopScan:Runnable = Runnable {
        bluetoothLeScanner.stopScan(bleScanner)
        bluetoothAdapter.disable()
        bluetoothAdapter.enable()
        scanHandler.postDelayed(startScan, 1000)
        Log.e("BLE_Scanner", "Stop Scan")
    }
    

    【讨论】: