flutter-permission-handler
flutter-permission-handler copied to clipboard
Is it possible to ask "which location level is currently available"?
As I understand this plugin, at least for the location permissions, I have to request the status of each possibility of permission level in order to see which my app has. for example, I have to first have to ask for the status of locationAlways, then ask for the status of LocationWhileInUse, etc, etc. This doesnt seem to be working as some respond with "undetermined".
Is there a way to just ask "which location level is available" and get a response such as "CurrentPermssion.LocationWhileInUse"? Am I missing something?
This plugin used to work fine until the rewrite a couple of months ago. Now I have these undetermined issues.
Any help will be appreciated. thanks.
This is what I am doing right now for Android to get the answer, but I am new at programming so might not be the most efficient way.
AppLocationPermissionLevel result;
final PermissionState location = _status(await Permission.location.status);
final PermissionState always =
_status(await Permission.locationAlways.status);
final PermissionState whileInUse =
_status(await Permission.locationWhenInUse.status);
if (location == PermissionState.undetermined) {
result = AppLocationPermissionLevel.undetermined;
} else if (always == PermissionState.granted) {
result = AppLocationPermissionLevel.always;
} else if ((always == PermissionState.undetermined ||
always == PermissionState.denied) &&
whileInUse == PermissionState.granted) {
result = AppLocationPermissionLevel.whileInUse;
} else if (always == PermissionState.permanentlyDenied &&
whileInUse == PermissionState.granted) {
result = AppLocationPermissionLevel.alwaysIsPermanentlyDenied;
} else if (location == PermissionState.denied) {
result = AppLocationPermissionLevel.denied;
} else if (location == PermissionState.permanentlyDenied) {
result = AppLocationPermissionLevel.permanentlyDenied;
}
iOS seems much simpler, but i dont think its possible to identify the temporary always option (the one that has 2 popups with the second one appearing at a random time...I am referring to this https://hypertrack.com/blog/2020/06/24/impact-of-ios13-ios14-location-permissions-on-background-location-access/ )
Hi @gkrawiec
If you need to know if your app has a certain permission, for examplePermission.locationAlways
, you need to call Permission.locationAlways.request()
first. This will request the permission and should return the status after the user has chosen from the pop-up. Permission.location.status
wil return granted if either Permission.locationAlways
or Permission.locationWhileInUse
has been granted.
Let me know if this answers your question and/or you have any other questions!
But according to this I have to make 3 different requests to find the permission that is available. Why not just ask "which location permission is granted"?
I don't think a funtionality for that is currently availible. Permission.locationAlways
and Permission.locationWhileInUse
are actually two diffrent permissions (Permission.Location
is identical to permission.locationWhileInUse
in Android according to documentation). To make such a funtionality you would for example need extra return values from android to distinguish between permission level.
To anwer your question, you could try something like this:
var locationAlwaysStatus = await Permission.locationAlways.status;
var locationWhileInUseStatus = await Permission.locationWhenInUse.status;
if (locationAlwaysStatus == PermissionStatus.granted) {
// LocationAlways is available
} else if (locationWhileInUseStatus == PermissionStatus.granted) {
// LocationWhileInUse is available, LocationAlways is either denied or not determined
} else {
// No location permission level has been granted
}
Because of the undertermined issue, there are way more options. In my previous comment I put what I was doing to get the result https://github.com/Baseflow/flutter-permission-handler/issues/349#issuecomment-662530239
You should think about adding this "what is the current permission?" feature to the package. It doesnt make much sense to have to ask each one when one is simply interested in a single answer.
thank you.
I don't think a funtionality for that is currently availible.
Permission.locationAlways
andPermission.locationWhileInUse
are actually two diffrent permissions (Permission.Location
is identical topermission.locationWhileInUse
in Android according to documentation). To make such a funtionality you would for example need extra return values from android to distinguish between permission level. To anwer your question, you could try something like this:var locationAlwaysStatus = await Permission.locationAlways.status; var locationWhileInUseStatus = await Permission.locationWhenInUse.status; if (locationAlwaysStatus == PermissionStatus.granted) { // LocationAlways is available } else if (locationWhileInUseStatus == PermissionStatus.granted) { // LocationWhileInUse is available, LocationAlways is either denied or not determined } else { // No location permission level has been granted }
Hi @gkrawiec,, those undetermined
issues will be gone in the newest version of the plugin (undetermined
status is removed since version ^6.0.0 as mentioned in the changelog). To answer your question about if there is a way to ask which level of location is allowed, the answer is yes and no.
As mentioned before by SemPakonka:
Permission.Location
is identical topermission.locationWhileInUse
in Android according to documentation
This means that if you allow the Permission.location
permission, Permission.locationWhileInUse
will also have the status of granted
. This also goes for the other way around of course.
So if you want to know what kind of level 'location level' your app has you can start by requesting the Permission.locationAlways.status
. if this one is granted, you will also get granted
back from the other location
permissions (locationWhileInUse
or location
). If you get a denied
back you can check for one of the other 2 location permissions, see if one of them is granted
(remember, if one of those 2 has the status granted
the other one is granted
as well).
So yes, you can ask the status for the location permissions, but you can not call a method that will return which one is granted and which one is denied. I personally don't see the need to built this in, since a simple check can already determine which permission is granted
and which not, and you know which permission have been asked when requesting the user for a location permission since the descriptions in the dialogs are clear.
If you do want to know which permission is granted
out of the 3 location permission, a simple check like this will work:
void _askPermission() async {
await Permission.locationWhenInUse.request();
if (await Permission.locationAlways.status == PermissionStatus.granted){
print('location Awlays is granted, other 2 permissions are granted for sure if this one is granted');
print(await Permission.locationWhenInUse.status);
print(await Permission.location.status);
} else if (await Permission.locationWhenInUse.status == PermissionStatus.granted ||
await Permission.location.status == PermissionStatus.granted) {
print('locationAlways is not granted, but locationWhenInUse and location are both granted');
print(await Permission.locationAlways.status);
print(await Permission.locationWhenInUse.status);
print(await Permission.location.status);
} else {
print('No location permission is granted');
}
}
Let me know if this answered your question!
Apps need to behave differently depending on whether they can run in the background or "whileInUse". So I need to run this check every single time. This is fine. I did solve it (look at my post earlier in this thread). I do not understand why you cannot include this in the API so the simple check of three permissions is done by the package's API. That would be even simpler.
I am learning programming. So maybe you can explain to me why you believe this is unnecessary. Isnt one of the points of the API for the plugin to abstract commonly used features so that everybody doesnt have to code the same thing over and over again?
thanks.
Hi @gkrawiec, I don't think it's the permission handlers job to tell you which location
level is granted and which not by calling a method that will run that check. Because a simple .status
will already tell you the status The reason why is because it can be done in a simple if/else if statement with an optional else (see example below).
if (await Permission.locationAlways.status == PermissionStatus.granted){
// Behave as it should with Permission.locationAlways permission allowed.
} else if (await Permission.locationWhenInUse.status == PermissionStatus.granted) {
// Behave as it should with Permission.location or Permission.locationWhenInUse is granted.
} else {
// Optional else statement where you can try to; Open App Settings, request permission, show error dialog etc.
}
This is a simple statement which is not an unnecessary amount of lines in your code.
If I were to add a method you could call to see what location
permission is granted with just one call, it should return something like a list
or map
with the current statusses of the three permissions. Causing you to make a function to loop through the list or something to check the statusses.
Or I could return the 'highest' level of permission which is granted
, so you can call a method that will return the 'highest' location permission level that is granted
. But still you have to check which permission it is then in the code. causing you to write the same amount of lines or probably even more lines then the simple if/else if example I gave.
Isnt one of the points of the API for the plugin to abstract commonly used features so that everybody doesnt have to code the same thing over and over again?
This is true of course, but in this case you end up with the same amount of lines that you have to write to check the current permission status, and which one is granted
or not.
So the reason to built in such functionality seems a bit unnecessary to me, but if you have a better idea which uses less lines of code instead of the if/else if statement I would love to hear it of course!