Flutter how to get latitude, longitude using geolocator package?
Already gave permissions both android and ios, downloaded package using pubspec.yaml. I don't understand why can't print longitude and latitude to console? tried write print(position), print(position.longitude()), print(position.latitue()).
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
class LoadingScreen extends StatefulWidget {
#override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
void getLocation() async {
print('Printing text before getCurrentLocation()');
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.low);
print(position);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
color: Colors.red,
onPressed: () {
getLocation();
},
child: Text('Get Location'),
),
),
);
}
} ```
It should be position.latitude or position.longitude. You've used position.longitude() & position.latitude(), which is incorrect.
Also, you need to add async-await for onPressed callback. I'm assuming that you've added permissions in manifest & granted the necessary permissions as well.
Method
void getLocation() async {
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.low);
print(position.latitude);
print(position.longitude);
}
Widget
RaisedButton(
color: Colors.red,
onPressed: () async {
await getLocation();
},
child: Text('Get Location'),
),
Related
The print works perfectly well when it the getLocation function is called inside the onPressed of elevated button.
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
void main(List<String> args) {
runApp(const LoadingScreen());
}
class LoadingScreen extends StatefulWidget {
const LoadingScreen({super.key});
#override
State<LoadingScreen> createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
void getLocation() async {
LocationPermission permission;
permission = await Geolocator.checkPermission();
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
//nothing
}
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low);
print(position);
}
#override
void initState() {
super.initState();
getLocation();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: ElevatedButton(
onPressed: (() {
getLocation();
}),
child: const Text(''),
),
),
],
),
),
);
}
}
But when I try to call the same getLocation function inside initstate, the print function 'prints' nothing inside the console.
P.S. I am using VSCode and emulator is Genymotion.
This question already has answers here:
Do not use BuildContexts across async gaps
(10 answers)
Closed 6 months ago.
I am trying to get the weather of a location as a result of api call to the OpenWeatherApi. The async function getLocationAndWeatherData() is used to get the data. Now after getting the data, I need to send this data to a new screen. So I've used the arguments parameter. Now, when I use the Navigator.pushNamed() after getting the weather data, I'm getting the warning as mentioned in the question. So what's the workaround?
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import '../services/location.dart';
import '../services/networking.dart';
class LoadingScreen extends StatefulWidget {
#override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
#override
void initState() {
super.initState();
}
bool pressed = false;
Widget loadingAndNext() {
setState(() {
pressed = false;
});
return Center(
child: SpinKitDoubleBounce(
color: Colors.white,
size: 50.0,
),
);
}
Widget mainScreen() {
return Center(
child: TextButton(
onPressed: () {
setState(() {
pressed = true;
getLocationAndWeatherData();
});
},
child: Container(
padding: EdgeInsets.all(18.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white,
),
child: Text("Get Location"),
),
),
);
}
Future<dynamic> getLocationAndWeatherData() async {
Location location = Location();
await location.getCurrentLocation();
double lat = location.getLatitude();
double lon = location.getLongitude();
NetworkHelper networkHelper = NetworkHelper(lat: lat, lon: lon);
var x = await networkHelper.getData();
Navigator.pushNamed(context, "/location", arguments: {'weatherData': x});
pressed = false;
}
#override
Widget build(BuildContext context) {
return Scaffold(body: !pressed ? mainScreen() : loadingAndNext());
}
}
After awaiting for the result in getLocationAndWeatherData(),when I use the Navigator.pushNamed(),I get a warning that I shouldn't use BuildContexts here. If I use this method in setState, I need it to be asynchronous. Can I use async and await in setState? If not, how do I get rid of this warning?
try
if (!mounted) return ;
right before Navigation
I want to know is there any way to get user's latitude and longitude with only ACCESS_COARSE_LOCATION permission and not ACCESS_FINE_LOCATION?
I tried getting these two parameters with geolocator and location without the ACCESS_FINE_LOCATION permission, but it didn't work.
Here you can see my code where I tried to get lat and lon with geolocator. When I add the ACCESS_FINE_LOCATION to my Manifest, It works perfectly, but when I remove it, it doesn't work.
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
class geoLocator extends StatefulWidget {
#override
_geoLocatorState createState() => _geoLocatorState();
}
class _geoLocatorState extends State<geoo> {
var lat;
var lon;
Future _getCurrentLocation() async {
Position position;
try {
position =
await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.low);
} catch (e) {
print(e);
}
if (position != null) {
setState(() {
lat = position.latitude;
lon = position.longitude;
});
}
}
#override
void initState() {
super.initState();
_getCurrentLocation();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
mainAxisAlignment: MainAxisAlignment.center,
Text(lat.toString()),
Text(lon.toString()),
SizedBox(height: 20,),
RaisedButton(onPressed: _getCurrentLocation, child: Text("Get Location"),),
],
),
),
);
}
}
Here is my code in a loading_screen.dart file. I've clearly mentioned to print my position and even called the method in onpressed. Still no response from it.
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
class LoadingScreen extends StatefulWidget {
#override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
void getLocation() async{
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.low);
print(position);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
getLocation();
},
child: Text('Get Location'),
),
),
);
}
}
There are few steps missing from your implementation.
First you need to check for permission, if permission is allowed, get location else ask for permission.
You also need to add permission in you manifest for android and in info.plist for ios
sample code :-
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Test(),
);
}
}
class Test extends StatefulWidget{
#override
_Test createState() => _Test();
}
class _Test extends State<Test>{
void getLocation() async{
LocationPermission permission = await Geolocator.checkPermission();
if(permission == LocationPermission.always || permission == LocationPermission.whileInUse) {
printLocation();
}else{
requestPermission();
}
}
requestPermission() async{
LocationPermission permission = await Geolocator.requestPermission();
if(permission == LocationPermission.always || permission == LocationPermission.whileInUse) {
printLocation();
}else{
requestPermission();
}
}
printLocation() async{
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.low, timeLimit: Duration(seconds: 10));
print(position);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
getLocation();
},
child: Text('Get Location'),
),
),
);
}
}
I'm using the geolocator plugin to access the user's location but it seems like it does not work, cause when I run my code I get the error on message.
I have done all the geolocation configuration, but I have the problem.
Adding the Geolocator plugin(pubspec.yaml)
dependencies:
flutter:
sdk: flutter
geolocator: ^5.1.3
For android, head on over to your AndroidManifest.xml and add either of these permissions:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Source code for getting address
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:geolocator/geolocator.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager;
Position _currentPosition;
String _currentAddress;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Location"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (_currentPosition != null) Text(_currentAddress),
FlatButton(
child: Text("Get location"),
onPressed: () {
_getCurrentLocation();
},
),
],
),
),
);
}
_getCurrentLocation() {
geolocator
.getCurrentPosition(desiredAccuracy: LocationAccuracy.best)
.then((Position position) {
setState(() {
_currentPosition = position;
});
_getAddressFromLatLng();
}).catchError((e) {
print(e);
});
}
_getAddressFromLatLng() async {
try {
List<Placemark> p = await geolocator.placemarkFromCoordinates(
_currentPosition.latitude, _currentPosition.longitude);
Placemark place = p[0];
setState(() {
_currentAddress =
"${place.locality}, ${place.postalCode}, ${place.country}";
});
} catch (e) {
print(e);
}
}
}
The problem I get when I run my code is here.
Try flutter clean on terminal and then run the app again, You can also use location plugin instead of Geolocator, to get the user's location