Comments (12)
Also having this issue. When the user selects LocationPermissionLevel.locationWhenInUse on android, the permission status is PermissionStatus.denied. Cant reproduce the same on iOS
We are using location_permissions 2.0.4+1 on an android emulator running android 10
from flutter-permission-plugins.
@mvanbeusekom I am still seeing this issue after changing the compileSdkVersion
and the targetSdkVersion
to API level 29
. I have pinpointed the issue to the following:
If the application contains the <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
permission then the user is presented with a modal that has three options regardless of the enum value
passed to requestPermissions(...)
:
- Allow location always
- Allow location while the app is in use
- Disallow location
If the user selects the Allow while in use
option then subsequent requests to checkPermissionStatus(level: LocationPermissionLevel.whileInUse)
will return PermissionsStatus.denied
Here is a gif of the example application above with what I am seeing when I add the <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
and then request location permissions using requestPermissions(level: LocationPermissionLevel.locationWhenInUse)
Hope this helps, there is for sure some nuance in here that is hard to pick up on.
from flutter-permission-plugins.
Finally found the issue, the problem is related to the targetSdkVersion
that is referenced. The example
App that is part of the location_permissions
plugin targets version 29.
However if you create a new application with flutter create
by default the app references version 28. You can easily fix this by updating the compileSdkVersion
and targetSdkVersion
parameters in your android/app/build.gradle
file and set them to 29
.
I will have a look and see if I can create some kind of fix to fall back on the old permission handling when the configured SDK is set to 28. So if you want it fixed now please update to SDK version 29.
from flutter-permission-plugins.
Hi @DenisBogatirov, I have tried to reproduce this issue but I am failing. Could you provide some extra information maybe? Things that would help would be:
- Which version of the plugin are you using?
- Which Android version are you using and are you running on emulator or real device?
Here is the code I used to try and reproduce the error (I am on Android emulator with API29, using version 2.0.4+1 of the plugin) :
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.baseflow.location_permissions_example">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="location_permissions_example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
main.dart:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:location_permissions/location_permissions.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
LocationPermissions().openAppSettings().then((bool hasOpened) =>
debugPrint('App Settings opened: ' + hasOpened.toString()));
},
)
],
),
body: Center(
child: ListView(
children: _createWidgetList(),
),
),
),
);
}
List<Widget> _createWidgetList() {
List<Widget> widgets = [];
if (Platform.isAndroid) {
widgets.add(_PermissionWidget(LocationPermissionLevel.locationWhenInUse));
widgets.add(_StreamingStatusWidget());
} else if (Platform.isIOS) {
widgets.add(_PermissionWidget(LocationPermissionLevel.locationWhenInUse));
widgets.add(_PermissionWidget(LocationPermissionLevel.locationAlways));
}
return widgets;
}
}
class _StreamingStatusWidget extends StatelessWidget {
final Stream<ServiceStatus> statusStream =
LocationPermissions().serviceStatus;
@override
Widget build(BuildContext context) => ListTile(
title: const Text('ServiceStatus'),
subtitle: StreamBuilder<ServiceStatus>(
stream: statusStream,
initialData: ServiceStatus.unknown,
builder: (_, AsyncSnapshot<ServiceStatus> snapshot) =>
Text('${snapshot.data}'),
),
);
}
class _PermissionWidget extends StatefulWidget {
const _PermissionWidget(this._permissionLevel);
final LocationPermissionLevel _permissionLevel;
@override
_PermissionState createState() => _PermissionState(_permissionLevel);
}
class _PermissionState extends State<_PermissionWidget> {
_PermissionState(this._permissionLevel);
final LocationPermissionLevel _permissionLevel;
PermissionStatus _permissionStatus = PermissionStatus.unknown;
@override
void initState() {
super.initState();
//_listenForPermissionStatus();
}
void _listenForPermissionStatus() {
final Future<PermissionStatus> statusFuture =
LocationPermissions().checkPermissionStatus();
statusFuture.then((PermissionStatus status) {
setState(() {
_permissionStatus = status;
});
});
}
Color getPermissionColor() {
switch (_permissionStatus) {
case PermissionStatus.denied:
return Colors.red;
case PermissionStatus.granted:
return Colors.green;
default:
return Colors.grey;
}
}
@override
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0),
child: GestureDetector(
onTap: () {
requestPermission(_permissionLevel);
},
child: Row(
children: <Widget>[
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(_permissionLevel.toString()),
Text(
_permissionStatus.toString(),
style: TextStyle(color: getPermissionColor()),
),
]),
),
IconButton(
icon: const Icon(Icons.check),
onPressed: () {
checkPermission(context, _permissionLevel);
}),
IconButton(
icon: const Icon(Icons.info),
onPressed: () {
checkServiceStatus(context, _permissionLevel);
}),
],
),
),
),
);
}
void checkServiceStatus(
BuildContext context, LocationPermissionLevel permissionLevel) {
LocationPermissions()
.checkServiceStatus()
.then((ServiceStatus serviceStatus) {
final SnackBar snackBar =
SnackBar(content: Text(serviceStatus.toString()));
Scaffold.of(context).showSnackBar(snackBar);
});
}
Future<void> checkPermission(
BuildContext context,
LocationPermissionLevel permissionLevel,
) async {
final PermissionStatus permissionResult =
await LocationPermissions().checkPermissionStatus(
level: permissionLevel,
);
final snackBar = SnackBar(
content: Text("Permission status: $permissionResult"),
);
Scaffold.of(context).showSnackBar(snackBar);
setState(() {
_permissionStatus = permissionResult;
});
}
Future<void> requestPermission(
LocationPermissionLevel permissionLevel) async {
final PermissionStatus permissionRequestResult = await LocationPermissions()
.requestPermissions(permissionLevel: permissionLevel);
setState(() {
_permissionStatus = permissionRequestResult;
});
}
}
from flutter-permission-plugins.
Can confirm the bug, the following code is showing the same issue:
PermissionStatus statusAsk = await LocationPermissions().requestPermissions(
permissionLevel: LocationPermissionLevel.locationWhenInUse); // granted
PermissionStatus statusCheck = await LocationPermissions().checkPermissionStatus(
level: LocationPermissionLevel.locationWhenInUse); // denied
Tested in Android 10, both using a device (Samsung S10), and emulator using Android 10 as well. Importing version 2.0.4+1.
Also, using permission_handler
instead correctly returns the expected value.
from flutter-permission-plugins.
Having the same issue. Any solution?
from flutter-permission-plugins.
Same issue here, Android 10 with location enabled while app is in use.
from flutter-permission-plugins.
Same issue exactly as @fabiomgoncalves describes it. requestPermissions(permissionLevel: LocationPermissionLevel.locationWhenInUse)
returns granted but a followup checkPermissionStatus(level: LocationPermissionLevel.locationWhenInUse)
returns denied if you click to only allow "when in-use". It only works if you allow permission "all the time". Thanks!
from flutter-permission-plugins.
Thanks for all the feedback, I struggled a bit reproducing the issue but I managed to reproduce it now as well (not sure why). I will now look into the bug and try to provide a fix a.s.a.p.
from flutter-permission-plugins.
I have had a look at the code and it seems that the implementation of the ContextCompat.checkSelfPermission()
method has been changed in API version 29. From my tests I get the following:
- When targeting SDK 28 and running on a device running 28 (or lower) the code works as expected;
- When targeting SDK 28 and running on a device running 29 the bug described above occurs;
- When targeting SDK 29 and running on a device running 29 (or lower) the code works as expected.
So the only solution I can think of is to upgrade your android/app/build.gradle
file and target SDK version 29.
from flutter-permission-plugins.
I can confirm that updating my compileSdkVersion
and targetSdkVersion
to 29 fixes the issue on Android 10, but it still behaves properly on older android versions (just asking for overall permission). Thank you very much for the fix!
from flutter-permission-plugins.
Can also confirm what @brianb-sf is experiencing, with the same Manifest permissions even though targetSdkVersion
is set to 29
. checkPermissionStatus
is returning denied when Allow location while the app is in use
is selected.
from flutter-permission-plugins.
Related Issues (20)
- Multiple bugs when we deny location permission and then ask for it again HOT 1
- iOS - Location permission dialog is not appearing and always giving denied response. HOT 9
- Is there any plans to support Web version? HOT 1
- Location permission level has no effect on checking or requesting permissions. HOT 3
- AndroidManifest need ACCESS_FINE_LOCATION permission? HOT 2
- Request ServiceStatus
- On iOS 13, location always is incorrectly returned as granted when you only have when in use HOT 2
- Method requestPermissions returns inconsistent results with "Allow Once" on iOS
- Android 11 support problem
- Android permission allowWhenAppInUse triggering inactive and resumed appLifeStateEvent
- [iOS] Requesting location always permissions does not return status when requesting more than once or selecting while using HOT 4
- Issue with the checkPermissionStatus on Android when the user selects "Allow only while using the app" HOT 2
- iOS permission key search is incomplete HOT 1
- [android] "Can request only one set of permissions at a time." HOT 5
- Null Safety Support HOT 1
- Will these packages eventually replace the permission_handler package? HOT 1
- Open turn on location service
- Show Rationale Dialog
- On Android version less than 6 (M) checkPermissionStatus returns Denied HOT 4
- LocationPermissionsPlugin.java uses or overrides a deprecated API
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flutter-permission-plugins.