dpa99c / cordova-diagnostic-plugin

Cordova/Phonegap plugin to manage device settings
540 stars 361 forks source link

Problem on setBluetoothState on android version 9 #352

Closed akimakitalo closed 4 years ago

akimakitalo commented 5 years ago

I'm submitting a ... (check one with "x"):

Bug report

Current behavior: On android version 9 (Honor 9), setBluetoothState() does not work correctly anymore, and successCallback returns an incorrect value. I cannot confirm if this is a general change on android 9.0, or if this is a Huawei change that applies to Honor phones.

Prior to update to android 9, setBluetoothState correctly turned bluetooth on, while success callback was called properly.

After updating to android 9, setBluetoothState now causes a popup from OS asking the user to allow/deny change to bluetooth state. Presumably this is a security update intended to limit the ability of apps to change bluetooth state without user permission.

However the success callback is still called immediately and always returns OK, even if user has not yet granted permission to let the application change the bluetooth state or even if user ultimately denies permission.

Example of how it works right now on android 9:

  1. setBluetoothState() called with intent to set state to true.
  2. setBluetoothState() success callback called with "OK". At this point, bluetooth state has not changed.
  3. OS shows popup asking the user to confirm if bluetooth state should be changed.
  4. User eventually presses yes or no.
  5. If user pressed yes, bluetooth state changes to true. If user presses no, bluetooth state does not change.

Expected behavior: setBluetoothState() should probably wait for user confirmation before calling the success callback, and call errorCallback if user denies permission to change bluetooth state.

Example on how it should work:

  1. setBluetoothState() called with intent to set state to true.
  2. OS shows popup asking the user to confirm if bluetooth state should be changed.
  3. User eventually presses yes or no.
  4. If user pressed yes, successCallback called. If user pressed no, errorCallback called with somekind of user_denied_permission error.

Steps to reproduce:

On android 9, simply do the following:

cordova.plugins.diagnostic.setBluetoothState((result) => {
    console.log(`successCallback result is ${result}, but bluetooth state has not yet changed, and will not change until user grants permission on OS popup.`);
}, (err) => {
    console.log(err);
}, true);

Environment information

Runtime issue



dpa99c commented 5 years ago

Looks like there's not an easy fix here.

According to this SO post, modifying Bluetooth state programmatically (without prompting user permission) on Android 9+ requires WRITE_SETTINGS permission which itself requires a special permission request process (see here).

So the best course of action (as you've suggested) would be to try to hook in to the outcome of the permission request dialog. However so far I've not found any example of how the plugin can get async notification of the user decision in that dialog on Android 9.

dpa99c commented 5 years ago

I've tested this on a Pixel 2 running Android 9.0 and I'm not seeing the permissions dialog appear: setBluetoothState() works as expected. So I wonder if this is specific to the Huawei Honor 9 variant of Android 9?

dpa99c commented 5 years ago

Also tested on Android 10/Q Beta 4 running on Pixel 2 and also no permissions dialog when using setBluetoothState() to enable/disable the Bluetooth device setting

dpa99c commented 4 years ago

Closed as unable to repro

egeozer commented 2 years ago

I know this is closed, but in order to reproduce, you need a Huawei phone with Android 9+.