Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix android bluetooth permission request above api version 30 #993

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions permission_handler_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
## 10.2.1

* Check for BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE or BLUETOOTH_CONNECT instead of BLUETOOTH permissions on api versions above 30.

## 10.2.0

* Added support for the new Android 13 permissions: SCHEDULE_EXACT_ALARM, READ_MEDIA_IMAGES, READ_MEDIA_VIDEO and READ_MEDIA_AUDIO
- Added support for the new Android 13 permissions: SCHEDULE_EXACT_ALARM, READ_MEDIA_IMAGES, READ_MEDIA_VIDEO and READ_MEDIA_AUDIO

## 10.1.0

* Added support for the new Android 13 permission: NEARBY_WIFI_DEVICES.
- Added support for the new Android 13 permission: NEARBY_WIFI_DEVICES.

## 10.0.0

* __BREAKING CHANGE__: Updated Android `compileSdkVersion` to `33` to handle the new `POST_NOTIFICATIONS` permission.
> When updating to version 10.0.0 make sure to update the `android/app/build.gradle` file and set the `compileSdkVersion` to `33`.
- **BREAKING CHANGE**: Updated Android `compileSdkVersion` to `33` to handle the new `POST_NOTIFICATIONS` permission.
> When updating to version 10.0.0 make sure to update the `android/app/build.gradle` file and set the `compileSdkVersion` to `33`.

## 9.0.2+1

* Undoes PR [#765](https://github.com/baseflow/flutter-permission-handler/pull/765) which by mistake requests write_external_storage permission based on the target SDK instead of the actual SDK of the Android device.
- Undoes PR [#765](https://github.com/baseflow/flutter-permission-handler/pull/765) which by mistake requests write_external_storage permission based on the target SDK instead of the actual SDK of the Android device.

## 9.0.2

* Moves Android implementation into its own package.
- Moves Android implementation into its own package.
Original file line number Diff line number Diff line change
Expand Up @@ -481,12 +481,36 @@ private int checkNotificationPermissionStatus(Context context) {
}

private int checkBluetoothPermissionStatus(Context context) {
List<String> names = PermissionUtils.getManifestNames(context, PermissionConstants.PERMISSION_GROUP_BLUETOOTH);
boolean missingInManifest = names == null || names.isEmpty();
if (missingInManifest) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
Copy link
Contributor

@wujek-srujek wujek-srujek Jul 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have just spent some time with this library and getting to know its code and testing it on various Android devices, and here is the result of my research: this change (and PR) seems to be unnecessary, at least with version 10.4.2.

As you can see here https://github.com/Baseflow/flutter-permission-handler/blob/permission_handler_v10.4.2/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionManager.java#L322-L324 the checkBluetoothPermissionStatus method edited here is used if the new permissions are checked on a device with API level < S (31) - in this case the library will simply fall back to checking for the old Permissions.BLUETOOTH (code before this PR). If the current device is 31 or higher, the method will not be called and the permissions will be checked by the code starting here: https://github.com/Baseflow/flutter-permission-handler/blob/permission_handler_v10.4.2/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionManager.java#L327.

Similarly, requestPermissions (not touched in this PR) works correctly - on pre-31 devices it will first determine the status of the permissions (by using checkBluetoothPermissionStatus and the fallback logic as described above) and because Permissions.BLUETOOTH is a 'normal' permission, as long as it is in the manifest it will be 'granted' (not having it in the manifest is an error), so requesting it is a no-op - it will not put the permission to permissionsToRequest list. On 31 and later devices, it will correctly request the new permissions.

Which means - as long as the Flutter part of you application uses new permissions, it will all work even on pre-31 devices as the library is smart enough to fallback to the old permission if new ones are used on old devices. Tested with both a 33 and 23 device.

As a side note, irrelevant to this PR, the same logic applies to the new Permissions.POST_NOTIFICATIONS introduced in API level 33 - if used on a pre-33 device, this library falls back to using the NotificationManagerCompat for the check, and 33 and later check the permission - see https://github.com/Baseflow/flutter-permission-handler/blob/permission_handler_v10.4.2/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionManager.java#L479-L492.

// BLUETOOTH permission was removed in Android S in favor of BLUETOOTH_SCAN,
// BLUETOOTH_ADVERTISE and BLUETOOTH_CONNECT.
// This means above version 30 we need to check if any one of those permissions
// are present instead.
boolean scanPermission = checkPermissionStatus(context,
PermissionConstants.PERMISSION_GROUP_BLUETOOTH_SCAN);
boolean advertisePermission = checkPermissionStatus(context,
PermissionConstants.PERMISSION_GROUP_BLUETOOTH_ADVERTISE);
boolean connectPermission = checkPermissionStatus(context,
PermissionConstants.PERMISSION_GROUP_BLUETOOTH_CONNECT);

if (!scanPermission && !advertisePermission && !connectPermission) {
Log.d(PermissionConstants.LOG_TAG, "Of the bluetooth permissions (BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE or BLUETOOTH_CONNECT) missing in manifest");
return PermissionConstants.PERMISSION_STATUS_DENIED;
}
return PermissionConstants.PERMISSION_STATUS_GRANTED;
}
// legacy check for BLUETOOTH permission
boolean bluetoothPermission = checkPermissionStatus(context, PermissionConstants.PERMISSION_GROUP_BLUETOOTH);
if (!bluetoothPermission) {
Log.d(PermissionConstants.LOG_TAG, "Bluetooth permission missing in manifest");
return PermissionConstants.PERMISSION_STATUS_DENIED;
}
return PermissionConstants.PERMISSION_STATUS_GRANTED;
}

private boolean checkPermissionStatus(Context context, @PermissionConstants.PermissionGroup int permission) {
List<String> names = PermissionUtils.getManifestNames(context, permission);
return names != null || !names.isEmpty();
}
}
}
Comment on lines +515 to 516

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one of these should remain. If both are kept this results in an error

2 changes: 1 addition & 1 deletion permission_handler_android/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class _PermissionState extends State<PermissionWidget> {
return ListTile(
title: Text(
_permission.toString(),
style: Theme.of(context).textTheme.bodyText1,
style: Theme.of(context).textTheme.bodyLarge,
),
subtitle: Text(
_permissionStatus.toString(),
Expand Down
2 changes: 1 addition & 1 deletion permission_handler_android/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: permission_handler_android
description: Permission plugin for Flutter. This plugin provides the Android API to request and check permissions.
version: 10.2.0
version: 10.2.1
homepage: https://github.com/baseflow/flutter-permission-handler

environment:
Expand Down