8

I am now using the new BLE api in android developing.

Basic idea is using bluetooth scanning result to inflate the recyclerview(list);

I followed the BLE guide on google developer

Now I have two problem: 1. onBatchScanResults listener is never triggered, butonScanResult works well, is that because the scanner only sense 1 sensor nearby?

  1. my BLE scanner is much slower compared with other applications.

The following is the two core functions' code snippet.

private void scanBLE(boolean enable) {
    final BluetoothLeScanner mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
    if (enable) {
        mScanning = true;
        mBluetoothLeScanner.startScan(mScanCallback);        
    } else {
        if (mScanning) {
            mScanning = false;
            mBluetoothLeScanner.stopScan(mScanCallback);
        }
    }

    Log.i(TAG, "now the scanning state is" + mScanning);
}

// Device scan callback.
private ScanCallback mScanCallback =
        new ScanCallback() {
    public void onScanResult(int callbackType, android.bluetooth.le.ScanResult result) {
        addBeaconTolist(result, beaconsList);
        mAdapter.notifyDataSetChanged();
    };

    public void onScanFailed(int errorCode) {
        Log.i(TAG, "error code is:" + errorCode);
    };

    public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult> results) {
        Log.i(TAG, "event linstener is called!!!!");
        Log.i(TAG, "batch result are:" + results);
        beaconsList.clear();
        for (int i = 0; i < results.size(); i++) {
            ScanResult result = results.get(i);
            addBeaconTolist(result, beaconsList);
        }
        mAdapter.notifyDataSetChanged();
    };

};

in MainFragment is like following:

    beaconsList = new ArrayList<BeaconsInfo>();

    mAdapter = new BeaconsAdapter(beaconsList);
    mRecyclerView.setAdapter(mAdapter);

    scannBLE(true);
Haven
  • 7,808
  • 5
  • 25
  • 37

2 Answers2

23

Whether or not you get batch results or individual results depends on your scan settings.

  1. In order to get batch results, you need to adjust the ScanSettings. Check out the documentation for the ScanSettings.Builder, and try using SCAN_MODE_LOW_POWER, which batches up results. You can also try adjusting the batch interval with setReportDelay(long reportDelayMillis); You can see a blog post I wrote about the power benefits of these settings here.

  2. It's not totally clear what you mean by "my BLE scanner is much slower compared with other applications", but it may be that the app's UI lags because you are not updating it on the UI thread. Try wrapping your calls to notifyDatasetChanged like this:

    runOnUiThread(new Runnable() {
      @Override
      public void run() {
         mAdapter.notifyDataSetChanged();
      }
    });
    
davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • do I need use flushPendingScanResults() to get the batch scan result? – Haven Nov 20 '14 at 14:35
  • 2
    No, that's only needed if you want to get the batch early. If you just wait, you will get it when the OS decides to send it. – davidgyoung Nov 20 '14 at 14:37
  • I have a basic question after reading your blog, does this ble scanning run in background? or a service is needed to do that job ? @davidgyoung – Haven Nov 21 '14 at 10:17
  • 1
    In the case I describe in the blog, yes, the Android Beacon Library runs scans in the background in a Service. – davidgyoung Nov 21 '14 at 12:15
  • Thanks, at the moment everytime i set the scansetting's reportDelay ,my nexus5's app will come out a SCAN_FAILED_FEATURE_UNSUPPORTED, it seems that this is the problem of the API? – Haven Nov 22 '14 at 08:48
  • That is one problem with the new bluetooth LE APIs: spotty device support. Nexus 5s also do not support advertising, but Nexus 9s do. See here: http://stackoverflow.com/questions/26441785/does-bluetoothleadvertiser-work-on-a-nexus-5-with-android-5-0 – davidgyoung Nov 22 '14 at 11:58
  • Doesn't work on my Z2 and setReportDelay prevents me from getting any results at all. Also, SCAN_MODE_LOW_POWER is default. – Siamaster Oct 07 '15 at 20:12
0

Try setUseHardwareBatchingIfSupported(true). This solves the problem for me on moto360 2nd gen. I think this is auto implemented for newer API.

ADM
  • 20,406
  • 11
  • 52
  • 83
  • How do you use it? It's not offered on the IDE, and there isn't documentation about it either: https://developer.android.com/reference/android/bluetooth/le/ScanSettings.Builder – android developer Jan 26 '23 at 23:10