Baseflow / flutter-permission-handler

Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
https://baseflow.com
MIT License
2.05k stars 858 forks source link

requestPermission does not return result #84

Closed NeroJz closed 4 years ago

NeroJz commented 5 years ago

🔙 Regression

List permissions_group = [PermissionGroup.contacts, PermissionGroup.storage];

Map<PermissionGroup, PermissionStatus> permissions = await PermissionHandler().requestPermissions(permissions_group);

print(permissions)

Hi, I tried to run the code above. Unfortunately, I cannot get the result after granting the permission from the dialog. Any suggestion?

marinat commented 5 years ago

any suggestions?

marinat commented 5 years ago

🔙 Regression

List permissions_group = [PermissionGroup.contacts, PermissionGroup.storage];

Map<PermissionGroup, PermissionStatus> permissions = await PermissionHandler().requestPermissions(permissions_group);

print(permissions)

Hi, I tried to run the code above. Unfortunately, I cannot get the result after granting the permission from the dialog. Any suggestion?

Show code, pls

mvanbeusekom commented 5 years ago

@NeroJz, some more information would be appreciated. The example app with the plugin doesn't show this behaviour.

Things I would be interested in is:

The best way for us to help you would be to share a example app reproducing the problem.

kevincaicedo commented 5 years ago

I have also presented the same problem and this happens when you add some dependency using register.addRequestPermissionsResultListener happens to me with the ImagePicker

gvstrmrgh commented 5 years ago

Experiencing the same issue, tested on huawei p9 Android 7.0

try {
      final permissionNames = await permissionHandler.requestPermissions(permissionsNeeded);
      print("got permissions: $permissionNames");
} catch(e) {
      print("request permission error: $e");
}

the print statement in the try block is never called. if i rerun the function (after having chosen deny or approve on the permission dialogs) I get ERROR_ALREADY_REQUESTING_PERMISSIONS in the catch block

Flutter version 1.2.1 Latest version of the plugin (^3.0.0 specified in pubspec)

ghost commented 5 years ago

Hey @mvanbeusekom I'm having the exact same issue. My app gets stuck on this line: await PermissionHandler() .requestPermissions([PermissionGroup.locationWhenInUse]);

Even though permissions are granted, it doesn't move further than this. If I restart the app, it recognizes that permissions were granted and then progresses further.

This is the result of flutter doctor -v:

[√] Flutter (Channel master, v1.5.9-pre.216, on Microsoft Windows [Version 10.0.17763.475], locale en-US)
    • Flutter version 1.5.9-pre.216 at C:\flutter
    • Framework revision 829bdeb426 (9 hours ago), 2019-05-10 15:53:41 -0700
    • Engine revision 6e3c043141
    • Dart version 2.3.1 (build 2.3.1-dev.0.0 a0290f823c)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at C:\Users\Fawad\AppData\Local\Android\sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
    • All Android licenses accepted.

[√] Android Studio (version 3.4)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 35.0.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

[√] VS Code (version 1.33.1)
    • VS Code at C:\Users\Fawad\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.0.1

[√] Connected device (1 available)
    • SM G950F • ce03171369b23cc90c • android-arm64 • Android 9 (API 28)

Also this line shows up in the debug console: E/location_permissions(20056): Flutter result object is null.

Not sure if this is relevant but figured it might help if it is.

ened commented 5 years ago

Should be fixed in #109 already, please retest.

evelyne24 commented 5 years ago

I have the same issue in version 3.1.0 which apparently is the latest version at the moment of testing. This happens on iOS 12+.

I execute the following code:

Future<bool> checkPermissions() async {
    try {
      PermissionStatus permission = await PermissionHandler().checkPermissionStatus(PermissionGroup.contacts);
      _log.debug('Current contacts permissions: $permission');
      if (permission != PermissionStatus.granted) {
        _log.debug('Asking for contacts permissions: $permission');
        Map<PermissionGroup, PermissionStatus> result =
            await PermissionHandler().requestPermissions([PermissionGroup.contacts]);
        _log.debug('Permission result: ${result[permission]}');
        return result[permission] == PermissionStatus.granted;
      }
      return true;
    } catch (e) {
      // somethings this crashes on iOS with an error inside the library - monitor
      _log.error('Crash when asking permissions', e);
      return false;
    }
  }

Aside from the crash that happens (a separate issue, probably related to this), this is what I get when I Deny the permissions:

14:31:41.044 110 fine Current contacts permissions: PermissionStatus.denied
14:31:41.046 111 fine Asking for contacts permissions: PermissionStatus.denied
14:31:41.048 112 fine Permission result: null

Ideally, there would be a way to show the permission dialog again, to be able to press Allow

boskokg commented 5 years ago

I also had this problem on android but it turns out that imei_plugin plugin invoked it...

https://github.com/kevincaicedo/imei_plugin/issues/9

ghost commented 5 years ago

Facing the same problem now, no progress? await never receive any response from requestPermissions.

dmskys commented 5 years ago

Facing the same problem now, no progress? await never receive any response from requestPermissions.

Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel dev, v1.10.13, on Mac OS X 10.14.6 18G103, locale zh-Hans-CN)

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3) [✓] Xcode - develop for iOS and macOS (Xcode 11.0) [✓] Android Studio (version 3.5) [✓] VS Code (version 1.39.0) [✓] Connected device (1 available)

dmskys commented 5 years ago

I found this reason because imei_plugin prevented the return

pablanka commented 4 years ago

I'm facing this issue. package version: ^4.4.0+hotfix.2 os: android

My code:

final handler = PermissionHandler(); 
handler.requestPermissions(perms).then((value) => print(value));

print(value) is never called

ened commented 4 years ago

Please submit a sample project on GitHub along with testing instructions and info about your environment. You can also clone the current master branch and use the example there to demonstrate.

pablanka commented 4 years ago

If I add file_picker package, after granting permissions I get the following log

E/FilePickerDelegate(25834): Can't find a valid activity to handle the request. Make sure you've a file explorer installed.

and then await requestPermissions() never returns.

So I removed file_picker package from pubspec.yaml, built the app again and everything works ok.

Any idea why could it be?

ened commented 4 years ago

Sounds like FilePicker overrides a listener (activity result or similar). I know @miguelpruivo is working on a new version & suggest we check with them once done.

miguelpruivo commented 4 years ago

@ened @pablanka it’s already deployed. You can update it to file_picker: 1.5.0+2 with Android V2 support.

@pablanka you shouldn’t need any permission handler for the picker. Permissions are handled automatically by the plugin itself.

ened commented 4 years ago

@miguelpruivo The issue may happen when developers use file_picker and permission_handler together in the same project. I haven't checked the code yet but would suspect the "permission result listener" could be overwritten by one of the plugins. @pablanka Perhaps you could check again with the latest versions?

EdwynZN commented 4 years ago

Can confirm the problem persists after updating both file_picker and permission_handler

file_picker: ^1.5.0+2
permission_handler: ^4.4.0+hotfix.2

I have 2 method, read and write file

final PermissionHandler _permissionHandler = PermissionHandler();

Future<String> requestWritePermission() async {
    final Map<PermissionGroup, PermissionStatus> response = await _permissionHandler.requestPermissions([PermissionGroup.storage]);
    switch(response[PermissionGroup.storage]){
      case(PermissionStatus.granted):
        return 'Permssion granted';
      case(PermissionStatus.denied):
      case(PermissionStatus.neverAskAgain):
      case(PermissionStatus.restricted):
      case(PermissionStatus.unknown):
      default:
      return 'Permssion denied';
    }
  }

Future<Map<String,dynamic>> openFileExplorer() async {
    final String _path = await FilePicker.getFilePath(type: FileType.any);
    if(_path == null) return null;
    else if(_path.substring(_path.lastIndexOf('.')) != '.json') return null;
    return await compute(readFile, _path);
  }

If I requestWritePermission() and deny it the next time I use the method it shows the error

E/flutter ( 4903): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(ERROR_ALREADY_REQUESTING_PERMISSIONS, A request for permissions is already running, please wait for it to finish before doing another request (note that you can request multiple permissions at the same time)., null)

but it shows the dialog box asking for permission once more, I can allow it and everything will work fine, but there is that exception when the user can deny it.

Using openFileExplorer() and deny access give me a exception that wasn't before

I/flutter ( 6271): [FilePicker] Platform exception: PlatformException(read_external_storage_denied, User did not allowed reading external storage, null)

I was working with

file_picker: 1.4.0+1
permission_handler: 4.0.0

and the same methods worked just fine

miguelpruivo commented 4 years ago

@EdwynZN that's probably because both plugins ask for the same permission. You don't need to use PermissionHandler before picking files because file_picker will ask for permissions if they aren't given already.

EdwynZN commented 4 years ago

I changed the plugins version to

file_picker: 1.4.0+1 #old version
permission_handler: ^4.4.0+hotfix.2 #latest version

and tried again and the problem is no more

@miguelpruivo I use those methods in different buttons (one to save and one to retrieve a file) so when I use requestWritePermission() I only use permission handler and for openFileExplorer() only file_picker to avoid asking twice with file_picker and permission_handler but when I want to write a file and use requestWritePermission() many times (asking and denying access sometime to see what happens) it gives me the first error, and I'm just using permission handler in that method, no file picker.

changing file picker plugin to 1.4.0+1 and trying again gives me no error of ERROR_ALREADY_REQUESTING_PERMISSIONS. I believe the latest filepicker use the same PlatformMethod or something that fires it twice, even when I'm not using the plugin

miguelpruivo commented 4 years ago

@EdwynZN actually, older versions were more prone to errors than the latest, which optimizes all those steps by implementing the handlers in a delegate — just like the official image_picker plugin does.

I’d like to help you nevertheless, but it’s hard to tell whether this is file_picker or permission_handler’s fault. It could even be neither and just a conflict that could anyhow be worked around.

What is the plugin that throws the error? Can you pick it from the logs?

Thanks!

EdwynZN commented 4 years ago

I think the problem is solved but I still don't know why. Creating a new project with only file_picker and permission_handler solved the problem but the other one still have it

The new project runs just fine https://gist.github.com/EdwynZN/d8d2158a1bef722504acd02f985b4864

If I run the old project which have basically the same buttons and methods (just added a compute to write or read a file after making sure I have the permissions) I get this error

E/flutter (19844): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(ERROR_ALREADY_REQUESTING_PERMISSIONS, A request for permissions is already running, please wait for it to finish before doing another request (note that you can request multiple permissions at the same time)., null)
E/flutter (19844): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7)
E/flutter (19844): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:321:33)
E/flutter (19844): <asynchronous suspension>
E/flutter (19844): #2      MethodChannelPermissionHandler.requestPermissions (package:permission_handler_platform_interface/src/method_channel/method_channel_permission_handler.dart:72:30)
E/flutter (19844): #3      PermissionHandler.requestPermissions (package:permission_handler/permission_handler.dart:32:47)
E/flutter (19844): #4      _BottomBarState._requestWritePermission (package:amiibo_network/screen/settings_screen.dart:537:30)
E/flutter (19844): #5      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
E/flutter (19844): #6      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36)
E/flutter (19844): #7      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter (19844): #8      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11)
E/flutter (19844): #9      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5)
E/flutter (19844): #10     BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:199:7)
E/flutter (19844): #11     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:467:9)
E/flutter (19844): #12     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12)
E/flutter (19844): #13     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:117:9)
E/flutter (19844): #14     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
E/flutter (19844): #15     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:115:18)
E/flutter (19844): #16     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:7)
E/flutter (19844): #17     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
E/flutter (19844): #18     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter (19844): #19     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter (19844): #20     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter (19844): #21     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter (19844): #22     _rootRunUnary (dart:async/zone.dart:1138:13)
E/flutter (19844): #23     _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (19844): #24     _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
E/flutter (19844): #25     _invoke1 (dart:ui/hooks.dart:273:10)
E/flutter (19844): #26     _dispatchPointerDataPacket (dart:ui/hooks.dart:182:5)
E/flutter (19844): 

This is after running final var response = await PermissionHandler().requestPermissions([PermissionGroup.storage]); deny the access and running it again because the await method never returned a value and is still waiting.

Flutter doctor -v

[√] Flutter (Channel stable, v1.12.13+hotfix.8, on Microsoft Windows [Versión 10.0.18363.720], locale es-MX)
    • Flutter version 1.12.13+hotfix.8 at E:\Programs\flutter
    • Framework revision 0b8abb4724 (6 weeks ago), 2020-02-11 11:44:36 -0800
    • Engine revision e1e6ced81d
    • Dart version 2.7.0

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at C:\Users\dartz\AppData\Local\Android\Sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.3
    • ANDROID_HOME = C:\Users\dartz\AppData\Local\Android\Sdk
    • Java binary at: E:\Programs\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
    • All Android licenses accepted.

[√] Android Studio (version 3.6)
    • Android Studio at E:\Programs\Android\Android Studio
    • Flutter plugin version 44.0.2
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[√] Connected device (1 available)
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

• No issues found!
miguelpruivo commented 4 years ago

Ok. So that’s probably some sort of leak from PermissionHandler when the request is canceled @EdwynZN.

EdwynZN commented 4 years ago

perhaps this is a problem with the enforced scope storage changes from Android Q/R so the permission request and file paths outside the scope have some problem?

miguelpruivo commented 4 years ago

@EdwynZN hum I hardly doubt as this happens as well on versions below Android Q (10).

EdwynZN commented 4 years ago

I think I finally found the problem and solution. My older project has this problem and when creating a new one with the same methods and latest plugins it seemed to work fine. So digging around I found that the MainActivity.java/kt was different, the older one was created prior to version 1.12, it uses io.flutter.app.FlutterActivity which is depracated.

Creating a new project or following the instructions of https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects solved all my problems, now I can use file_picker: ^1.5.0+2 and permission_handler: ^4.4.0+hotfix.2.

Basically if your android project MainActivity.java or kt is using io.flutter.app.FlutterActivity or your AndroidManifest.xml is using io.flutter.app.FlutterActivity or have

<meta-data
    android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
     android:value="true" />

you need to update your flutter project to 1.1.2 to work with the new Android wrappers

miguelpruivo commented 4 years ago

Thank you @EdwynZN this is good to know and may help other users facing the same issue.

marchacio commented 4 years ago

I changed the plugins version to

file_picker: 1.4.0+1 #old version
permission_handler: ^4.4.0+hotfix.2 #latest version

and tried again and the problem is no more

@miguelpruivo I use those methods in different buttons (one to save and one to retrieve a file) so when I use requestWritePermission() I only use permission handler and for openFileExplorer() only file_picker to avoid asking twice with file_picker and permission_handler but when I want to write a file and use requestWritePermission() many times (asking and denying access sometime to see what happens) it gives me the first error, and I'm just using permission handler in that method, no file picker.

changing file picker plugin to 1.4.0+1 and trying again gives me no error of ERROR_ALREADY_REQUESTING_PERMISSIONS. I believe the latest filepicker use the same PlatformMethod or something that fires it twice, even when I'm not using the plugin

This solved my error, thank you! I hope this can help someone else

miguelpruivo commented 4 years ago

@marchacio you should check @EdwynZN last answer with an explanation for the actual fix. Downgrading the version is not the right solution.