Flutter: How do I listen to permissions real time
6,291
Solution 1
I'm in the same boat and have found that this works
You need to extend your class with WidgetsBindingObserver
class _AppState extends State<App> with WidgetsBindingObserver {
PermissionStatus _status;
...
...
then add these methods to your class
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
// check permissions when app is resumed
// this is when permissions are changed in app settings outside of app
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
PermissionHandler()
.checkPermissionStatus(PermissionGroup.locationWhenInUse)
.then(_updateStatus);
}
}
My full code is below, but I've not included the build widget to keep it brief
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void main() => runApp(App());
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> with WidgetsBindingObserver {
PermissionStatus _status;
// check permissions
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
PermissionHandler() // Check location permission has been granted
.checkPermissionStatus(PermissionGroup
.locationWhenInUse) //check permission returns a Future
.then(_updateStatus); // handling in callback to prevent blocking UI
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
// check permissions when app is resumed
// this is when permissions are changed in app settings outside of app
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
PermissionHandler()
.checkPermissionStatus(PermissionGroup.locationWhenInUse)
.then(_updateStatus);
}
}
override
Widget build(BuildContext context) {
return MaterialApp(
...
...
}
void _updateStatus(PermissionStatus status) {
if (status != _status) {
// check status has changed
setState(() {
_status = status; // update
});
} else {
if (status != PermissionStatus.granted) {
PermissionHandler().requestPermissions(
[PermissionGroup.locationWhenInUse]).then(_onStatusRequested);
}
}
}
}
void _askPermission() {
PermissionHandler().requestPermissions(
[PermissionGroup.locationWhenInUse]).then(_onStatusRequested);
}
void _onStatusRequested(Map<PermissionGroup, PermissionStatus> statuses) {
final status = statuses[PermissionGroup.locationWhenInUse];
if (status != PermissionStatus.granted) {
// On iOS if "deny" is pressed, open App Settings
PermissionHandler().openAppSettings();
} else {
_updateStatus(status);
}
}
I hope this helps
Solution 2
Null safe code:
permission_handler: ^8.0.0+2
The idea is to check for the permission in the app's lifecycle callback when the state is resumed. Here's the minimal code to get you going.
class _FooPageState extends State<FooPage> with WidgetsBindingObserver {
final Permission _permission = Permission.location;
bool _checkingPermission = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.resumed && !_checkingPermission) {
_checkingPermission = true;
_checkPermission(_permission).then((_) => _checkingPermission = false);
}
}
Future<void> _checkPermission(Permission permission) async {
final status = await permission.request();
if (status == PermissionStatus.granted) {
print('Permission granted');
} else if (status == PermissionStatus.denied) {
print('Permission denied. Show a dialog and again ask for the permission');
} else if (status == PermissionStatus.permanentlyDenied) {
print('Take the user to the settings page.');
}
}
@override
Widget build(BuildContext context) => Scaffold();
}
Author by
iprateekk
Updated on December 10, 2022Comments
-
iprateekk over 1 year
I am working on an app in which I want to continuously listen to location and battery permissions.
Sample scenario:
- The user opens the app
- Grants permission access
- Goes to settings and revokes the permissions
- Opens the app again
- The app displays a snackbar that informs the user that permission has been revoked.
I am a beginner and I am using the flutter-permissions-handler and the piece of code below shows my usage.
_listenForLocationPermission() { Future<PermissionStatus> status = PermissionHandler() .checkPermissionStatus(PermissionGroup.locationWhenInUse); status.then((PermissionStatus status) { setState(() { _permissionStatus = status; if (_permissionStatus != PermissionStatus.granted) { _renderOfflineSnackbar('Offline'); } }); }); }
Any advice on the above is appreciated.
-
iprateekk over 4 yearsMany thanks for your answer. I will try this and report back.
-
Abiud Orina almost 4 yearsDo you know how many days of headaches you have saved me??? Bless you!
-
Haidar over 2 yearsis there a way to check for the permanently denied without requesting the permission?
-
CopsOnRoad over 2 years@HaidarMehsen No, that's not possible.