I am using the flutter geolocator package to get a device's current location. but, it is not returning the location and sends null values instead of longitude and latitude.
I have linked all the codes related to location access for Android and iOS.
Here is my code
loading_screen.dart
import 'package:flutter/material.dart';
import 'package:clima/services/location.dart';
class LoadingScreen extends StatefulWidget {
@override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
@override
void initState() {
super.initState();
print('init state called');
getLocation();
}
double? lat;
double? long;
void getLocation() async {
Location location = Location();
await location.getCurrentLocation();
print(location.longitude);
print(location.latitude);
lat = location.latitude;
long = location.longitude;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('$lat & $long'),
),
);
}
}
location.dart
import 'package:geolocator/geolocator.dart';
class Location {
double? longitude;
double? latitude;
Future<void> getCurrentLocation() async {
try {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.lowest);
longitude = position.longitude;
latitude = position.latitude;
} catch (e) {
print(e);
}
}
}
Here is the console log
Running Gradle task 'assembleDebug'...
√ Built build\app\outputs\flutter-apk\app-debug.apk.
D/FlutterGeolocator( 9601): Attaching Geolocator to activity
D/FlutterGeolocator( 9601): Creating service.
D/FlutterGeolocator( 9601): Binding to location service.
D/FlutterGeolocator( 9601): Geolocator foreground service connected
D/FlutterGeolocator( 9601): Initializing Geolocator services
Debug service listening on ws://127.0.0.1:52220/Dm4z5g8IYT4=/ws
Syncing files to device SM A528B...
I/flutter ( 9601): init state called
I/BufferQueueProducer( 9601): [SurfaceView - com.kanuthakor.clima/com.kanuthakor.clima.MainActivity@e98a93d@0#1(BLAST Consumer)1](id:258100000001,api:1,p:9601,c:9601) queueBuffer: queued for the first time.
D/ViewRootImpl@797d88a[MainActivity]( 9601): Creating frameDrawingCallback nextDrawUseBlastSync=false reportNextDraw=true hasBlurUpdates=false
D/ViewRootImpl@797d88a[MainActivity]( 9601): Creating frameCompleteCallback
I/SurfaceView@e98a93d( 9601): uSP: rtp = Rect(0, 0 - 1080, 2265) rtsw = 1080 rtsh = 2265
I/SurfaceView@e98a93d( 9601): onSSPAndSRT: pl = 0 pt = 0 sx = 1.0 sy = 1.0
I/SurfaceView@e98a93d( 9601): aOrMT: uB = true t = android.view.SurfaceControl$Transaction@10aa451 fN = 1 android.view.SurfaceView.access$500:124 android.view.SurfaceView$SurfaceViewPositionUpdateListener.positionChanged:1728 android.graphics.RenderNode$CompositePositionUpdateListener.positionChanged:319
I/SurfaceView@e98a93d( 9601): aOrMT: vR.mWNT, vR = ViewRootImpl@797d88a[MainActivity]
I/ViewRootImpl@797d88a[MainActivity]( 9601): mWNT: t = android.view.SurfaceControl$Transaction@10aa451 fN = 1 android.view.SurfaceView.applyOrMergeTransaction:1628 android.view.SurfaceView.access$500:124 android.view.SurfaceView$SurfaceViewPositionUpdateListener.positionChanged:1728
I/ViewRootImpl@797d88a[MainActivity]( 9601): mWNT: merge t to BBQ
D/ViewRootImpl@797d88a[MainActivity]( 9601): Received frameDrawingCallback frameNum=1. Creating transactionCompleteCallback=false
I/BufferQueueProducer( 9601): [ViewRootImpl@797d88a[MainActivity]#0(BLAST Consumer)0](id:258100000000,api:1,p:9601,c:9601) queueBuffer: queued for the first time.
D/OpenGLRenderer( 9601): GPIS:: SetUp Pid : 9601 Tid : 9632
D/ViewRootImpl@797d88a[MainActivity]( 9601): Received frameCompleteCallback lastAcquiredFrameNum=1 lastAttemptedDrawFrameNum=1
I/ViewRootImpl@797d88a[MainActivity]( 9601): [DP] pdf(0) 1 android.view.ViewRootImpl.lambda$addFrameCompleteCallbackIfNeeded$3$ViewRootImpl:4987 android.view.ViewRootImpl$$ExternalSyntheticLambda16.run:6 android.os.Handler.handleCallback:938
I/ViewRootImpl@797d88a[MainActivity]( 9601): [DP] rdf()
D/ViewRootImpl@797d88a[MainActivity]( 9601): reportDrawFinished (fn: -1)
I/ViewRootImpl@797d88a[MainActivity]( 9601): MSG_WINDOW_FOCUS_CHANGED 1 1
D/InputMethodManager( 9601): startInputInner - Id : 0
I/InputMethodManager( 9601): startInputInner - mService.startInputOrWindowGainedFocus
D/InputMethodManager( 9601): startInputInner - Id : 0
any help will be highly appreciated, thank you.
CodePudding user response:
Did you given these permissions?
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
You need to check run time permission and I didn't use your Location class.
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
//import 'package:clima/services/location.dart';
class LoadingScreen extends StatefulWidget {
@override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
@override
void initState() {
super.initState();
print('init state called');
getLocation();
}
double? lat;
double? long;
Future<Position> getLocation() async {
Location location = Location();
bool serviceEnabled;
LocationPermission permission;
print('inside getLoction1');
// 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.
print('Location services are disabled.');
}
print('inside getLoction2');
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.
print('Location permissions are denied');
}
print('inside getLoction3');
}
print('inside getLoction4');
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
print(
'Location permissions are permanently denied, we cannot request permissions.');
}
print('inside getLoction5');
final position = await Geolocator.getCurrentPosition();
print(position.latitude);
print(location.longitude);
print(location.latitude);
print('inside getLoctio6');
lat = location.latitude;
long = location.longitude;
return position;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<Position>(
future: getLocation(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.connectionState == ConnectionState.done) {
print(snapshot.data!.latitude);
return Center(
child: Text(
'${snapshot.data!.latitude}${snapshot.data!.longitude}'),
);
} else {
return SizedBox.shrink();
}
}),
);
}
}
CodePudding user response:
The problem is most likely the use of LocationAccuracy.lowest
. On Android this translates to the PASSIVE_INTERVAL setting. This means that the location request will not trigger the location services to fetch a location but instead only return location triggered by other clients actively requesting a location update.
You'd most likely want to update the accuracy to LocationAccuracy.low
or higher if you want to actively trigger a location update and not rely on other applications to acquire a location for you.
Here is a complete overview of all accuracy options and their Android counterparts:
Geolocator | Android |
---|---|
LocationAccuracy.lowest | PRIORITY_PASSIVE |
LocationAccuracy.low | PRIORITY_LOW_POWER |
LocationAccuracy.medium | PRIORITY_BALANCED_POWER_ACCURACY |
LocationAccuracy.high | PRIORITY_HIGH_ACCURACY |
LocationAccuracy.best | PRIORITY_HIGH_ACCURACY |
LocationAccuracy.bestForNavigation | PRIORITY_HIGH_ACCURACY |