Fetching Current Location with Permission not working - flutter

I am using
geolocator: '^3.0.1'
permission_handler: '^3.0.0'
Now I want to fetch the current location of the user and show it on the map as the user opens the Map.
So my Code is :
Future<void> requestPermission() async {
PermissionHandler()
.checkPermissionStatus(PermissionGroup.location)
.then((PermissionStatus permissionStatus) async {
print("Checking Permission " + permissionStatus.toString());
if (permissionStatus == PermissionStatus.granted) {
_getCurrentLocation();
} else {
print("Asking Permission " + permissionStatus.toString());
final List<PermissionGroup> permissions = <PermissionGroup>[
PermissionGroup.locationWhenInUse
];
final Map<PermissionGroup, PermissionStatus> permissionRequestResult =
await PermissionHandler().requestPermissions(permissions);
if (PermissionStatus.granted ==
permissionRequestResult[PermissionGroup.locationWhenInUse]) {
print("Permission Granted " + permissionStatus.toString());
_getCurrentLocation();
}
}
});
}
and permissions are defined in the manifest for android and info.list for IOS.
Now the issue is when I run this function and when it calls requestPermission function, it shows the popup asking for the permission and
when I allow the permission app crashes with an error :
java.lang.RuntimeException: Failure delivering result ResultInfo{who=#android:requestPermissions: ... java.lang.IllegalStateException: Reply already submitted
and also the result of permission is Permission.disabled though I allowed the permission in application settings and in permission it shows that location is permission is allowed. but I tried opening app several times it shows Permission.disabled.
and even if I deny the app crashes with the same error.
So what I have concluded is :
If I allow or deny it crashes because it is requesting multiple times and even if I allow the result is Permission.disabled.
Link for the video: https://youtu.be/A1DKkw6u4HI
Can anyone help me solving this issue?
Or please tell me how to take the current location map easily

please tell me how to take the current location map easily
If you just need to fetch current location easily and you just need location permission then :
you can use location plugin with flutter :
In your pubspec.yml : location : ^2.3.0
Then for fetching Current location :
Import location Package
import 'package:location/location.dart' as locationPackage;
Add this to your State
locationPackage.Location _locationService = new locationPackage.Location();
bool _permission = false;
Call this function in initState or whenever you need current Location
fetchCurrentLocation() async {
await _locationService.changeSettings(
accuracy: locationPackage.LocationAccuracy.HIGH, interval: 1000);
locationPackage.LocationData location;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
bool serviceStatus = await _locationService.serviceEnabled();
print("Service status: $serviceStatus");
if (serviceStatus) {
_permission = await _locationService.requestPermission();
print("Permission: $_permission");
if (_permission) {
location = await _locationService.getLocation();
print("Location: ${location.latitude}");
}
} else {
bool serviceStatusResult = await _locationService.requestService();
print("Service status activated after request: $serviceStatusResult");
if (serviceStatusResult) {
fetchCurrentLocation();
}
}
} on PlatformException catch (e) {
print(e);
if (e.code == 'PERMISSION_DENIED') {
//error = e.message;
} else if (e.code == 'SERVICE_STATUS_ERROR') {
//error = e.message;
}
location = null;
}
}

Related

Use getPositionStream to add location indicator Flutter

I have a HERE map with various functionality operating fine
I have a location indicator that currently operates Geolocator.getCurrentPosition(); which works fine, taking the lat,long and heading to place indicator.
I want it to update with users location from device.
I need to use Geolocator.getPositionStream to achieve this but after trying the implementation example online I'm stuck as it has different requirements to Current Position and the code won't work
Here is the LocationIndicator method, set to getRandom
void _addLocationIndicator(GeoCoordinates geoCoordinates, LocationIndicatorIndicatorStyle indicatorStyle) {
LocationIndicator locationIndicator = LocationIndicator();
locationIndicator.locationIndicatorStyle = indicatorStyle;
Location location = Location.withCoordinates(geoCoordinates);
location.time = DateTime.now();
location.bearingInDegrees = _getRandom(0, 360);
locationIndicator.updateLocation(location);
_hereMapController.addLifecycleListener(locationIndicator);
}
This is the given code for Stream
final LocationSettings locationSettings = LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 100,
);
StreamSubscription<Position> positionStream = Geolocator.getPositionStream(locationSettings: locationSettings).listen(
(Position position) {
print(position == null ? 'Unknown' : position.latitude.toString() + ', ' + position.longitude.toString());
});
This is the Current Location example which I have used and it works fine for current location
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();
}
Thanks

How do I handle a future not returning?

I'm using a location plugin to get the current location of the device. However, on certain devices, await getLocation() never returns (there are also no errors in the debug console). How do I handle such an issue?
this is my code for getCurrentLocation()
import 'package:geolocator/geolocator.dart';
import 'location.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> getCurrentLocation() async {
bool serviceEnabled;
LocationPermission permission;
Position position;
await reqLocation(); // requests turn on location
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.deniedForever) {
return Future.error(
'Location permissions are permantly denied, we cannot request permissions.');
}
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission != LocationPermission.whileInUse &&
permission != LocationPermission.always) {
return Future.error(
'Location permissions are denied (actual value: $permission).');
}
}
print('LOGIC');
position = await Geolocator.getCurrentPosition();
if (position == null) {
print('null');
} else {
print('LOCATION');
print(position);
}
return position;
}
Use a timeout for your future to handle this case: Flutter - Future Timeout
Use your future like this:
var result = await getCurrentLocation().timeout(const Duration(seconds: 5, onTimeout: () => null));
Now, your future runs for 5 seconds and if the operation is not complete yet, the future completes with null (because onTimeout returned null. You can use a different value as you like [Refer to the link above]).
Now check result. if null, the operation did not complete within specified time limit else you get your position value in result as usual if it managed to complete within the specified duration.

Flutter Location package requestService() never returns

I have a function like this. Using Location package from flutter it shows the dialog to enable GPS.
Future<bool> _checkServiceStatus() async {
final Location location = Location();
bool serviceStatus = await location.serviceEnabled();
if (!serviceStatus) {
serviceStatus = await location.requestService();
print('status -> $serviceStatus');
}
return serviceStatus;
}
When its calling await location.requestService(), it is showing the dialog to enable GPS but after that it never returns the result.
Even its not executing the print() function.
What am i doing wrong here?
Any help would be very appreciated! Thanks in advance.
I had the same issue. It could be solved by upgrading your Flutter project, follow this link https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects
Try this code to check wather permission enabled, service enabled than it returns true else false. Must configure "location" package related configuration in android and ios projects.
Future<bool> checkServiceStatus() async {
final Location location = Location();
final locationPermission = await location.hasPermission();
if (locationPermission == PermissionStatus.granted) {
final locationServiceEnabled = await location.serviceEnabled();
if (locationServiceEnabled == true) {
return true;
} else {
final requestServiceStatus = await location.requestService();
if (requestServiceStatus == true) {
return true;
} else {
BotToast.showSimpleNotification(
title: "Enable GPS to allow this feature");
return false;
}
}
} else {
BotToast.showSimpleNotification(title: "Required location permission to allow this feature");
return false;
}
}

How to get call back of Google location service dialog button click's in flutter?

I need to fetch current location of device in my Flutter App. I have added plugins are location: ^2.3.5 and geolocator: ^5.0.1 to get current location.
All is working fine but when the GPS of my device is off(disabled) then it shows a dialog that i have shown in Image please check it.I need call back on press ok button so that i can get current location and execute next code lines. I will be thankful to you if you help me.
Here have some code.
getCurrentLocation() async{
try {
await location.getLocation().then((locationData){
if(locationData!=null){
moveHomeWithLatLon(context,false,locationData.latitude.toString(),locationData.longitude.toString());
}else{
dialogInternetCheck(context, alert, "Please check location services on device");
}
});
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'Permission denied';
dialogInternetCheck(context, alert, "Location services "+error);
}
}
}
You should check for the service status result after requesting location service. If it is true that means the user has provided the access. I have provided the example below
bool serviceStatusResult = await location.requestService();
print("Service status activated after request: $serviceStatusResult");
if (serviceStatusResult) {
await _getCurrentLocation();
}
Future<bool> _getCurrentLocation() async {
try {
Location location = Location();
LocationData userLocation = await location.getLocation();
} on PlatformException catch (e) {
Log.info("Location fetch failed : ${e.toString()}");
}
return Future.value(true);
}

alternate method of onRequestPermissionResult() in Flutter

I am requesting runtime permissions in Flutter. How to handle the result of permissions in Flutter. As we know In Android there is onRequestPermissionsResult(). Whats alternate method in Flutter.
use the plugin simple_permissions
It can check, request and get permissions with callbacks
Sample code from the example
requestPermission() async {
final res = await SimplePermissions.requestPermission(permission);
print("permission request result is " + res.toString());
}
checkPermission() async {
bool res = await SimplePermissions.checkPermission(permission);
print("permission is " + res.toString());
}
getPermissionStatus() async {
final res = await SimplePermissions.getPermissionStatus(permission);
print("permission status is " + res.toString());
}