Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

LBluetoothLeScannerCompat fails to work when using ScanSettings.CALLBACK_TYPE_FIRST_MATCH | ScanSettings.CALLBACK_TYPE_MATCH_LOST #214

Open
saiimons opened this issue Mar 7, 2015 · 10 comments

Comments

@saiimons
Copy link

saiimons commented Mar 7, 2015

I am running the code on a Nexus 9, with Android 5.0.1.
Scan fails to start with the following message :

java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission: Neither user 10119 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.bluetooth.IBluetoothGatt$Stub$Proxy.startScan(IBluetoothGatt.java:747)
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.onClientRegistered(BluetoothLeScanner.java:299)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:56)
at android.os.Binder.execTransact(Binder.java:446)

I found out that the parameters are handled using reflection.

The only compatible setting is the CALLBACK_TYPE_ALL_MATCHES.

In my opinion we could fix the issue by :

  • Not using reflection
  • Changing the ScanCallback in order to handle these parameters.

I am working on a fix, and will probably post a reply about it.

@g-ortuno
Copy link
Contributor

g-ortuno commented Mar 7, 2015

Do you have the correct permissions in the manifest?

On Sat, Mar 7, 2015, 2:17 PM Simon GUEROUT [email protected] wrote:

I am running the code on a Nexus 9, with Android 5.0.1.
Scan fails to start with the following message :

java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission: Neither
user 10119 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at
android.bluetooth.IBluetoothGatt$Stub$Proxy.startScan(IBluetoothGatt.java:747)
at
android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.onClientRegistered(BluetoothLeScanner.java:299)
at
android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:56)
at android.os.Binder.execTransact(Binder.java:446)

I found out that the parameters are handled using reflection.

The only compatible setting is the CALLBACK_TYPE_ALL_MATCHES.

In my opinion we could fix the issue by :

  • Not using reflection
  • Changing the ScanCallback in order to handle these parameters.

I am working on a fix, and will probably post a reply about it.


Reply to this email directly or view it on GitHub
#214.

@saiimons
Copy link
Author

saiimons commented Mar 7, 2015

Well, I have BLUETOOTH and BLUETOOTH_ADMIN, but as BLUETOOTH_PRIVILEGED is not supposed to be used, I did not include it at first.

public static final String BLUETOOTH_PRIVILEGED
Allows applications to pair bluetooth devices without user interaction, and to allow or disallow phonebook access or message access. This is not available to third party applications.

Constant Value: "android.permission.BLUETOOTH_PRIVILEGED"

Even including it does not change anything.

Here is the code I am using

scanner = BluetoothLeScannerCompatProvider.getBluetoothLeScannerCompat(mContext);
// THIS FAILS
scanner.startScan(
  Arrays.asList(new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString("7265656c-7941-6374-6976-652055554944")).build()),
  new ScanSettings.Builder() //
      .setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH | ScanSettings.CALLBACK_TYPE_MATCH_LOST) //
      .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) //
      .setScanResultType(ScanSettings.SCAN_RESULT_TYPE_FULL) //
      .build(),
  scanCallback
);

// THIS WORKS
scanner.startScan(
  Arrays.asList(new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString("7265656c-7941-6374-6976-652055554944")).build()),
  new ScanSettings.Builder() //
      .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) //
      .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) //
      .setScanResultType(ScanSettings.SCAN_RESULT_TYPE_FULL) //
      .build(),
  scanCallback
);

@g-ortuno
Copy link
Contributor

g-ortuno commented Mar 7, 2015

Take a look at this. It seems there is one extra permission needed for the
library.
https://github.com/google/uribeacon/blob/master/android-uribeacon/uribeacon-sample/src/main/AndroidManifest.xml
Also if you look at the BLE API in lollipop it says only the all matches is
supported.

On Sat, Mar 7, 2015, 2:51 PM Simon GUEROUT [email protected] wrote:

Well, I have BLUETOOTH and BLUETOOTH_ADMIN, but as BLUETOOTH_PRIVILEGED is
not supposed to be used, I did not include it at first.

public static final String BLUETOOTH_PRIVILEGED
Allows applications to pair bluetooth devices without user interaction,
and to allow or disallow phonebook access or message access. This is not
available to third party applications.

Constant Value: "android.permission.BLUETOOTH_PRIVILEGED"

Even including it does not change anything.

Here is the code I am using

scanner = BluetoothLeScannerCompatProvider.getBluetoothLeScannerCompat(mContext);// THIS FAILS
scanner.startScan(
Arrays.asList(new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString("7265656c-7941-6374-6976-652055554944")).build()),
new ScanSettings.Builder() //
.setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH | ScanSettings.CALLBACK_TYPE_MATCH_LOST) //
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) //
.setScanResultType(ScanSettings.SCAN_RESULT_TYPE_FULL) //
.build(),
scanCallback
);
// THIS WORKS
scanner.startScan(
Arrays.asList(new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString("7265656c-7941-6374-6976-652055554944")).build()),
new ScanSettings.Builder() //
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) //
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) //
.setScanResultType(ScanSettings.SCAN_RESULT_TYPE_FULL) //
.build(),
scanCallback
);


Reply to this email directly or view it on GitHub
#214 (comment).

@saiimons
Copy link
Author

saiimons commented Mar 7, 2015

The extra permission is not used in Lollipop, but it is in my Manifest.
As for the ALL_MATCHES vs the FIRST_MATCH|MATCH_LOST, it is handled for the older versions in JbBluetoothLeScannerCompat.
I'll try to code a similar function so that the feature is supported in Lollipop.

@saiimons
Copy link
Author

saiimons commented Mar 7, 2015

I am working on a project based on parts of this library : https://github.com/reelyactive/ble-android-sdk
I'll fix my project and port the changes in this one (I'll submit a pull request)

@g-ortuno
Copy link
Contributor

g-ortuno commented Mar 7, 2015

The compat library uses the ble lollipop library if available (where only
all matches is supported) . If you're on a nexus 9 then it's probably not
using the jellybean library.

On Sat, Mar 7, 2015, 3:19 PM Simon GUEROUT [email protected] wrote:

I am working on a project based on parts of this library :
https://github.com/reelyactive/ble-android-sdk
I'll fix my project and port the changes in this one (I'll submit a pull
request)


Reply to this email directly or view it on GitHub
#214 (comment).

@saiimons
Copy link
Author

saiimons commented Mar 7, 2015

I tried using both versions of the API on hte Nexus 9 and using FIRST_MATCH|MATCH_LOST fails with the newest :

// GO LOLLIPOP
scanner = BluetoothLeScannerCompatProvider.getBluetoothLeScannerCompat(mContext);
// GO JELLYBEAN
scanner = BluetoothLeScannerCompatProvider.getBluetoothLeScannerCompat(mContext, false);

@g-ortuno
Copy link
Contributor

g-ortuno commented Mar 7, 2015

So the first one doesn't work but the second one does?

On Sat, Mar 7, 2015, 3:28 PM Simon GUEROUT [email protected] wrote:

I tried using both versions of the API on hte Nexus 9 and using
FIRST_MATCH|MATCH_LOST fails with the newest :

// GO LOLLIPOP
scanner = BluetoothLeScannerCompatProvider.getBluetoothLeScannerCompat(mContext);// GO JELLYBEAN
scanner = BluetoothLeScannerCompatProvider.getBluetoothLeScannerCompat(mContext, false);


Reply to this email directly or view it on GitHub
#214 (comment).

@saiimons
Copy link
Author

saiimons commented Mar 9, 2015

So I tried 4 cases:

  • JB APIs + ALL_MATCHES => OK
  • JB APIs + FIRST_MATCH|MATCH_LOST => OK
  • Lollipop APIs + ALL_MATCHES => OK
  • Lollipop APIs + FIRST_MATCH|MATCH_LOST => NOT OK
    The issue comes from the fact that the ScanSettings are not used the same way in JbBluetoothLeScannerCompat and LBluetoothLeScannerCompat

In the JbBluetoothLeScannerCompat the adresses seen during the scan are kept in memory, in order to track events when using FIRST_MATCH|MATCH_LOST, in LBluetoothLeScannerCompat there is a call to

if (method.toString().contains(".setCallbackType(")) {
    method.invoke(builder, settings.getCallbackType());
    callbackTypeSet = true;
}

which leads to the error.
Looking at the Android source code shows that these are not public (yet).
(https://android.googlesource.com/platform/frameworks/base/+/android-5.0.2_r1/core/java/android/bluetooth/le/ScanSettings.java)

In order to support FIRST_MATCH|MATCH_LOST, the same code as in JbBluetoothLeScannerCompat#callbackLeScanClients
should be used for new matches (+ an alarm to check for lost matches ?).

@Peter767
Copy link

Peter767 commented Dec 3, 2019

I am running the code on a Nexus 9, with Android 5.0.1.
Scan fails to start with the following message :

java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission: Neither user 10119 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.bluetooth.IBluetoothGatt$Stub$Proxy.startScan(IBluetoothGatt.java:747)
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.onClientRegistered(BluetoothLeScanner.java:299)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:56)
at android.os.Binder.execTransact(Binder.java:446)

I found out that the parameters are handled using reflection.

The only compatible setting is the CALLBACK_TYPE_ALL_MATCHES.

In my opinion we could fix the issue by :

  • Not using reflection
  • Changing the ScanCallback in order to handle these parameters.

I am working on a fix, and will probably post a reply about it.

I am working on it. I will fix it within 10 days. I got the real issue I will fix it. for more information click scanner.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants