location.getLocation() does not access my location - flutter

I use these packages
google_maps_flutter: ^2.2.3
flutter_polyline_points: ^1.0.0
location: ^4.4.0
The fact is that when I test on the emulator, this command works correctly. She's tracking tracking location
await location.getLocation().then((locationn) {
currentLocation = locationn;
});
When I test on a real device, this also works, but I need to enable geolocation in advance and log in to google maps.
If I do not include geolocation in advance and request the user's location, this function will not work
Future<LocationData> getCurrentLocation() async {
Location location = Location();
try {
await location.getLocation().then((locationn) {
currentLocation = locationn;
});
location.onLocationChanged.listen(
(newLoc) {
currentLocation = newLoc;
},
);
} catch (e) {
print('т $e');
}
notifyListeners();
return currentLocation;}
the program stops here in this line and does not move any further. There are no error messages
await location.getLocation().then((locationn) {
I'm doing the main function in future builder. here you can see that the maps are not displayed because of Marker() which requires my map coordinates
(mapModel.currentLocation!.latitude!, mapModel.currentLocation!.longitude!).
However, the get Current Location() function cannot return the current Location variable because, as I said earlier, for some reason it stops at the line
await location.getLocation().then((locationn)
FutureBuilder<LocationData>(
future: mapModel.getCurrentLocation(),
builder:(context, snapshot){
if (snapshot.connectionState == ConnectionState.done) {
return GoogleMap(
markers: {
Marker(
markerId: const MarkerId("currentLocation"),
position: LatLng(mapModel.currentLocation!.latitude!,
mapModel.currentLocation!.longitude!),
)
},
position: LatLng(mapModel.currentLocation!.latitude!,
mapModel.currentLocation!.longitude!),
the manifest has all the necessary permissions
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Related

my flutter google maps project, after first install I can't see the blue dot of my gps location, but on every other opening of the app it works

In my flutter google maps project, after first install I can't see the blue dot of my gps location(current location) on every other opening of the app it works properly. Please help me to understand the issue and to fix the issue.
I used geoLocation package for get current location.
Also add the location permissions in android manifest file.
Method I used to get the current location
_getCurrentLocation() async {
final GoogleMapController controis = await _controller.future;
await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high)
.then((Position position) async {
setState(() {
_currentPosition = position;
// ignore: avoid_print
print("current position: $_currentPosition");
controis.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(position.latitude, position.longitude), zoom: 5),
),
);
});
await _getAddress();
}).catchError((e) {
print(e);
});
}

Permisson handler - location do not work (Flutter)

I have a problem with Permisson Handler while try to use location.
When i tap and run gps func everything seems fine. Pop up is showing up I can choose options - Allow, Allow while Using etc, however when I choose allow or allow while it do not turn on location. It was working perfectly and just stopped somehow (permission is set to granted).
When I turn it on manually (Location on my device) everything is like it was before. I don't now why this prompt stops turning on location service.
void _onGpsTap() async {
bloc.emitEvent(DisplayProgressIndicator());
try {
permissionStatus = await Permission.location.status;
if (permissionStatus.isUndetermined) {
permissionStatus = await Permission.location.request(); // Here I'm asking for turning location on
}
if (permissionStatus.isDenied) {...
I'm using
geolocator: ^5.3.1
permission_handler: 5.0.0+hotfix.3
Try out below code:-
var status = await Permission.location.request();
if(status.isGranted){
log("Permission Granted");
getAddress();
}
getAddress() async {
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
latitude = position.latitude;
longitude = position.longitude;
if(latitude != null && longitude != null){
apiCall();
}
}
permission_handler: ^8.1.4+2
geolocator: ^7.2.0+1
I found out that is not possible to turn on location service via. flutter and the user have to do it maunally.

Not able to get the Latitude and Longitude while using 'GeoLocator' package

I am trying to use 'GeoLocator' to retrieve Latitude & Longitude. However, not able to get any output?
Also will be helpful if someone can help me organize the 'geoLocator' package as a service in a separate dart file.
As suggested I tried changing the code, but still not able to get the geolocation. Also when I call the '_determinePosition()' getting "Instance of 'Future'
".
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
//
Future<Position> _determinePosition() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
if (permission == LocationPermission.denied) {
return Future.error('Location permissions are denied');
}
}
return await Geolocator.getCurrentPosition();
}
#override
Widget build(BuildContext context) {
// TESTIST IF PRINT CAN WORK HERE
print(_determinePosition());
return Scaffold(
appBar: AppBar(
title: Text("Location"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(
child: Text("Get location"),
onPressed: () {
// PRINTING IN THE CONSOLE
_determinePosition();
},
),
],
),
),
);
}
}
Try to add the Internet permission in addition to the location permissions per the documentation (https://pub.dev/packages/geolocator):
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Regarding getting "intsantce of a Future" instead of the result you need to await the call to _determinePosition() just like this:
onPressed: () async{
// PRINTING IN THE CONSOLE
await _determinePosition();
},
For using Geolocator as a service I recommend to use a dependency injection solution like Provider(https://pub.dev/packages/provider) or GetIt(https://pub.dev/packages/get_it)
Use below function which checks the permission and returns current position, so before getting location it's important to check whether we had required permission or not.
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.deniedForever) {
// Permissions are denied forever, handle appropriately.
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
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');
}
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
return await Geolocator.getCurrentPosition();
}

Flutter Geolocator Location doesn't obtain for real phones

I used geolocator flutter package for my little app and it works perfectly with emulator, but when I try to use in my real smart phone, it doesnt work. Do you have any idea?
void getLocationData() async {
WeatherModel weatherModel = WeatherModel();
var weatherData = await weatherModel.getLocationWeather();
//print(weatherData);
var zipCode = await weatherModel.getLocationZipCode();
zipCode = zipCode.toString().substring(0, 2);
Navigator.push(context, MaterialPageRoute(builder: (context) {
return LocationScreen(
locationWeather: weatherData,
zipCode: zipCode,
);
}));
}
Future<dynamic> getLocationWeather() async {
Location location = Location();
await location.getCurrentLocation();
NetworkHelper networkHelper = NetworkHelper(
'$openWeatherMapURL?lat=${location.latitude}&lon=${location.longitude}&appid=$apiKey&units=metric');
var weatherData = await networkHelper.getData();
return weatherData;
}
Angela Yu's student? her projects need one update for optimizing and fixing little errors.
I got problems with Geolocator, it was not being used correctly, and this site helped me a lot. Then I made my own Location class with Provider and... life becomes good again.
Try use geolocator. I seems you are not using geolocator package
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager;
// return true if location service is enable, false if not
bool locationServiceEnable = await geolocator.isLocationServiceEnabled();
// position instace
Position position;
// if location service enable get current position
if (locationServiceEnable) {
// await current position
position = await geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
// if location service is not enable get last known position
} else {
// await last known position
position = await geolocator.getLastKnownPosition(
desiredAccuracy: LocationAccuracy.best);
}
if (position != null) {
// fetch weather data with position data
}
You should add
<uses-permission android:name="android.permission.INTERNET" />
to the AndroidManifest.xml. It helps to use the internet to fetch location data in an Android device, because your app still need to get data from URL openweathermap.
using geolocator: ^7.0.1
and adding
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
to AndroidManifest.xml file
void getLocation() async {
print('getLocation');
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
print(position);
}
and using in onPressed
onPressed: () {
getLocation();
},
solves the problem.

Device Country in Flutter

I am trying to get country of device (Android) in Flutter. I used this tutorial, but I think it is the wrong approach for my problem.
Locale myLocale = Localizations.localeOf(context);
print(myLocale.languageCode.toString() + ' ' + myLocale.countryCode.toString());
Based on this, I have couple of questions/issues:
I am always getting en US even though I have set device language to Urdu - Pakistan. So what am I missing?
I want to display certain app items based on the country the device is in, not based on language as people living in Pakistan with language set to English (US) will get items actually intended for USA based users. So, should I use geoLocation and get longitude and latitude and decide based on that data? Or is there any other simpler approach just to get country of user?
Thanking in anticipation.
Add this 2 library in pubspec.yaml
geolocator: ^5.1.1
geocoder: ^0.2.1
Then Add permission for Location access. Check here
At last call this method where you want.
Future<String> getCountryName() async {
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
debugPrint('location: ${position.latitude}');
final coordinates = new Coordinates(position.latitude, position.longitude);
var addresses = await Geocoder.local.findAddressesFromCoordinates(coordinates);
var first = addresses.first;
return first.countryName; // this will return country name
}
if you are looking to get the device country without using "geolocator" so you don't need to get the device permission, you can use the below code:
Future<String> getCountry() async{
Network n = new Network("http://ip-api.com/json");
locationSTR = (await n.getData());
locationx = jsonDecode(locationSTR);
return locationx["country"];
}
The Network class code is below:
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
class Network {
final String url;
Network(this.url);
Future<String> apiRequest(Map jsonMap) async {
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/x-www-form-urlencoded');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
// todo - you should check the response.statusCode
String reply = await response.transform(utf8.decoder).join();
httpClient.close();
return reply;
}
Future<String> sendData(Map data) async {
http.Response response = await http.post(url,
headers: {'Content-Type': 'application/json; charset=UTF-8'},
body: jsonEncode(data));
if (response.statusCode == 200)
return (response.body);
else
return 'No Data';
}
Future<String> getData() async {
http.Response response = await http.post(url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'});
if (response.statusCode == 200)
return (response.body);
else
return 'No Data';
}
}
you can get the city and countrycode and internet provider as well.
try this
import 'dart:io' show Platform;
String localeName = Platform.localeName;
Use the flutter_sim_country_code, with this package you can get a user localizations variables and country code directly from the user sim and network provider. For example;
networkCountryIso,
simCountryIso,
these variable always holds the country code,
please use package https://pub.dev/packages/devicelocale
I have tested with real device, it works fine
code snippet
String locale = await Devicelocale.currentLocale;
full code
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:devicelocale/devicelocale.dart';
void main() => runApp(MyApp());
/// Demo getting a device locale
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List _languages = List();
String _locale;
#override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
List languages;
String currentLocale;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
languages = await Devicelocale.preferredLanguages;
print(languages);
} on PlatformException {
print("Error obtaining preferred languages");
}
try {
currentLocale = await Devicelocale.currentLocale;
print(currentLocale);
} on PlatformException {
print("Error obtaining current locale");
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_languages = languages;
_locale = currentLocale;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
children: <Widget>[
Text("Current locale: "),
Text('$_locale'),
Text("Preferred Languages: "),
Text(_languages.toString()),
],
)
),
),
);
}
}
I had the same problem working on an app with country specific functionality. All these methods mentioned here are good, having gone through them all myself I realised none will cover all possible scenarios.
So, I changed the approach to the problem. Instead of making decision programmatically, which country user is in and going ahead with it. I thought it is better to identify the user's country using one of the methods that suits your app most and then present it to the user. If they wish they can change it, otherwise in most cases auto detection is valid.
For my app I presented users with country when logging in and a flat button at bottom to change it if it is not correct.
This solution requires location service to be enabled.
Add these two dependencies in your pubspec.yaml file
geolocator: ^7.0.3
geocoding: ^2.0.0
Future<String> getCountryCodeName() async {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
List<Placemark> address =
await placemarkFromCoordinates(position.latitude, position.longitude);
Placemark placeMark = address.first;
String country = placeMark.country;
return country; // this will return country }
You have to use a geolocator and geocode plugin. then create this method use below code. In Android Manifest.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Function
Future<String> getCountryName() async {
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
await Geolocator.requestPermission();
}
if (permission == LocationPermission.deniedForever) {
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
}
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
debugPrint('location: ${position.latitude}');
final coordinates = new Coordinates(position.latitude, position.longitude);
var addresses =
await Geocoder.local.findAddressesFromCoordinates(coordinates);
var first = addresses.first;
print(first.countryName);
return first.countryName;
}
Try this. Don't forget to provide necessary permissions in android manifest and ios as well.
import 'package:geolocator/geolocator.dart';
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager;
geolocator
.getCurrentPosition(desiredAccuracy: LocationAccuracy.best)
.then((Position position) {
setState(() {
_currentPosition = position;
});
}).catchError((e) {
print(e);
});
Building on #chunhunghan's answer, you can use the plugin https://pub.dev/packages/devicelocale. To get the country code, you have to use:
Locale l = await Devicelocale.currentAsLocale;
String countryCode = l.countryCode;
For the full code, check: https://pub.dev/packages/devicelocale#-example-tab-
var code = WidgetsBinding.instance.window.locale.countryCode;