This is my first StackOverflow question and I am learning Dart and Flutter as a newbie.
I have been introduced to the geolocator package and I have been using the latest version which is version 8.2.1. I am also working with Android Studio and its Android Emulator.
The challenge has been to gain latitude and longitude values, and these would come from position data acquired by geolocator.
After some tests, the results have been that the location services are enabled, permission for the location data to be noticed is granted, but despite this, the position data is not being retrieved by geolocator.
I spent some time in the emulator's settings and managed to set a location in San Jose, California, which I hoped that geolocator would then find and work with, but doing so made no difference.
The console's response which seems important is "Future Not Completed":
✓ Built build/app/outputs/flutter-apk/app-debug.apk. Installing build/app/outputs/flutter-apk/app.apk... D/FlutterGeolocator( 6027): Attaching Geolocator to activity D/FlutterGeolocator( 6027): Creating service. D/FlutterGeolocator( 6027): Binding to location service. D/FlutterGeolocator( 6027): Geolocator foreground service connected D/FlutterGeolocator( 6027): Initializing Geolocator services Debug service listening on ws://127.0.0.1:64162/f6U62iu6OXc=/ws Syncing files to device sdk gphone64 x86 64... I/flutter ( 6027): Currently, the emulator's Location Services Status = true. D/CompatibilityChangeReporter( 6027): Compat change id reported: 78294732; UID 10149; state: ENABLED I/flutter ( 6027): Current Location Permission Status = LocationPermission.whileInUse. I/flutter ( 6027): TimeoutException after 0:00:05.000000: Future not completed
My Code:
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
void main() {
runApp(ScreenView());
}
class ScreenView extends StatefulWidget {
double? latitude;
double? longitude;
ScreenView({this.latitude, this.longitude});
void locationHereIs() async {
await locationServicesStatus();
await checkLocationPermissions();
try {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low)
.timeout(Duration(seconds: 5));
print(position);
} catch (e) {
print(e);
}
}
Future<void> checkLocationPermissions() async {
LocationPermission permission = await Geolocator.requestPermission();
print('Current Location Permission Status = $permission.');
}
void checkLocationSettings() async {
await Geolocator.openLocationSettings();
}
Future<void> locationServicesStatus() async {
bool isLocationServiceEnabled = await Geolocator.isLocationServiceEnabled();
print(
'Currently, the emulator\'s Location Services Status = $isLocationServiceEnabled.');
}
@override
State<ScreenView> createState() => _ScreenViewState();
}
class _ScreenViewState extends State<ScreenView> {
@override
void initState() {
ScreenView().locationHereIs();
super.initState();
}
@override
Widget build(BuildContext context) {
return Container();
}
}
If you can help me understand what's going wrong so that I can fix things and get results, that'd be perfect. In your response, please assume that I have used complileSdkVersion 32, miniSdkVersion 23 and targetSdkVersion 32.
With thanks : )
CodePudding user response:
Use this code for fix it :
Future<Position> _getGeoLocationPosition() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
await Geolocator.openLocationSettings();
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
print('Location permissions are denied');
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
print('Location permissions are permanently denied, we cannot request permissions.');
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(desiredAccuracy: LocationAccuracy.high);
}
Result :
Position position = await _getGeoLocationPosition();
CodePudding user response:
I have found a solution and a reasonable explanation for why current-position data will not be retrieved by geolocator when operating with
- android's emulator
:
The reason is because the android emulator is not a real device and lacks the level of functionality found within real android devices; android emulator cannot accept geolocator's current-position function.
Android emulator does accept geolocator's lastKnownLocation function though, and a location set within the emulator's location settings will be noticed and confirmed by geolocator via its lastKnownLocation function.
I trust that this finding helps everyone working with geolocator relying on the android emulator : )
Dart code example:
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
void main() {
runApp(ScreenView());
}
class ScreenView extends StatefulWidget {
double? latitude;
double? longitude;
ScreenView({this.latitude, this.longitude});
void lastKnownPosition() async {
await locationServicesStatus();
await checkLocationPermissions();
try {
Position? position = await Geolocator.getLastKnownPosition();
print(position);
} catch (e) {
print(e);
}
}
void locationHereIs() async {
await locationServicesStatus();
await checkLocationPermissions();
try {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low)
.timeout(Duration(seconds: 28));
print(position);
} catch (e) {
print(e);
}
}
Future<void> checkLocationPermissions() async {
LocationPermission permission = await Geolocator.requestPermission();
print('Current Location Permission Status = $permission.');
}
void checkLocationSettings() async {
await Geolocator.openLocationSettings();
}
Future<void> locationServicesStatus() async {
bool isLocationServiceEnabled = await Geolocator.isLocationServiceEnabled();
print(
'Currently, the emulator\'s Location Services Status = $isLocationServiceEnabled.');
}
@override
State<ScreenView> createState() => _ScreenViewState();
}
class _ScreenViewState extends State<ScreenView> {
@override
void initState() {
ScreenView().lastKnownPosition();
super.initState();
}
@override
Widget build(BuildContext context) {
return Container();
}
}
Console output with lastKnownLocation:
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk...
Debug service listening on ws://127.0.0.1:52586/aA04hHZ7dIg=/ws
Syncing files to device sdk gphone64 x86 64...
I/flutter (11353): Currently, the emulator's Location Services Status = true.
D/CompatibilityChangeReporter(11353): Compat change id reported: 78294732; UID 10149; state: ENABLED
I/flutter (11353): Current Location Permission Status = LocationPermission.whileInUse.
I/flutter (11353): Latitude: 37.333333333333336, Longitude: -121.89206891099967
Conclusion: there has been a suspicion that the geolocator package is flawed without explanation. The above shows and explains that geolocator works fine with android emulator and should remain a favourite of android developers.