Flutter-permission-handler: openAppSettings not opening App Settings Menu.

Created on 15 Dec 2020  路  3Comments  路  Source: Baseflow/flutter-permission-handler

馃悰 Bug Report

When the storage permission is permanently denied by selecting 'deny' on the permission request dialog menu twice, calls to openAppSettings return with a true result without actually navigating to the settings menu. This is the worst case for the developer since the result value doesn't notify the application that anything went wrong, leaving the application permanently locked out without more intelligent intervention from the end user.

Expected behavior

Open System settings menu when permission is permanently denied and print true on exit or else print false if the settings menu could not be opened.

Reproduction steps

Flutter 1.22.4

  var galleryWritePermission = Permission.storage;
  var permissionStatus = await galleryWritePermission.status;
  // Gallery write permissions are required so if the user has opted to
  // never see the permissions dialog, we have to send them to the
  // system's settings to manually permit it.
  if (permissionStatus.isPermanentlyDenied) {
    print('${await openAppSettings()}'); // returns true but does not actually open the app settings
  }
  // Request gallery write permissions if not permanently denied. If successful,
  // the user may continue to make their selection.
  // Otherwise, we back out and the user may try again.
  permissionStatus = await galleryWritePermission.request();
  if (!permissionStatus.isGranted) return;

 ////// APPLICATION CODE //////

Configuration

Version: 5.0.1+1

Platform:

  • [ ] : iphone: iOS
  • [ x] :robot: Android API 29
android needs more info

Most helpful comment

I have struggled a lot with this issue and finally come to a solution which works fine for me. I have noticed that if you call .status on a permission, the result obtained is not proper in cases when permission is permanently denied. It returns PermissionStatus.denied even when I have permanently denied the permission. So the fix is quite simple. Instead of calling .status on a permission, call .request method as it returns Permission Status. This status returned is proper and works fine.

  Future<PermissionStatus?> askPermission() async {
    Permission _permission = Permission.storage;
    PermissionStatus _status = await _permission.request();
    if (_status.isPermanentlyDenied) {
      print('denied');
      await openAppSettings();
    }
    return _status;
  }

This function works fine for me.

All 3 comments

Hi,
I think the reason why this behaviour is occuring is because you make a request directly after you open the app setings. The plugin does actually open settings app, or at least it completes the intent. Thats why await openAppSettings() returns true.
The flutter app re-opens when await galleryWritePermission.request(); runs.

Anyway, I think a workaround would be something like this:

    var galleryWritePermission = Permission.storage;
    var permissionStatus = await galleryWritePermission.status;

    if (permissionStatus.isPermanentlyDenied) {
      await openAppSettings();
    } else if (!permissionStatus.isGranted) {
      permissionStatus = await galleryWritePermission.request();
    }

    if (!permissionStatus.isGranted) return;

Thus ensuring no request gets executed after the intent has ran.
This also ensures it does not request permissions if it has been pernamently denied. :D

@Sempakonka Thanks, I got it working with the following.

var galleryWritePermission = Platform.isAndroid ? Permission.storage : Permission.photos;
  var permissionStatus = await galleryWritePermission.status;
  // Gallery write permissions are required so if the user has opted to
  // never see the permissions dialog, we have to send them to the
  // system's settings to manually permit it.
  if (permissionStatus.isPermanentlyDenied) {
    await openAppSettings();
  }
  else {
    permissionStatus = await galleryWritePermission.request();
  }
  if (!permissionStatus.isGranted) return;

Think the key insight here was

The flutter app re-opens when await galleryWritePermission.request(); runs.

I was most likely mistaken. From the permission-handler documnentation, it was my understanding was that if if a permission was permanently denied, then await *.request() would essentially be a no-op just as is the case when the permission is granted. Thanks for the help. I'll close the ticket now.

I have struggled a lot with this issue and finally come to a solution which works fine for me. I have noticed that if you call .status on a permission, the result obtained is not proper in cases when permission is permanently denied. It returns PermissionStatus.denied even when I have permanently denied the permission. So the fix is quite simple. Instead of calling .status on a permission, call .request method as it returns Permission Status. This status returned is proper and works fine.

  Future<PermissionStatus?> askPermission() async {
    Permission _permission = Permission.storage;
    PermissionStatus _status = await _permission.request();
    if (_status.isPermanentlyDenied) {
      print('denied');
      await openAppSettings();
    }
    return _status;
  }

This function works fine for me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

klaszlo8207 picture klaszlo8207  路  5Comments

jaleelmeemo picture jaleelmeemo  路  5Comments

petrnymsa picture petrnymsa  路  3Comments

yethael picture yethael  路  3Comments

pedromassango picture pedromassango  路  4Comments