don / cordova-plugin-ble-central

Bluetooth Low Energy (BLE) Central plugin for Apache Cordova (aka PhoneGap)
Apache License 2.0
950 stars 604 forks source link

BLE Scan does not work on Android 12 when targetSDK is set to 31+ #875

Closed LDLCLid3 closed 2 years ago

LDLCLid3 commented 2 years ago

Hello !

I've a problem with scanning method on Android 12 (SDK 31). Since the update, if i start a scan, he will stopped directly and without errors on console. I have see that we need to add new Android permissions for Android 12 in the AndroidManifest.xml, but same issues here.

Someone has the same issue ?

peitschie commented 2 years ago

Hi! I don't yet have access to an Android 12 phone yet, so any assistance here would be great. Looking at the changes made in Android 12, I think you are on the right track however.

Reading https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android12-or-higher, BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, and BLUETOOTH_SCAN permissions are all runtime permissions so will require plugin changes to implement.

As a temporary workaround, you might try manually requesting the above permissions yourself using https://github.com/dpa99c/cordova-diagnostic-plugin, and see if that allows the scan to behave correctly.

If it does, I'd be interested to know so a patch can be raised here to fix it more widely.

LDLCLid3 commented 2 years ago

Hello Peitschie !

I will modify the plugin to implement all the changes for the new API of Android 12. I am already on the modifications, and I will have to submit a push request in the weekend or the beginning of next week, when I I will have tested the modifications made to the plugin and checked all API modifications.

Thank you for your message :)

chladnefazole commented 2 years ago

@peitschie I tried to use cordova-diagnostic-plugin for requesting permissions. When I call isBluetoothEnabled, it returns true. However scanning still does not work.

Scanning function looks like:

  public tryConnect() {
    cordova.plugins.diagnostic.isBluetoothEnabled(
      (enabled) => {
        console.log("Bluetooth is " + (enabled ? "enabled" : "disabled"));

        console.log("Starting scan...");
        this._ble.scan([], 5,
          (device) => { console.log("Device found: " + device); },
          () => { console.log("No device found."); }
        );
      },
      (error) => { console.error("The following error occurred: " + error); }
    );
  }

However I never see success message Device found OR failure message No device found. Chrome/app on phone do not freeze or anything, but after Starting scan no message arrives.

Hope it helps someone :)

peitschie commented 2 years ago

@chladnefazole just to clarify, you would be wanting to use cordova.plugins.diagnostic.requestRuntimePermissions to add the 3 additional permissions needed for Android 12.

Probably something like this:

const permissions = [
  "android.permission.BLUETOOTH_CONNECT",
  "android.permission.BLUETOOTH_SCAN",
];

cordova.plugins.diagnostic.requestRuntimePermissions(
  () => { ble.scan([], 5, (device) => console.log("Device found:", device) },
  (err) => console.log("Runtime permissions failed"),
  permissions
);
LDLCLid3 commented 2 years ago

Hello @peitschie,

I've done my code for android 12 permissions, but i can't push my branch on origin for begin a pull request. I don't know why... If you have a response ?

Thanks !

peitschie commented 2 years ago

That sounds exciting @LDLCLid3

I'd suggest this doco is a good place to start: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork

In summary:

  1. Create your own fork of this repo and push the code change there
  2. Raise a Pull Request in this repo to propose your changes for merging
chladnefazole commented 2 years ago

@peitschie I tried it like that at first, but it doesn't work for bluetooth permissions. You have to request one of the permissions defined as a runtime permission constant and none of the BT permissions are defined...

Looking at it now, I don't see any option in that library to request BT permissions on Android. Only on iOS is there requestBluetoothAuthorization. Maybe you know of another way?

mohitcis commented 2 years ago

Hello @peitschie,

Any update on this issue ?

Thanks!

peitschie commented 2 years ago

@mohitcis if you have the ability, it'd be worth trying out @LDLCLid3 's pull request #879 and see if that solves your issue. I'll try and push out an alpha prerelease with that change later today to make it a bit more accessible.

peitschie commented 2 years ago

@mohitcis I've published #879 in a pre-release package cordova-plugin-ble-central@1.4.2-alpha.0 on NPM Do you want to install this and see if it works for you?

mohitcis commented 2 years ago

Thank you so much @peitschie , Yes let me install the this pre-release package version and check it at my side. I will update you for the same.

mohitcis commented 2 years ago

Hello @peitschie and @LDLCLid3,

Thank you so much both of you for making changes in plugin, Can you both please help me in below issue ? I am getting this issue only after adding 1.4.2-alpha.0 version.

I have added this plugin into my app using below command :

ionic cordova plugin add cordova-plugin-ble-central@1.4.2-alpha.0 --save

After that I run app in mobile using :

ionic cordova run android --device

After that it is giving me below error (Also check below attached screenshot):

Task :app:processDebugResources FAILED FAILURE: Build failed with an exception.

Note : Please check below attached screenshot

Screenshot 2021-12-03 at 5 19 20 PM

peitschie commented 2 years ago

@mohitcis are you able to confirm which version of cordova and cordova-android you're using? Also, what is your min/max/targetSDKVersions from the config.xml?

It seems like the Android build step is confused by that... something we'll need to figure out how to improve!

mohitcis commented 2 years ago

Hi @peitschie,

Yes I am using following versions :

  1. Cordova : 10.0.0 (cordova-lib@10.1.0)
  2. cordova-android : android 10.1.1
  3. Android Target SDK : 30
  4. Android Minimum SDK : I did not mention in config.xml file but I think by default ionic might use 21 or 23

Please also check following below configuration as well :

Ionic: Ionic CLI : 6.18.1 (/Users/cis/.nvm/versions/node/v14.18.2/lib/node_modules/@ionic/cli) Ionic Framework : ionic1 1.3.4 @ionic/v1-toolkit : 1.0.22

Cordova: Cordova CLI : 10.0.0 (cordova-lib@10.1.0) Cordova Platforms : android 10.1.1, ios 6.2.0 Cordova Plugins : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.2.1, (and 22 other plugins)

Utility: cordova-res : 0.15.3 native-run : 1.5.0

System: Android SDK Tools : 26.1.1 (/Users/cis/Library/Android/sdk) NodeJS : v14.18.2 (/Users/cis/.nvm/versions/node/v14.18.2/bin/node) npm : 6.14.15 OS : macOS Big Sur

peitschie commented 2 years ago

Hrm. Finally got my hands on an Android 12 phone, and can confirm the issue you're seeing. I'll need some more time to troubleshoot, as the answer about what flags to set and how currently isn't obvious to me!

mohitcis commented 2 years ago

Okay @peitschie, Yes please take your time :)

I would like to request you to please reply on this ticket once you complete with plugin changes.

Thanks!

LDLCLid3 commented 2 years ago

Hi guys !

I'm using capacitor for me, and all my changes worked as well ! I don't know why u have this problem but, if i can help u for something, i can still look !

Best regards !

peitschie commented 2 years ago

So, the issue arises specifically when the target SDK is set to 31+. @mohitcis , you should be able to get away with the current released NPM package (v1.4.1) as long as your Android target SDK is kept to 30. In this configuration, Android compatibility hooks kick-in, ensuring the app gets the right permissions.

@LDLCLid3 the patch you've assembled here works well only if the target SDK is 31+ (which I presume is what you're running on your capacitor project?). Unfortunately, if the Android target SDK is 30 or earlier, the usesPermissionFlags causes a compile error in gradle. If I fix those, I run into the next problem that compiling with a target SDK of 30 but running on Android 12 breaks because ACCESS_FINE_LOCATION is required for this specific combination.

All in all, it's a tricky set of constraints to get working. If the manifest is updated with the new flags for Android 12, it is no longer compatible for building with Android 11 or earlier. If the manifest is adapted to compile on Android 11, it stops being able to run with the new permissions on Android 12 😒

I'll need to ponder a bit more whether it's possible to bring the improvements into the library in a way that doesn't break backwards compatibility.

LDLCLid3 commented 2 years ago

Hello @peitschie,

Yes, I did run into this problem at some point, however, I think Android is going to force us to compile to the latest SDK with every new "security" update. For this point, I think we should remove the permissions of the plugin manifest and put them in the manifest of the application. I don't know if this might work, but it would avoid having to compile on SDK 31+.

mohitcis commented 2 years ago

Hi @peitschie and @LDLCLid3 ,

Thank you so much both of you for working so hard to make changes in plugin.

Actually my requirement is, This plugin should work on Android target SDK 31+ and lower version of SDK also, I would like to request both of you to please let me know what changes I need to do to make it work for all version of SDK?

Thanks!

LDLCLid3 commented 2 years ago

Hello @mohitcis !

No worries, it's normal :)

If you want your application to work, you can use my git repo as long as this repository hasn't merged my changes, and put your compileSDKVersion and your targetSDKVersion in version 31.

Normally you won't need to make any more changes and the app will work fine on the latest versions of android.

mohitcis commented 2 years ago

Hi @LDLCLid3 ,

Thank you! I will put compileSDKVersion and your targetSDKVersion in version 31.

Will your git repo also work on lower version of SDK like 30, 29 etc ?

Thanks!

LDLCLid3 commented 2 years ago

The only requirement for your Android Studio to compile is to set your Target variables and compile to 31 or higher.

If you use these values, you will have no problem running it on other versions of android (except for versions prior to 23 it seems to me).

mohitcis commented 2 years ago

Okay Thanks @LDLCLid3, I will check it and will update you for the same.

Also If it works at my side then I will use your repo until @peitschie merge your pull request.

Thanks!

mohitcis commented 2 years ago

Hi @LDLCLid3,

I have removed the the official ionic plugin (Created by Don) and added your plugin using following command :

Ionic cordova plugin add https://github.com/LDLCLid3/cordova-plugin-ble-central.git

After adding plugin I added android platform 10.1.1 into app and also added Android target SDK to 31, After that I try to run app into mobile then I got below issue : Screenshot 2021-12-16 at 6 16 16 PM

After that I go to manifest file manually and add android:exported = true and again run the app but got below issue :

Screenshot 2021-12-16 at 6 20 00 PM

Can you please help in this ?

Thanks!

mohitcis commented 2 years ago

Hi @peitschie and @LDLCLid3 ,

Please help me to make BLE Plugin work on Android 12.

Thanks!

mohitcis commented 2 years ago

Hi @LDLCLid3,

I have removed the the official ionic plugin (Created by Don) and added your plugin using following command :

Ionic cordova plugin add https://github.com/LDLCLid3/cordova-plugin-ble-central.git

After adding plugin I added android platform 10.1.1 into app and also added Android target SDK to 31, After that I try to run app into mobile then I got below issue : Screenshot 2021-12-16 at 6 16 16 PM

After that I go to manifest file manually and add android:exported = true and again run the app but got below issue :

Screenshot 2021-12-16 at 6 20 00 PM

Can you please help in this ?

Thanks!

Hi @peitschie and @LDLCLid3 ,

First of all thank you so much both of you, Now BLE plugin (created by @LDLCLid3 : https://github.com/LDLCLid3/cordova-plugin-ble-central.git) is working on android version 12.

So after adding "android:exported = true" into "AndroidManifest.xml" file (path : platforms/android/app/src/AndroidManifest.xml), Earlier I was getting below issue :

Screenshot 2021-12-16 at 6 20 00 PM

I did R&D for this issue and found that this issue was occurring because I was using JDK 8 version but I need to use at-least JDK 11 for running app into Android 12. So I have installed JDK 11.0.13 version and set path for it in Mac OS (set path in bash or zsh file).

After that I add plugin created by @LDLCLid3 using below command :

Ionic cordova plugin add https://github.com/LDLCLid3/cordova-plugin-ble-central.git

After that I tried to run the app into mobile it run successfully and also the BLE plugin created by @LDLCLid3 's worked fine and my bluetooth devices is working fine in Android 12.

@LDLCLid3 Can you please create pull request, I think your android 12 fix can be mergeable. @peitschie can you also please check this at your side ?

Thanks Guys!

Path-A commented 2 years ago

@LDLCLid3 I'm integrating this into my ionic capacitor project. Your pull-request is working on my android 11 phone, but I'm having the same behavior on my Android 12 where it hangs during connection.

Are you using the typical installation instructions:

// Install Core library (once per project)
npm install @awesome-cordova-plugins/core

// Install Ionic Native TypeScript wrapper
npm install @awesome-cordova-plugins/ble 

// Install Cordova plugin
npm install https://github.com/LDLCLid3/cordova-plugin-ble-central

// Update native platform project(s) to include newly added plugin
ionic cap sync

Or are you forgoing the native libraries altogether?

@mohitcis Maybe you could provide how you're importing / interacting with the library without the native wrappers?

For some additional info, it seems to get stuck connecting to the target bluetooth device using the autoconnect feature. When I use the regular connect method, it starts to connect, but ultimately is never successful (giving an error). On Android 11, both of these still work. This is the case regardless of whether I build for sdk 31 or 30.

Resolve Msg: Connecting to Device!
V/Capacitor/Plugin: To native (Cordova plugin): callbackId: BLE234351336, service: BLE, action: stopScan, actionArgs: []
D/BluetoothAdapter: isLeEnabled(): ON
V/Capacitor/Plugin: To native (Cordova plugin): callbackId: BLE234351337, service: BLE, action: connect, actionArgs: ["ADDRESS HERE"]
D/BluetoothGatt: connect() - device: ADDRESS HERE, auto: false
D/BluetoothGatt: registerApp()
D/BluetoothGatt: registerApp() - UUID=UUID HERE
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=9
D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=9 device=ADDRESS HERE
D/BluetoothGatt: discoverServices() - device: ADDRESS HERE
D/BluetoothGatt: onConnectionUpdated() - Device=ADDRESS HERE interval=6 latency=0 timeout=500 status=0
D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=9 device=ADDRESS HERE
D/BluetoothGatt: cancelOpen() - device: ADDRESS HERE
D/BluetoothGatt: close()
D/BluetoothGatt: unregisterApp() - mClientIf=9
V/Capacitor/Plugin: To native (Cordova plugin): callbackId: BLE234351338, service: BLE, action: disconnect, actionArgs: ["ADDRESS HERE"]
Reject Msg: Disconnected: {"name":"NAME HERE","id":"ADDRESS HERE","errorMessage":"Peripheral Disconnected"}

EDIT: After spending a lot of time debugging this from the peripheral's bluetooth logs, it seems that there is a timeout disconnect that occurs. The phone has essentially a 0% success rate (although, I have rarely/randomly gotten it to connect). In a weird turn of events, going into the Android 12 Developer Options and enabling Gabeldorsche Bluetooth feature stack allows the phone to properly connect to the peripheral. The phone utilized is a Pixel 6.

EDIT 2: I just got my hands on a Galaxy S22. On Android 12, by default, it can properly connect, but it seems to have a moderately-low success rate (about 50% success) and it takes longer to connect. This is the case for both the pull-request (target 31 sdk) and the current repo 1.4.4. set to 30 target. Gabeldorsche Bluetooth feature stack is oddly missing from the developer options, so I cannot try that on the S22.

peitschie commented 2 years ago

@Path-A it sounds like the issue you're seeing here is unrelated to the scan permissions problem here. It might be worth moving this to it's own issue for further discussion to avoid confusion?

Path-A commented 2 years ago

Sure, that sounds fine. I'm puzzled by why the specific developer option seems to fix all of my issues.

peitschie commented 2 years ago

Android 12 support has been added in #923

@Path-A if you're still seeing issues with 1.5.0, please raise a new issue with the symptoms you're encountering and we'll see if we can sort it.