Code Monkey home page Code Monkey logo

android-scanner-compat-library's People

Contributors

hearsilent avatar lenguyenthanh avatar paulpv avatar philips77 avatar piotr-pawlowski avatar roshanrajaratnam avatar roum-old1 avatar ruslan-h avatar sureshjoshi avatar unverbraucht avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-scanner-compat-library's Issues

Problems with scanning on Huawei P8 Lite

I was able to solve this with the following scanning options, just thought i'll open a ticket in case someone is looking for options to test when the scanning fails on a phone:

ScanSettings.Builder()
    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
    .setReportDelay(1000)
    .setUseHardwareBatchingIfSupported(false)
    .setUseHardwareFilteringIfSupported(false);

BT Adapter is not turned ON

I got this crash, I've check BT is on by mBluetoothAdapter.isEnabled().
It's seems like sometimes mBluetoothAdapter.isEnabled() not the same mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON.

Do you have any suggestions?

Thx!

Fatal Exception: java.lang.IllegalStateException: BT Adapter is not turned ON
at no.nordicsemi.android.support.v18.scanner.BluetoothLeUtils.checkAdapterStateOn(BluetoothLeUtils.java:137)
at no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerImplLollipop.startScanInternal(BluetoothLeScannerImplLollipop.java:64)
at no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat.startScan(BluetoothLeScannerCompat.java:123)

IllegalArgumentException in Android 7 and some Samsung devices

Hi, I'm seeing these crashes in Google Play console

java.lang.IllegalArgumentException: 
  at android.bluetooth.le.BluetoothLeScanner.stopScan (BluetoothLeScanner.java:226)
  at no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerImplLollipop.stopScan (BluetoothLeScannerImplLollipop.java:98)
 ...
  at android.os.Handler.dispatchMessage (Handler.java:98)
  at android.os.Looper.loop (Looper.java:154)
  at android.os.HandlerThread.run (HandlerThread.java:61)

I'm only seeing them on S8 and S3 devices, and only on Android 7.0, but we don't have that many users.

I can't see how stopScan can throw IllegalArgumentException (here's nougat's BluetoothLeScanner. I guess that's some Samsung fidling?

I've never been able to reproduce it, but I don't usually work with those devices

Handling of onScannerRegistered() status=6 (Scanning too frequently)

Hello,

If a scan is started too often it will fail silently, only printing a onScannerRegistered where you have to read the status code. Is there a way to catch this even? When a scan fails because user or app initiated the scan too often? The ScanCallback does not yeild a onScanFailed.

In my app a scan happens directly when a user enters a certain view, thus toggling in and out of the app (resume/pause) several times will cause the scan to start/stop several times. Sometimes the scan fails to start and thus user is unaware that the scan is not actually running because it fails silently.

The same issue can be found in the nRF Connect app and can be easily reproduced there, happily button mashing the Scan button will cause the app to show a state of scanning (button showing "STOP SCANNING") even though the starting of the scan failed.

I kept getting source code not matching byte code when trying to trace down the error so it was hard for me to research this issue further. Tried looking through the Android Source code but it seems like they are not propagating this information to layers above:
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/bluetooth/le/BluetoothLeScanner.java#394

Is there any way to know if you are scanning to often and let the user know or just delay the scan until the module is ready?

Best regards
David

ManufacturerSpecificData is not working properly

I have a low-power Bluetooth device that advertisement data like this:
[
02 01 05 08 09 61 6e 74 68 65 72 6f
09 ff 11 02 11 02 d9 21 a3 38
1e ff 11 02 11 02 d9 21 a3 38 21 43 01 d9 00 10 19 44 45 4c 20 68 73 65 4d 20 47 53 54 42
4a 00 00 00 00 00 00 00 00 00
]
// result.getScanRecord().getManufacturerSpecificData()
//or
//result.getScanRecord().getManufacturerSpecificData(0x0211)

The ManufacturerSpecificData I read sometimes is like this:
[ 11 02 d9 21 a3 38 ] (When the signal is weak, more is like this)
, sometimes it is like this:
[
11 02 d9 21 a3 38 21 43 01 d9 00 10 19 44 45 4c 20 68 73 65 4d 20 47 53 54 42
4a 00 00 00 00 00 00 00 00 00
]
And I want to get all the advertisement data, but I didn't find the relevant method.
I hope I can get your reply, thank you.

Emulate SCAN_MODE_OPPORTUNISTIC on older devices

SCAN_MODE_OPPORTUNISTIC has been added in Android Marshmallow.
Currently the library declares this constant, and even use it on Android Marshmallow+ devices, but:

  1. The documentation doesn't mention it:
    /**
    * Set scan mode for Bluetooth LE scan.
    *
    * @param scanMode The scan mode can be one of {@link ScanSettings#SCAN_MODE_LOW_POWER},
    * {@link ScanSettings#SCAN_MODE_BALANCED} or
    * {@link ScanSettings#SCAN_MODE_LOW_LATENCY}.
    * @throws IllegalArgumentException If the {@code scanMode} is invalid.
    */
    @NonNull
    public Builder setScanMode(final int scanMode) {
    if (scanMode < SCAN_MODE_OPPORTUNISTIC || scanMode > SCAN_MODE_LOW_LATENCY) {
    throw new IllegalArgumentException("invalid scan mode " + scanMode);
    }
    this.scanMode = scanMode;
    return this;
    }
  2. The library does not emulate this mode for older versions.

Although it is not possible to fully recreate the same behavior, this could be emulated as SCAN_MODE_LOW_POWER. With setPowerSave(...) method those settings would be applied for pre-Marshmallow devices just like they are when LOW_POWER mode is used. This would have to be documented.

The reason this mode should be supported on older platforms is that currently it is ignored.

Disabling background scan when device is locked

Hi there,

I tried the background scanning and it works just perfectly except for devices running Android 7 or lower where this background scanning behavior is emulated as the battery drains really quickly.

On devices with O or P, I saw that the scanning is normally suspended by the OS some time after the device was locked. Is it possibly to do this too or (even better) to just throttle the background scanning then?

Regards

Max

BluetoothLeScanner on android 6.0.1 (ss s6 edge) cannot found device android >= 6.0.1

Hi all,
this code for scanning BLE device:

if (mBluetoothLEScanner == null) {
// create bluetoothLE scanner if it is null
mBluetoothLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
}
// start scan bluetooth
mBluetoothLEScanner.startScan(
null,
buildScanSettings(),
mProxyScanCallback);

private ScanSettings buildScanSettings() {
ScanSettings.Builder builder = new ScanSettings.Builder();
builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
builder.setReportDelay(0);
return builder.build();
}

Setting:



I cannot found device android >= 6.0.1, but can scan other device

There are any problem?Thank you.

In Android 9 and 10 if use filter peer not found on scan process

Hi.
Using this lib, I came across an unpleasant thing: if I set filter like as:

final List<ScanFilter> filters = new ArrayList<>();
filters.add(new ScanFilter.Builder().setDeviceName(KNOWN_DEV_NAME).build());
scanner.startScan(filters, settings, scanCallback);

then scanner do not return result and stop by timeout.

Any settings for "setScanMode" do not give a result.

When don`t use filter: all ok.

Code example:

final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
final ScanSettings settings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .setReportDelay(500)
                .build();
final List<ScanFilter> filters = new ArrayList<>();
filters.add(new ScanFilter.Builder().setDeviceName(working_device_name).build());
scanner.startScan(filters, settings, scanCallback);

Scanning multiple iBeacon devices

Hello!
We are trying to use AndroidScannerCompatLibrary in our Android application to scan BLE devices and measure its RSSI level. BLE devices is mounted on ceiling with distance approximately 1m.
There is implementation of StartScan() action (its uses Xamarin Binding Library from Nordic AndroidScannerCompatLibrary .aar file):

var scanner = BluetoothLeScannerCompat.Scanner;
            ScanSettings settings = new ScanSettings.Builder()
               .SetLegacy(false)
               .SetScanMode(ScanSettings.ScanModeLowLatency)
               .SetMatchMode(ScanSettings.MatchModeAggressive)
               .SetNumOfMatches(ScanSettings.MatchNumMaxAdvertisement) использую
               .SetReportDelay(0)
               .SetUseHardwareBatchingIfSupported(false)
               .Build();
           List< ScanFilter > filters = new List<ScanFilter>();
scanner.StartScan(filters, settings, _signalsScanCallback);

_signalsScanCallback store signals in package. After some period of time application send package to server storage.
And this is our stored RSSI level data set (from two iBeacon devices):
1
It seems like we have data from “one-device-per-period-of-time”.
Should we StartScan() for each device separately with list of ScanFilters, or it’s ok to use one instance of Scanner for all of it? We try to compare our results with same measures from “nRf connect”, and it’s differing. Can someone explain what are we doing wrong?

Android P scanner compatibility

Hi,
Has anyone ever tested the library with the latest version of Android P.
The library is working flawlessly on devices from Lollipop to Android Oreo but for some reasons, it doesn't work on my Pixel 2.
What trouble me is that the NRF connect app seems to be able to discover the device without any issue.

Thanks for the feedback !

The time period opens the scanning, the scanning stops, sometimes does not scan the data, after a period of time only then normal.

private volatile boolean turnOnOff = false;

private void startTimer() {
    timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
            if (!turnOnOff) {
                scanner.startScan(null, scanSettings, scanCallback);
                Log.i("定时性", "扫描");
            } else {
                scanner.stopScan(scanCallback);
                Log.i("定时性", "停止");
            }
            turnOnOff = !turnOnOff;
        }
    } ,0 , 1000);
}

I can`t stop scan,After I call the stop scan method, the callback is still executed.

 override fun onBatchScanResults(results: List<ScanResult>?) {
            // This callback will be called only if the report delay set above is greater then 0.

            // If the packet has been obtained while Location was disabled, mark Location as not required
            if (Utils.isLocationRequired(application) && !Utils.isLocationEnabled(application))
                Utils.markLocationNotRequired(application)

            var atLeastOneMatchedFilter = false
            for (result in results!!)
                atLeastOneMatchedFilter = mDevicesData.deviceDiscovered(result) || atLeastOneMatchedFilter
            if (atLeastOneMatchedFilter) {
                mDevicesData.applyFilter()
                mScannerState.recordFound()
            }
            stopScan()
        }

fun stopScan(){
        val scanner = BluetoothLeScannerCompat.getScanner()
        scanner.stopScan(scanCallback)
    }

Scan result name is null

Hi, i have some weird behavior with ble scanning.
I implemented app that perform scanning and connection to ble devices with help of android scanner, the problem is i have some devices (for example samsung s8 android version 9) that the scan result not contains the device name, i checked from other android device i do see the name.
I downloaded the NrfConnect app from google play store and it seems that this app show the device name at 80 % of the time in the problematic device (samsung s8) , so i downloaded this library to see what is the 'magic' that helps to receive the name, but after building simple app that prints the name to log i seed that even with current library the names are null always.
The question is what can lead to this problem ? Do you use current library in the NrfConnect app ?

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
      if(checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 23);
      }
    }



    final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();

    final ScanSettings settings = new ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setUseHardwareBatchingIfSupported(false)
            //.setReportDelay(5000)
            .build();
    final List<ScanFilter> filters = new ArrayList<>();
    filters.add(new ScanFilter.Builder().setServiceUuid(new ParcelUuid(UUID.fromString("XXXXXX-XXXX-0BAC-5241-XXXXXX"))).build());



    startScanBtn.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        scanner.startScan(filters, settings,listener);
      }
    });

    stopScanBtn.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        scanner.stopScan(listener);
      }
    });
  }

  private ScanCallback listener = new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
      super.onScanResult(callbackType, result);
      String name = result.getDevice().getName();
      Log.d("OnMyScanResult", "DeviceName: "+name);
    }

    @Override
    public void onScanFailed(int errorCode) {
      super.onScanFailed(errorCode);
      Log.d("ScanResult", "Scan failed code: "+errorCode);
    }

    @Override
    public void onBatchScanResults(@NonNull List<ScanResult> results) {
      super.onBatchScanResults(results);

      for(ScanResult result : results){
        String name = result.getDevice().getName();
        Log.d("OnMyScanResult", "DeviceName: "+name);
      }
    }
  };

About Android9.0 scanning

hello,I can't get the scan result with Android 9.0. The callback result is empty. What's the solution?

Extra in callback intent

Hi there,

as in the example code, I try to add an extra to a callback intent, but this leads to some interesting results:

First, only the added extra shows up in the intent, meaning that BluetoothLeScannerCompat.EXTRA_LIST_SCAN_RESULT was removed.

But also I get massive stacktraces in logcat:

2019-09-17 10:33:02.790 1365-3432/? E/Parcel: Class not found when unmarshalling: no.nordicsemi.android.support.v18.scanner.ScanResult
    java.lang.ClassNotFoundException: no.nordicsemi.android.support.v18.scanner.ScanResult
        at java.lang.Class.classForName(Native Method)
        at java.lang.Class.forName(Class.java:453)
        at android.os.Parcel.readParcelableCreator(Parcel.java:2811)
        at android.os.Parcel.readParcelable(Parcel.java:2765)
        at android.os.Parcel.readValue(Parcel.java:2668)
        at android.os.Parcel.readListInternal(Parcel.java:3098)
        at android.os.Parcel.readArrayList(Parcel.java:2319)
        at android.os.Parcel.readValue(Parcel.java:2689)
        at android.os.Parcel.readArrayMapInternal(Parcel.java:3037)
        at android.os.BaseBundle.initializeFromParcelLocked(BaseBundle.java:288)
        at android.os.BaseBundle.unparcel(BaseBundle.java:232)
        at android.os.Bundle.putAll(Bundle.java:288)
        at android.content.Intent.fillIn(Intent.java:9433)
        at com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:269)
        at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:245)
        at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:10000)
        at android.app.IActivityManager$Stub.onTransact$sendIntentSender$(IActivityManager.java:11540)
        at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:3183)
        at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3829)
        at android.os.Binder.execTransact(Binder.java:752)
     Caused by: java.lang.ClassNotFoundException: no.nordicsemi.android.support.v18.scanner.ScanResult
        at java.lang.Class.classForName(Native Method)
        at java.lang.BootClassLoader.findClass(ClassLoader.java:1346)
        at java.lang.BootClassLoader.loadClass(ClassLoader.java:1406)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at java.lang.Class.classForName(Native Method) 
        at java.lang.Class.forName(Class.java:453) 
        at android.os.Parcel.readParcelableCreator(Parcel.java:2811) 
        at android.os.Parcel.readParcelable(Parcel.java:2765) 
        at android.os.Parcel.readValue(Parcel.java:2668) 
        at android.os.Parcel.readListInternal(Parcel.java:3098) 
        at android.os.Parcel.readArrayList(Parcel.java:2319) 
        at android.os.Parcel.readValue(Parcel.java:2689) 
        at android.os.Parcel.readArrayMapInternal(Parcel.java:3037) 
        at android.os.BaseBundle.initializeFromParcelLocked(BaseBundle.java:288) 
        at android.os.BaseBundle.unparcel(BaseBundle.java:232) 
        at android.os.Bundle.putAll(Bundle.java:288) 
        at android.content.Intent.fillIn(Intent.java:9433) 
        at com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:269) 
        at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:245) 
        at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:10000) 
        at android.app.IActivityManager$Stub.onTransact$sendIntentSender$(IActivityManager.java:11540) 
        at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:3183) 
        at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3829) 
        at android.os.Binder.execTransact(Binder.java:752) 
     Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
2019-09-17 10:33:02.790 1365-3432/? W/Bundle: Failed to parse Bundle, but defusing quietly
    android.os.BadParcelableException: ClassNotFoundException when unmarshalling: no.nordicsemi.android.support.v18.scanner.ScanResult
        at android.os.Parcel.readParcelableCreator(Parcel.java:2839)
        at android.os.Parcel.readParcelable(Parcel.java:2765)
        at android.os.Parcel.readValue(Parcel.java:2668)
        at android.os.Parcel.readListInternal(Parcel.java:3098)
        at android.os.Parcel.readArrayList(Parcel.java:2319)
        at android.os.Parcel.readValue(Parcel.java:2689)
        at android.os.Parcel.readArrayMapInternal(Parcel.java:3037)
        at android.os.BaseBundle.initializeFromParcelLocked(BaseBundle.java:288)
        at android.os.BaseBundle.unparcel(BaseBundle.java:232)
        at android.os.Bundle.putAll(Bundle.java:288)
        at android.content.Intent.fillIn(Intent.java:9433)
        at com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:269)
        at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:245)
        at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:10000)
        at android.app.IActivityManager$Stub.onTransact$sendIntentSender$(IActivityManager.java:11540)
        at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:3183)
        at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3829)
        at android.os.Binder.execTransact(Binder.java:752)

I was testing my code on a OnePlus 5T running Android 9, scanner lib is at 1.4.3.

Does anyone know what's going on there?

Cheers,

Max

Connect hangs on some devices

Hi,

Using your scanner compat library I've noticed that the scanner sometimes discovers devices where the record.device.name is null. Whenever the scanner identifies one of your boards like this I cannot connect to it - BleManager.connect(device) simply times out without providing any callbacks.

To resolve this problem I start nRF Connect which then causes the scanner to correctly find the friendly name of the devices as well as allowing me to connect to them.

It feels like I am missing something with the scanner, you seem to somehow reset the adapter. How is this done?

Thanks for some great products!

SCAN_RESULT_TYPE_FULL

Hello,

SCAN_RESULT_TYPE_FULL and SCAN_RESULT_TYPE_ABBREVIATED are private but the method setScanResultType is public.

Mike

Scanner scans for infinity when batching disabled and report delay is > 0

Issue initially reported here: https://stackoverflow.com/questions/47981327/scancallback-onbatchscanresults-is-getting-called-indefinitly (very long time ago).
I can confirm scanning started with the following settings does not stop when stopScan is called in onBatchedScanResults:

// Scanning settings
final ScanSettings settings = new ScanSettings.Builder()
	.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
	.setReportDelay(500)
	.setUseHardwareBatchingIfSupported(false)
	.build();

Logs from a sample app:

2019-01-18 16:28:56.831 29232-29232/no.nordicsemi.android.nrfblinky W/AA: callback used to start scan: no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerImplLollipop$ScanCallbackWrapperLollipop$1@f4e51ba
2019-01-18 16:28:57.331 29232-29232/no.nordicsemi.android.nrfblinky I/AA: onBatchScanResults: 16
2019-01-18 16:28:57.334 29232-29232/no.nordicsemi.android.nrfblinky W/AA: callback used to stop scan:  no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerImplLollipop$ScanCallbackWrapperLollipop$1@f4e51ba
2019-01-18 16:28:57.837 29232-29232/no.nordicsemi.android.nrfblinky I/AA: onBatchScanResults: 0
2019-01-18 16:28:59.844 29232-29232/no.nordicsemi.android.nrfblinky I/AA: onBatchScanResults: 0
2019-01-18 16:29:00.346 29232-29232/no.nordicsemi.android.nrfblinky I/AA: onBatchScanResults: 0
2019-01-18 16:29:00.847 29232-29232/no.nordicsemi.android.nrfblinky I/AA: onBatchScanResults: 0
2019-01-18 16:29:01.349 29232-29232/no.nordicsemi.android.nrfblinky I/AA: onBatchScanResults: 0
[...]

Tested with version 1.2.0 on Pixel 2 with Android Pie.

Caught a RuntimeException from the binder stub implementation

getting an unusual RuntimeException in Android 6.0.1 API23 with targetSdkVersion 23 (build.gradle)
It was OK in Android 6.0.1 API23 with targetSdkVersion 22 (build.gradle)

`02-20 13:08:53.919 12379-12513/ D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
02-20 13:08:53.923 12379-12513/ W/Binder: Caught a RuntimeException from the binder stub implementation.
java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results
at android.os.Parcel.readException(Parcel.java:1627)
at android.os.Parcel.readException(Parcel.java:1579)
at android.bluetooth.IBluetoothGatt$Stub$Proxy.startScan(IBluetoothGatt.java:772)
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.onClientRegistered(BluetoothLeScanner.java:324)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:56)
at android.os.Binder.execTransact(Binder.java:453)

02-20 13:09:01.213 12379-12574/ V/RenderScript: 0x7f5fe7e000 Launching thread(s), CPUs 8
02-20 13:09:01.231 12379-12379/ I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@abbc528 time:42374438`

mUUid,

filters.add(new ScanFilter.Builder().setServiceUuid(mUuid).build());
I don't know this.mUUid what it is mean.please

Invoke ScanCallback in worker thread

Hello,
What do you think about calling ScanCallback methods in a worker thread? It would be useful for wrapping scanner in RxJava Observable class. Right now everything is invoked in the main thread. It is simple to implement, just add a Handler param in startScan method (like in Android SensorManager or LocationManager class).

onBatchScanResults continue to receive after stopScan

i have logged (can't reproduce, now under heavy test) cases where scanner.stopScan(nordic_scanCallback); has been issued in API 18 (Android 4.3 HTC phone) but the onBatchScanResults (...) still continue receiving (something like that shown below) and NO D/BluetoothAdapter: onScanResult() - Device=B4:99:4C:1E:7C:32 RSSI=-88 logged.

@OverRide
public void onBatchScanResults(List results)
{
Log.d(TAG, "nordic_scanCallback -> onBatchScanResults sz = " + results.size());
}

D/BluetoothAdapter: stopLeScan()
...
....
D/BLE_com: nordic_scanCallback -> onBatchScanResults sz = 0
D/BLE_com: nordic_scanCallback -> onBatchScanResults sz = 0
D/BLE_com: nordic_scanCallback -> onBatchScanResults sz = 0
D/BLE_com: nordic_scanCallback -> onBatchScanResults sz = 0
...
...
...

SCAN_MODE_OPPORTUNISTIC crashes on Lollipop

Samsung S5, on Android 5.0.

new no.nordicsemi.android.support.v18.scanner.ScanSettings.Builder()
  .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC)
  .setUseHardwareBatchingIfSupported(false)
  .build();
java.lang.IllegalArgumentException: invalid scan mode -1
   at android.bluetooth.le.ScanSettings$Builder.setScanMode(ScanSettings.java:213)
   at no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerImplLollipop.toImpl(BluetoothLeScannerImplLollipop.java:186)
   at no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerImplLollipop.startScanInternal(BluetoothLeScannerImplLollipop.java:70)
   at no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat.startScan(BluetoothLeScannerCompat.java:112)

It should fallback to a mode that it does support, which would probably be SCAN_MODE_LOW_POWER.

Add a scanning operation timeout

It would be good to have a scanning timeout to set a maximum of the process if desired. Something like this in the API would be nice:

@NonNull
public Builder setDuration(final long durationMillis) {
  if (durationMillis < 0) {
    throw new IllegalArgumentException("durationMillis must be > 0");
  }
  this.durationMillis = durationMillis;
  return this;
}

and start a Handlerwith that specific durationMillis until it is reached to stop the scanning process. I guess that would require a new onStop method in the ScanCallback abstract class.

What do you think guys? Is it something the library could handle or it's just better to manage ourselves those timeouts?

How to check that bluetooth device is connected or not?

I have using this library to scan and connect the Bluetooth devices to android app. Its working fine. Now once device is connect then i set Connected text in ListAdapter textview in the app that user can see that device is connected. After if any device goes to out of range or disconnected then i need to update the state Connected to Connecting..... in the ListAdapter UI but how i know that device is connected or not?
One other thing is if device is connected and its state changed (means any kind of notify ) then how to know that ?
Help would be very appreciate and thanks

Bonding failed

Hello,
I tested this case with Samsung S9 (Android 9.0) and Sony (Android 7.0). Same problem appears.
I also downloaded from Play Store "nRF Connect for Mobile" to make sure my implementation is not the real issue here. Same happens there.

  1. I find BLE device in list
  2. I do connection (everything is fine here)
  3. I do "Bonding"
  4. Pop-up PIN dialog appears, I enter PIN, bond is made successfully.
  5. I go to Bluetooth setting and do "unpair" on my BLE device.

then I procceed 1.-2. steps. But then, when I do "bonding" it says "bonding failed" and no PIN pop-up is shown. I tried to delete app, delete cache data on Bluetooth and restart device. At some point I made it possible to do the bonding once again. Followed the same path and then again after I unpaired device, I could not find a way to create bond with it.

My question is - is this supposed to be like that? Could it be, that my device is configurated somehow wrongly (after unpairing which is from user side, bonding data is not deleted or smth)?
I did try to refresh device cache ect., but nothing changed.

https://i.imgur.com/gzpWIau.png

Manufacturer Data / Mask seem to be ignored when filtering ScanResults

Hi,

I'm currently trying to set some ScanFilters when registering my BLEScanner to filter on service UUID and Manufacturer Data.

The thing is, while the ScanResults I get are properly filtered with service UUID, there is no filter applied on Manufacturer Data, resulting on inconsistent Scan Result filtering...

I tried the following:

filters.add(ScanFilter.Builder()
                .setServiceUuid(ParcelUuid.fromString(serviceUUID.toString()))
                .build())

filters.add(ScanFilter.Builder()
                .setManufacturerData(manufacturerId, manufacturerData, mask)
                .build())

or

filters.add(ScanFilter.Builder()
                .setManufacturerData(manufacturerId, manufacturerData, mask)
                .setServiceUuid(ParcelUuid.fromString(serviceUUID.toString()))
                .build())

coupled with scanner.startScan(filters, settings, callback)

Scan Results only seem to be filtered on Service UUID.

My manufacturerId is an int, manufacturerData is a ByteArray and mask is a ByteArray of the same size with full 1.

Can you please help me on this issue ?

[1.3.0][Android < Oreo] Scanning stops when app is swiped out of the "task-manager"

The new pendingIndent solution works great on Android >= Oreo.
I wrote a foreground service that handles the BLE stuff independently from the actual app. This service is the only place where startScan/stopScan is called.

When I call scanner.startScan(filters, settings, mService, pendingIntent); the scanning stops when i swipe the app out of the android "task-manager" (The foreground-service is still running). When I start the scan with scanner.startScan(filters, settings, scanCallback); scanning didn't stop.

I think this is the normal background task behavior when the task is started from an activity in the app. I wonder why the background task get destroyed when I start the scan in the foreground service.

Scan record is always a partial byte array

Not sure if I've configured this correctly, but I'm not seeing any scan results returned in my callback. It looks like the scanRecord byte[] is coming in as partial instead of complete when attempting to init a ScanRecord. When parseServiceUuid is called on line 224 inside ScanRecord.java, there is no data to parse, so I'm not seeing any returned scan results in my callback. I've implemented a different scanning service which returns the 128 bit complete data type from the same peripheral device. Am I missing some configuration settings that allows the scanner to return the completed byte[]?

I'm using the sample scanning code noted in your readme.

Device name is null on some conditions.

Hi,

Sometimes the device name is null on onBatchScanResults, switching bluetooth on/off doesn't help, but after scanning with nRFConnect, and rescan with library the problem resolved. Is there any configuration that nRFConnect use? or is there any cache that I should clear before starting scan?

Failed to resolve no.nordicsemi.android.support.v18:scanner

Its working fine in my current project. i am using Android Studio 3.2 and before 3.1. i have seen one warning message that change the compile to implementation. But when i change compile to implementation then this error is occur in android studio 3.2. As per google that compile is closed to end of the 2018 so i am trying to change it. So is there any update regarding this then its appreciate. I have checked this stack overflow link also.

Problem in reliability of receiving advertisements. #41

Hello,
I am in the process of designing an app which listens for any BLE advertisements, and filters them according to their contents. Currently, I am testing the reliability of the nordic BluetoothLeScannerCompat - that is, I am seeing if it will receive all advertisement data. I have a peripheral emitting an advertisement on channels 37-39, once every 40ms.

In nRF connect, all of these advertisements are received with great consistency, as shown in the "History" tab of any device. However, when I use the nordic (and Android Standard) Scanner, I am much less consistent in receiving these advertisements. In a 15 second timespan, my application received about 40 advertisements from the peripheral, whereas nRF Connect received about 150.

My code for the scanner:

String desiredMacAddress = the peripherals mac address.
BluetoothAdapter mBTAdapter;
BluetoothLeScannerCompat mBleScanner;
ScanCallback scanCallback  = new ScanCallback (){
                @Override
                public void onScanResult(int callbackType, ScanResult result){
                    if ( result.getDevice().getAddress().equals(desiredMacAddress )
                          appendMyTextView("\n You received me!");
                    });
                }
            };

public void init(){
        final BluetoothManager btManager = (BluetoothManager) 
        scanActivity.getSystemService(Context.BLUETOOTH_SERVICE);
        mBTAdapter = btManager.getAdapter();
        mBleScanner = BluetoothLeScannerCompat.getScanner();

        scanLeDevice(true)
}

private void scanLeDevice(final boolean enable){
        if(enable) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    //BLEDevice Scan has ended
                   stop()
                }
            }, 15000);
            mLeScanner.startScan(scanCallback);
        }
        else{
            mScanning = false;
            mLeScanner.stopScan(scanCallback);
        }
    }

private void stop(){
     scanLeDevice(false)
}

Any advice on how to improve scan reliability would be much appreciated!

BluetoothLeScannerImplOreo startScan PendingIntent causes leak that eventually fails all future scans

This problem might manifest itself with can't Register GATT client, MAX client reached: 32 output in an unfiltered log.

Please also refer to my StackOverflow question and self-answer:
https://stackoverflow.com/q/57104535/252308

Basically, BluetoothLeScannerImplOreo startScanInternal has the following code (I added the log line in my fork):

        final PendingIntent pendingIntent = createStartingPendingIntent(nonNullFilters,
                nonNullSettings, context, callbackIntent);
        Log.v(TAG, "#GATT startScanInternal: pendingIntent=" + pendingIntent);
        return scanner.startScan(nativeFilters, nativeSettings, pendingIntent);

stopScanInternal has the following code (log line added in my fork):

        final PendingIntent pendingIntent = createStoppingPendingIntent(context, callbackIntent);
        Log.v(TAG, "#GATT stopScanInternal: pendingIntent=" + pendingIntent);
        scanner.stopScan(pendingIntent);

Here is a log of my app starting and stopping a few scans:

2019-07-19 21:14:51.230 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.startScan(...)
2019-07-19 21:14:58.424 16905-16905/com.testapp V/BleScannerImplOreo: #GATT startScanInternal: pendingIntent=PendingIntent{1dfc67: android.os.BinderProxy@e560a14}
2019-07-19 21:14:58.468 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register 3c2e1fd9-d3fd-6897-a113-863aa50df781
2019-07-19 21:14:58.468 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=7
2019-07-19 21:14:58.478 16905-16905/com.testapp V/BleScannerManager: scan: #GATT bleScanner.startScan(...); result=SUCCESS(0)
2019-07-19 21:14:58.479 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.startScan(...)
2019-07-19 21:14:58.481 16905-16905/com.testapp E/BleScannerManager: #GATT bleScannerStartScanCount=1, elapsedMillisSinceBleScannerStartScanFirstTime=0
2019-07-19 21:15:03.521 1447-1447/? D/BtGatt.ScanManager: awakened up at time 614650173
2019-07-19 21:15:08.250 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.stopScan(...)
2019-07-19 21:15:08.255 16905-16905/com.testapp V/BleScannerImplOreo: #GATT stopScanInternal: pendingIntent=PendingIntent{dc4115f: android.os.BinderProxy@84087ac}
2019-07-19 21:15:08.259 1447-1982/? E/BtGatt.ContextMap: Context not found for info com.android.bluetooth.gatt.GattService$PendingIntentInfo@77d2d25
2019-07-19 21:15:08.260 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.stopScan(...)
2019-07-19 21:15:08.556 1447-1447/? D/BtGatt.ScanManager: awakened up at time 614655208
2019-07-19 21:15:08.570 1447-1554/? E/BtGatt.GattService: Exception: android.app.PendingIntent$CanceledException
2019-07-19 21:15:20.556 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.startScan(...)
2019-07-19 21:15:20.570 16905-16905/com.testapp V/BleScannerImplOreo: #GATT startScanInternal: pendingIntent=PendingIntent{2ce86d6: android.os.BinderProxy@84087ac}
2019-07-19 21:15:20.575 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register 6b444e39-d61a-1d92-52d6-afd6e901b56b
2019-07-19 21:15:20.575 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=8
2019-07-19 21:15:20.576 16905-16905/com.testapp V/BleScannerManager: scan: #GATT bleScanner.startScan(...); result=SUCCESS(0)
2019-07-19 21:15:20.576 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.startScan(...)
2019-07-19 21:15:20.576 16905-16905/com.testapp E/BleScannerManager: #GATT bleScannerStartScanCount=2, elapsedMillisSinceBleScannerStartScanFirstTime=22097
2019-07-19 21:15:23.264 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.stopScan(...)
2019-07-19 21:15:23.269 16905-16905/com.testapp V/BleScannerImplOreo: #GATT stopScanInternal: pendingIntent=PendingIntent{ebafcb0: android.os.BinderProxy@ebb6729}
2019-07-19 21:15:23.272 1447-1982/? E/BtGatt.ContextMap: Context not found for info com.android.bluetooth.gatt.GattService$PendingIntentInfo@3abaefa
2019-07-19 21:15:23.272 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.stopScan(...)
2019-07-19 21:15:24.968 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.startScan(...)
2019-07-19 21:15:24.980 16905-16905/com.testapp V/BleScannerImplOreo: #GATT startScanInternal: pendingIntent=PendingIntent{8b1626b: android.os.BinderProxy@ebb6729}
2019-07-19 21:15:24.990 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register 0bbb0b8f-2c63-dfc2-268d-fbfe39360ddf
2019-07-19 21:15:24.990 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=9
2019-07-19 21:15:24.990 16905-16905/com.testapp V/BleScannerManager: scan: #GATT bleScanner.startScan(...); result=SUCCESS(0)
2019-07-19 21:15:24.990 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.startScan(...)
2019-07-19 21:15:24.991 16905-16905/com.testapp E/BleScannerManager: #GATT bleScannerStartScanCount=3, elapsedMillisSinceBleScannerStartScanFirstTime=26511
2019-07-19 21:15:25.019 1447-1554/? E/BtGatt.GattService: Exception: android.app.PendingIntent$CanceledException
2019-07-19 21:15:25.795 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register 32a50296-06f2-ed4d-f83c-25da059a4a19
2019-07-19 21:15:25.795 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=10
2019-07-19 21:15:26.046 1447-1447/? D/BtGatt.ScanManager: awakened up at time 614672699
2019-07-19 21:15:27.000 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.stopScan(...)
2019-07-19 21:15:27.005 16905-16905/com.testapp V/BleScannerImplOreo: #GATT stopScanInternal: pendingIntent=PendingIntent{40e339d: android.os.BinderProxy@6340012}
2019-07-19 21:15:27.008 1447-1982/? E/BtGatt.ContextMap: Context not found for info com.android.bluetooth.gatt.GattService$PendingIntentInfo@96b43b4
2019-07-19 21:15:27.009 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.stopScan(...)
2019-07-19 21:15:28.679 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register f119757a-00ff-29b4-72e0-952c5e0db695
2019-07-19 21:15:28.679 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=10
2019-07-19 21:15:28.810 1447-1447/? D/BtGatt.ScanManager: awakened up at time 614675462
2019-07-19 21:15:28.822 1447-1554/? E/BtGatt.GattService: Exception: android.app.PendingIntent$CanceledException

Notice that the pendingIntent= logged during a startScan and stopScan do not match.
This means that the code never actually stops any PendingIntent started scans.
The pendingIndent passed to stopScan must be the exact same one that was passed to startScan.

You can usually only start about 28, max of 32, scans before the OS blocks all future scans.
This repros on every API >= 26 phone I have tried.

I can look in to a fix and send a PR, but I wanted to open this issue to see if there is anything else to discuss.

Unable to scan devices

Hi,

I have used the Sample provided in the description, without any filter.
But still I am not getting callbacks. I have also referred to nrf-blinky example which uses this library.
My Scan code is exactly same as that provided in except filter part https://github.com/NordicSemiconductor/Android-nRF-Blinky. But still no callbacks are received.

Phone Model - Oneplus 3.
Note - I am trying to search and connect a non nordic BLE device. will that have any impact on this?
Please help I am stuck on this :(
Thanks,
sat

ScanFilter setServiceUuid doesn't work?

When I use the scanner library to filter my Bluetooth LE devices ,I use the method "setServiceUuid " but doesn't work?

final String uuid = "0000fff0-0000-1000-8000-00805f9b34fb";

setServiceUuid(ParcelUuid.fromString(uuid))

Android Lollipop "blocking" some devices on scan results

Hi,
I have one problem in scan devices on Android Lollipop (5.1.1).

I have one device advertising constantly and sometimes the library don't return this device in advertisement results.
I was investigating the problem and I noted that when the lib don't return the advertisement anyone BLE app returns that advertisement.
It's like the Android has blocked that "device" and anyone app can't identify.

On newer Android versions I don't have this problem.

Someone knows what's happening?

PS: There is a fun fact that looking the LOG, I can see de BLE Address with and error, but I don't found any explanation about that.

09-15 15:09:01.268 4379-4579/? E/bt-btm: new address: 55:44:33:22:11:00

where my BLE Address is 55:44:33:22:11:00 but the result don't appear in the return scanned devices on the lib.

I have tried to filter by BLE Address, services, manufacturer data, etc etc, but I have the same problem.

Thanks in advanced.

Scanning Problem in API 6.0.1

hello. i'm using your library in my project. Its working perfectly in API 5, But when i test it on 6.0.1 ScanCallBack didn't called.
i'm using scanner.startScan(mScanCallback) method and onScanResult never triggered.
Hope you will reply soon and guide me through. thanks

Scanner doesn't find device when using filters.

Hi,

Thanks for your great library. I tried to find a heart rate monitor gadget, but unfortunately scanner.startScan(filter, settings, callback) doesn't return any result. When I use scanner.startScan(callback) it found the device. I tested with both service UUID and device name. I used complete 128bit service uuid 0000180D-0000-1000-8000-00805f9b34fb.

auto-stop scanning when BT turns off should 1) be option, 2) auto-resume when on (also optional)

Commit 8a20607 is nice, but I think will break my app.
My app already detects BT on/off and "pauses" or "resumes" scanning as necessary.
If Android-Scanner-Compat-Library automatically stops scanning then my app could see that has a hard stop and hard stop itself.

I haven't yet updated my dependency to confirm if you change breaks my app.
But, hear me out and please let me know if my opinion seems valid...

Again, nice change, but if you are going to automatically stop scanning then coolio, but that is only part of the story.
To make this a complete solution then you must also then detect when BT is turned on and automatically start scanning if the user of your library hasn't called stop.

Also, this auto-stop/start feature should be an option, which would be fine to default to on.

It is possible that this change doesn't break my code, but I think this library would benefit from a more complete solution.

How to include this library in project where min SDK < 18?

I'd like to include Android-Scanner-Compat-Library in a project where min SDK < 18 so that if the device SDK is < 18, then I wouldn't use BLE capabilities, and otherwise I would use it per this library.

However, the manifest requires min SDK 18. Is there any way around this?

NullPointerException with ScanFilter setManufacturerData

Great library! Encountered one problem.

With the normal ScanFilter object I can make this call to filter only advertisements that match the specific manufacturer ID (while not caring what the actual manufacturer data is).

private final ScanFilter mScanFilter = new ScanFilter.Builder()
            .setManufacturerData(MFG_ID, null)
            .build();

But making this call with this scanner compat library and running it on 5.0.1 (and possibly others) results in a crash due to the null byte array.

Here's the stack trace:

java.lang.NullPointerException: Attempt to get length of null array
            at no.nordicsemi.android.support.v18.scanner.ScanFilter.matchesPartialData(ScanFilter.java:345)
            at no.nordicsemi.android.support.v18.scanner.ScanFilter.matches(ScanFilter.java:302)
            at no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat$ScanCallbackWrapper.matches(BluetoothLeScannerCompat.java:298)
            at no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat$ScanCallbackWrapper.handleScanResult(BluetoothLeScannerCompat.java:248)
            at no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerImplLollipop$ScanCallbackImpl.onScanResult(BluetoothLeScannerImplLollipop.java:131)
            at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:347)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.