In flutter how i can check if location is enabled? - flutter

I have problem when user entered google map page without location enabled the map wont updated so i want to check if the user have location enabled beforehand so i need function that return true if location enabled and false if not.

use permission handler plugin
ServiceStatus serviceStatus = await PermissionHandler().checkServiceStatus(PermissionGroup.location);
bool enabled = (serviceStatus == ServiceStatus.enabled);
you can also show a rationale for requesting permission (Android only)
bool isShown = await PermissionHandler().shouldShowRequestPermissionRationale(PermissionGroup.location);
or Location Plugin
var location = Location();
bool enabled = await location.serviceEnabled();
and request to enable it by
bool gotEnabled = await location.requestService();

for those who came to this stackoverflow question like myself, there have been changes and updates on PermissionHandler package and the older solutions are now invalid.
you can check if the location service is enabled:
if (await Permission.locationWhenInUse.serviceStatus.isEnabled) {
// Use location.
}

You can install the permission handler plugin and then use it:
final PermissionStatus permission = await PermissionHandler()
.checkPermissionStatus(PermissionGroup.location);

Related

Permissions always returns "Granted" for Permissions.Photos in .net MAUI

I am using below code to access gallery permissions in .net maui but it always returns Granted even on first time launch of the application and I am not able to see the permission popup saying "This app would like to access photos and media on your device"
public static async Task<PermissionStatus> GetMediaPermissionStatus()
{
PermissionStatus mediaResult = PermissionStatus.Disabled;
var tcs = new TaskCompletionSource<PermissionStatus>();
var status = await Permissions.CheckStatusAsync<Permissions.Photos>();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync<Permissions.Photos>();
}
tcs.SetResult(status);
return await tcs.Task;
}
Also when I execute below code getting 2 app permission Popups
1st Popup - "Allow application to take pictures and record video"
2nd Popup - "Allow application to access photos and media on your device?"
public async void TakePhoto()
{
if (MediaPicker.Default.IsCaptureSupported)
{
FileResult photo = await Microsoft.Maui.Media.MediaPicker.Default.CapturePhotoAsync();
if (photo != null)
{
// save the file into local storage
string localFilePath = Path.Combine(FileSystem.CacheDirectory, photo.FileName);
using Stream sourceStream = await photo.OpenReadAsync();
using FileStream localFileStream = File.OpenWrite(localFilePath);
await sourceStream.CopyToAsync(localFileStream);
}
}
}
I don't know if it is a bug or I am doing something wrong.
Any help is appreciated!
You can refer to this doc: Permissions of MAUI. There is a table in it. It uses ✔️ to indicate that the permission is supported and ❌ to indicate the permission isn't supported or isn't required
If a permission is marked as ❌, it will always return Granted when checked or requested.
Granted:
The user granted permission or is automatically granted.
Wish it can help you.

my current position isn't displaying on the console

here's a screenshot of the code
the code was running well before my current position was printing on the console then I terminated the program and ran it again then it just stopped working
Firstly, you need to decare your position variable outside the function block to be able to access it within your build Widgets.
class _LoadingScreenState extends State<LoadingScreen> {
late Position position;
// ...
Next, you need to update the position state using setState;
// ...
setState(() {
position = await Geolocator.getCurrentPosition( /* complete the call here*/;
});
print(position);
// ...
For any more help or explanation feel free to comment below. Bye!
The official documentation is cleared and detailed. You can consult this link geolocator, It's shows the steps to be followed during the implementation of get the current location.
Firstly, checking is location service enabled in the device,
Secondly, checking and requesting permission to access the position of the device.
Finally, get location service when service is enabled and
permissions are granted .
The following code, it's copied from official documentation:
import 'package:geolocator/geolocator.dart';
/// Determine the current position of the device.
///
/// When the location services are not enabled or permissions
/// are denied the `Future` will return an error.
Future<Position> _determinePosition() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
return await Geolocator.getCurrentPosition();
}

Flutter permission_handler : request location permission on iOS

I want to ask user to enable permission only if he denied the permission or the permission is not allowed
This function is working very well on android
Future _getLocationPermission() async {
if (await Permission.location.request().isGranted) {
permissionGranted = true;
} else if (await Permission.location.request().isPermanentlyDenied) {
throw('location.request().isPermanentlyDenied');
} else if (await Permission.location.request().isDenied) {
throw('location.request().isDenied');
permissionGranted = false;
}
}
but on iOS it throw exception permission isPermanentlyDenied
Unhandled Exception: location.request().isPermanentlyDenied
even if the user allowed location permission while using app
I'm using permission_handler package
iOS is stricter, it does not allow you to request for permission if the user has already permanently denied it. In this case your only option is to inform the user about this, and offer the possibility to open application settings and grant permission there. This will likely restart your application if the user grants.
So check the status without requesting:
final status = await Permission.location.status;
If status is permanently denied, display a Flutter dialog (you can't use the system permission grant dialog in this case):
if (status == PermissionStatus.permanentlyDenied) {
// display a dialog, explain the user that he/she can grant
// permission only in the phone's application settings
}
If the user want's to do it, you can route to the application settings:
openAppSettings(); // this is a method of the permission handler package
This method is a future, but in my experience you don't need to await it.
This is just a function that returns bool if the user enables location
or not simple
Future<bool> canGetLocation(Location location) async {
if (!await location.requestService()) return false;
final status = await location.requestPermission();
final granted = PermissionStatus.granted;
final grantedLimited = PermissionStatus.grantedLimited;
bool result = status == granted || status == granted;
return result;
}
if (await canGetLocation(location)) {
// Do something
} else {
final status = await handler.Permission.location.status;
if (status.isPermanentlyDenied || status.isDenied) {
// ask the user to open the app setting
// from permission handler package you have
openAppSettings();
} else {
// show info dialog or something that the user need to enable location services
}
}
Please check this link. You must have to mention permission in POD file also.

Flutter ask for screen lock PIN

using this package: https://pub.dev/packages/local_auth
We can ask for biometrics. But in some apps I see, that system ask for biometrics, but we have option "use system pin" and we can enter screen lock android pin instead of biometrics. Bu using package local_auth we can not ask for screen lock pin. How to do it?
We must check how many auth methods are enrolled (enrolled = can be used on this device AND user configure it)
If device do not have any enrolled biometrics method we shouldn’t allow to show biometrics pop-up. In the other case user can pass auth withoud provide any pin/biometric data:
final List<BiometricType> availableBiometrics =
await auth.getAvailableBiometrics();
final bool didAuthenticate = false;
if (availableBiometrics.isNotEmpty) {
// Here ask for bio:
didAuthenticate = await auth.authenticate();
}
When we use this line: didAuthenticate = await auth.authenticate(); WITHOUT if (availableBiometrics.isNotEmpty) user can pass security without provide any data.

Flutter: Permission_handler: iOS: Camera permission request not working AFTER first successfully denied

I'm sure this is a silly error on my behalf.
Using Permission_handler to request camera permissions on iOS.
On first attempt the dialog shows requesting permission and successfully approves or denies. However, if I deny the request first and try launching the camera again there is no dialog requesting permissions.
static Future<bool> checkCameraPermissions() async {
PermissionStatus status = await Permission.camera.status;
if (status.isUndetermined || status.isDenied) {
print('cam is denied or undetermined'); //Prints
PermissionStatus newStatus = await Permission.camera.request();
print(await Permission.camera.isDenied); //Prints 'true' immediately
if (newStatus.isDenied)
return false;
print('cam is approved!'); //Nope QQ
}
return true;
}
How do I force Permission_handler to request the user again?
According to Apple, the user response is stored and the dialog doesn't open again. You can read more about it over here
What you can do is show a dialog with steps to enable required permissions and open settings page.