Skip to content

Commit b8679a1

Browse files
authored
Fix permission page not showing if service disabled but all permissions granted (#5)
* Icon now accept widget * Do not show disclosure page again if it is already shown * fix build * Fix permission page not showing if service disabled but all permissions granted * update doc to clarify serviceItem config * Fix showing all items even when only one item needed to be requested
1 parent e742ae9 commit b8679a1

File tree

5 files changed

+46
-11
lines changed

5 files changed

+46
-11
lines changed

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,22 @@ dependencies:
1717
permission_handler: ^10.2.0
1818
```
1919
2. This package depends on [permission_handler](https://pub.dev/packages/permission_handler). Perform setup according to that package.
20-
3. If any features is required, it is highly recommended to also set the `<uses-feature>` tag in AndroidManifest.xml. Refer to [relevant Android Developers page](https://developer.android.com/guide/topics/manifest/uses-feature-element) for details.
20+
3. On Android, if you use `POST_NOTIFICATIONS` permission, update the `targetSdkVersion` in `build.gradle` to at least 33 so that the permission request dialog is shown correctly. Refer to [relevant Android Developer page](https://developer.android.com/develop/ui/views/notifications/notification-permission) for details.
21+
```groovy
22+
android {
23+
// ...
24+
defaultConfig {
25+
compileSdkVersion 33
26+
targetSdkVersion 33
27+
// ...
28+
}
29+
// ...
30+
}
31+
```
32+
4. If any features is required, it is highly recommended to also set the `<uses-feature>` tag in AndroidManifest.xml. Refer to [relevant Android Developers page](https://developer.android.com/guide/topics/manifest/uses-feature-element) for details.
2133

2234
## Usage
23-
1. Create an instance of FlutterForcePermission, providing configuration.
35+
1. Create an instance of FlutterForcePermission, providing configuration. Refer to documentation for [FlutterForcePermissionConfig] for details.
2436
```dart
2537
final perm = FlutterForcePermission(
2638
FlutterForcePermissionConfig(

lib/flutter_force_permission.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,21 @@ class FlutterForcePermission {
2323

2424
final TestStub _service;
2525

26+
bool _showing = false;
27+
2628
/// Show disclosure page.
2729
///
2830
/// This will show the disclosure page according to the provided configuration, and handles requesting permissions.
31+
/// If the disclosure page is already shown, it will do nothing.
2932
/// Returns a map of Permission and their status after requesting the permissions.
3033
/// Only permissions specified in the configuration will be included in the return value.
3134
Future<Map<Permission, PermissionServiceStatus>> show(
3235
NavigatorState navigator,
3336
) async {
3437
// Check for permissions.
3538
final permissionStatuses = await getPermissionStatuses();
39+
if (_showing) return permissionStatuses;
40+
_showing = true;
3641

3742
if (permissionStatuses.values
3843
.every((element) => element.status == PermissionStatus.granted)) {
@@ -54,6 +59,12 @@ class FlutterForcePermission {
5459
needShow = true;
5560
break;
5661
}
62+
if (perm is PermissionWithService &&
63+
permissionStatuses[perm]?.serviceStatus == ServiceStatus.disabled &&
64+
permConfig.required) {
65+
needShow = true;
66+
break;
67+
}
5768
}
5869
}
5970

@@ -72,6 +83,8 @@ class FlutterForcePermission {
7283
),
7384
);
7485

86+
_showing = false;
87+
7588
// Check for permission status again as it is likely updated.
7689
return getPermissionStatuses();
7790
}

lib/permission_item_config.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,19 @@ class PermissionItemConfig {
2121
/// The display item configuration for these permission(s). Refer to [PermissionItemText] for details.
2222
final PermissionItemText itemText;
2323

24-
/// If the permission has an associated service (e.g. location), this service
25-
/// will also be checked for availability.
24+
/// If the permission has an associated service (e.g. location) and this permission is required,
25+
/// this service will also be checked for availability.
2626
/// If service is unavailable and this item is not null, the disclosure page will
2727
/// show a disclosure item for this service, before `itemText`.
28-
/// If this permission is required, users will also be asked to enable the service.
28+
/// Users will also be asked to enable the service.
29+
///
30+
/// *Note*: This is used only when `required` is true.
2931
final PermissionItemText? serviceItemText;
3032

3133
/// Whether these permission(s) are required.
3234
///
33-
/// If it is required, users cannot migrate out of disclosure page until the permission is granted. `forcedPermissionDialogConfig` should include configuration for the
35+
/// If it is required, users cannot migrate out of disclosure page until the permission is granted.
36+
/// `forcedPermissionDialogConfig` under `itemText` should include configuration for the
3437
/// dialog shown when required permission are denied.
3538
final bool required;
3639
}

lib/permission_item_text.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class PermissionItemText {
1616
/// The Icon for the permission item.
1717
///
1818
/// If omitted, a default icon will be provided.
19-
final Icon? icon;
19+
final Widget? icon;
2020

2121
/// Detailed text for the permission.
2222
///

lib/src/views/disclosure_page.dart

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,17 @@ class _DisclosurePageState extends State<DisclosurePage>
109109

110110
final permissionItems =
111111
widget.permissionConfig.permissionItemConfigs.expand((e) {
112-
final denied = widget.permissionStatuses.values
113-
.any((element) => element.status != PermissionStatus.granted);
114-
final serviceDisabled = widget.permissionStatuses.values
115-
.any((element) => element.serviceStatus == ServiceStatus.disabled);
112+
var denied = false;
113+
var serviceDisabled = false;
114+
for (final Permission p in e.permissions) {
115+
if (widget.permissionStatuses[p]?.status != PermissionStatus.granted) {
116+
denied = true;
117+
}
118+
if (widget.permissionStatuses[p]?.serviceStatus ==
119+
ServiceStatus.disabled) {
120+
serviceDisabled = true;
121+
}
122+
}
116123
final itemText = e.itemText;
117124
final serviceText = e.serviceItemText;
118125
final permission = e.permissions.first;

0 commit comments

Comments
 (0)