Flutter Getx geolocator: Get user position for google maps - flutter

I am currently making a maps page and I need to get the user's current location and pass it into google maps. I am using GetX. However I am currently getting an error about type 'Future<dynamic>' is not a subtype of type 'LatLng' and I do not know what to do to fix this. Essentially I just want to get the user's location and pass it in to a GoogleMap as initial camera position.
Here is my controller:
class LocationController extends GetxController {
static LocationController instance = Get.find();
#override
void onReady() {
super.onReady();
getlocation();
}
getlocation() async {
bool serviceEnabled;
LocationPermission permission;
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
await Geolocator.openLocationSettings();
return Future.error("location service is not enabled");
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
//do stuff here
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
//stuff
return Future.error("location permissions denied");
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error("location permissions permanently denied");
}
Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
//position stream?
}
}
This is the code for the map page:
class MapPage extends StatefulWidget {
const MapPage({super.key});
#override
State<MapPage> createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Container(
child: GoogleMap(
initialCameraPosition: CameraPosition(
target: locationController.getlocation(), zoom: 16),
minMaxZoomPreference: MinMaxZoomPreference(15.5, 19),
zoomGesturesEnabled: true,
cameraTargetBounds: CameraTargetBounds(
LatLngBounds(
northeast: LatLng(43.7970928, -79.3067414),
southwest: LatLng(43.592580, -79.483674),
),
),
),
),
],
),
);
}
}

try this
// create a class for location also handle permission
class PermissionToUser {
static Future permissionForLocation() async {
final request = await [Permission.location].request();
log(request[Permission.location].toString());
final status = await Permission.location.status;
if (status.isDenied) {
request;
return false;
} else if (status.isRestricted) {
request;
return false;
} else if (status.isLimited) {
request;
return false;
} else {
return true;
}
}
static Future<Position>? determinePosition() async {
bool serviceEnabled;
LocationPermission permission;
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.denied) {
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
}
}
As per use on the controller
class LocationController extends GetxController {
/// Declare the postion also the lat long just for example
late Position? posinitial;
final lat = 0.0.obs, lng = 0.0.obs;
#override
void onInit() async {
/// Run through here
await PermissionToUser.permissionForLocation().then((value) async {
posinitial = await PermissionToUser.determinePosition();
}).whenComplete(() {
getPositionData();
});
super.onInit();
}
getPositionData() async{
// try to log the data if its not empty
if (posinitial != null) {
log("${posinitial!.latitude}",name:"latitude");
log("${posinitial!.longitude}",name:"longtitude");
/// just pass this to ui to use
lat(posinitial!.latitude);
long(posinitial!.longitude);
}
}
}
as for the googgle map you can call the postion
posinitial != null ?
GoogleMap(
initialCameraPosition: CameraPosition(
/// you can use the lat long that was declared on the controller
/// anyways many ways to do it.
target: LatLng(controller.posinitial!.latitude, controller.posinitial!.longitude), zoom: 16),
minMaxZoomPreference: MinMaxZoomPreference(15.5, 19),
zoomGesturesEnabled: true,
cameraTargetBounds: CameraTargetBounds(
LatLngBounds(
northeast: LatLng(43.7970928, -79.3067414),
southwest: LatLng(43.592580, -79.483674),
),
),
) : const SizedBox.shrink(),

I think you should create a seperate variable like this :
In controller, I created a Position type var myLocation and storing my location in it.
static LocationController instance = Get.find();
late Position myLocation;
#override
void onInit() {
super.onInit();
getlocation();
}
getlocation() async {
bool serviceEnabled;
LocationPermission permission;
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
await Geolocator.openLocationSettings();
return Future.error("location service is not enabled");
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
//do stuff here
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
//stuff
return Future.error("location permissions denied");
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error("location permissions permanently denied");
}
myLocation = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
//position stream?
}
and the GoogleMap widget should be like:
GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(
locationController.myLocation.latitude,
locationController.myLocation.longitude ),
zoom: 16),
minMaxZoomPreference: MinMaxZoomPreference(15.5, 19),
zoomGesturesEnabled: true,
cameraTargetBounds: CameraTargetBounds(
LatLngBounds(
northeast: LatLng(43.7970928, -79.3067414),
southwest: LatLng(43.592580, -79.483674),
),
),

Related

Stream<Position> of Geolocator.getPositionStream is not listen

I'm using geolocator and google_maps_flutter in my app to get user location, passing by getPositionStream.
The Map is the first screen of the app, and when I get user location it work fine, and the camera of the map zoom correctly.
But the user can login to his account, and it's recreated the Map. And my problem is here. When the login is done, my stream with my new location is not listen :/ I need to reload the app for that
My function in my viewModel
final Stream<Position>? stream = await _locationService.getLocation();
if (stream != null) {
stream.listen((location) async {
final newLocation =
CameraPosition(target: LatLng(location.latitude, location.longitude), zoom: 15);
if (controllerCompleter != null) {
final GoogleMapController controller = await controllerCompleter.future;
controller.animateCamera(CameraUpdate.newCameraPosition(newLocation));
}
});
}
In the locationService:
Future<Stream<Position>?> getLocation() async {
bool _serviceEnabled;
LocationPermission _permissionGranted;
_serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!_serviceEnabled) {
return null; // Use France's GPS coordinates by default
}
_permissionGranted = await Geolocator.checkPermission();
if (_permissionGranted == LocationPermission.denied) {
_permissionGranted = await Geolocator.requestPermission();
if (_permissionGranted == LocationPermission.denied ||
_permissionGranted == LocationPermission.deniedForever) {
return null; // Use France's GPS coordinates by default
} else {
return Geolocator.getPositionStream(locationSettings: locationSettings);
}
} else {
return Geolocator.getPositionStream(locationSettings: locationSettings);
}
}
If anyone have an idea of what I'm doing wrong.
Thanks in advance

Want to post geolocation on a external api using getx

I have already got the geolocation with longitude and latitude using the geolocation plugin with getx but now I want to post the same longitude and latitude on API with already present in the backhand the model is yet to be created and even the provider is also yet to be done and I don't know how and the location API post should run in the background once with the application opens up.
API body:-
{
"longitude":"55.5852",
"latitude":"77.6532"
}
Controller code:-
class RootController extends GetxController {
var latitude = 'Getting Latitude..'.obs;
var longitude = 'Getting Longitude..'.obs;
var address = 'Getting Address..'.obs;
final currentIndex = 0.obs;
final notificationsCount = 0.obs;
final customPages = <CustomPage>[].obs;
NotificationRepository _notificationRepository;
CustomPageRepository _customPageRepository;
StreamSubscription<Position> streamSubscription;
RootController() {
_notificationRepository = new NotificationRepository();
_customPageRepository = new CustomPageRepository();
}
#override
void onInit() async {
await getCustomPages();
getNotificationsCount();
if (Get.arguments != null && Get.arguments is int) {
changePageInRoot(Get.arguments as int);
} else {
changePageInRoot(0);
}
super.onInit();
getLocation();
}
#override
void onReady(){
super.onReady();
}
#override
void onClose(){
streamSubscription.cancel();
}
getLocation() async{
bool serviceEnabled;
LocationPermission permission;
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){
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever){
return Future.error('Location permissions are permanently denied');
}
streamSubscription = Geolocator.getPositionStream().listen((Position position) {
latitude.value = 'Latitude:${position.latitude}';
longitude.value = 'Longitude:${position.latitude}';
getAddressFromLatLang(position);
print(latitude.value);
print(longitude.value);
});
}
Future<void> getAddressFromLatLang(Position position)async{
List<Placemark> placemark = await
placemarkFromCoordinates(position.latitude,position.longitude);
Placemark place = placemark[0];
address.value = 'address:${place.locality},${place.country}';
}
List<Widget> pages = [
HomeView(),
// EServicesView2(),
ReviewsView(),
MessagesView(),
AccountView(),
];
Widget get currentPage => pages[currentIndex.value];
/**
* change page in route
* */
void changePageInRoot(int _index) {
currentIndex.value = _index;
}
void changePageOutRoot(int _index) {
currentIndex.value = _index;
Get.offNamedUntil(Routes.ROOT, (Route route) {
if (route.settings.name == Routes.ROOT) {
return true;
}
return false;
}, arguments: _index);
}
Future<void> changePage(int _index) async {
if (Get.currentRoute == Routes.ROOT) {
changePageInRoot(_index);
} else {
changePageOutRoot(_index);
}
await refreshPage(_index);
}
Future<void> refreshPage(int _index) async {
switch (_index) {
case 0:
{
await Get.find<HomeController>().refreshHome();
break;
}
case 2:
{
await Get.find<MessagesController>().refreshMessages();
break;
}
}
}
void getNotificationsCount() async {
notificationsCount.value = await _notificationRepository.getCount();
}
Future<void> getCustomPages() async {
customPages.assignAll(await _customPageRepository.all());
}
}
what else should I do?

Live location in flutter

How to get the coordinates of live location in flutter ? I want to get the live location coordinates. What could be done to get this ? I am imported the location package in flutter but I just want to get the coordinates of live location .
First of all you need to get a location plugin.
https://pub.dev/packages/location. Also I recommend that use Provider plugin and create model files. It will be more easier to manage. In addition , you have to check permission status of your device . you will reach all of information what you want to learn through link
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Location _location = Location();
LocationData currentLocation;
#override
void initState() {
location = new Location();
location.onLocationChanged.listen((LocationData cLoc) {
currentLocation = cLoc;
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Center(
child: Text(
'Location: Lat${currentLocation.latitude}, Long: ${currentLocation.longitude}'),);}}
Location location = new Location();
bool _serviceEnabled;
PermissionStatus _permissionGranted;
LocationData _locationData;
_serviceEnabled = await location.serviceEnabled();
if (!_serviceEnabled) {
_serviceEnabled = await location.requestService();
if (!_serviceEnabled) {
return;
}
}
_permissionGranted = await location.hasPermission();
if (_permissionGranted == PermissionStatus.denied) {
_permissionGranted = await location.requestPermission();
if (_permissionGranted != PermissionStatus.granted) {
return;
}
}
location.onLocationChanged.listen((LocationData currentLocation) {
// Use current location
});

Problem in storing LocationData in flutter

I am trying getting the location coordinates of user and storing it in variable.
I use the location library from flutter.
But I get this error:
type 'Future' is not a subtype of type 'Future'
This is my code
Future<LocationData> coords;
double lat, long;
coords = getUserLocationCoordinates();
coords.then((value) => {
lat = value.latitude,
long = value.longitude,
});
My getUserLocationCoordinates function
getUserLocationCoordinates() async {
LocationData currentLocation;
String error;
Location location = Location();
try {
currentLocation = await location.getLocation();
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'please grant permission';
print(error);
}
if (e.code == 'PERMISSION_DENIED_NEVER_ASK') {
error = 'permission denied- please enable it from app settings';
print(error);
}
currentLocation = null;
}
return currentLocation;
}
Any help is greatly appreciated
Initialize variables
String latitude_data;
String longitude_data;
bool _serviceEnabled;
Current Location Function
Future _getLocation() async {
Location location = new Location();
var _permissionGranted = await location.hasPermission();
_serviceEnabled = await location.serviceEnabled();
if (_permissionGranted != PermissionStatus.granted || !_serviceEnabled) {
_permissionGranted = await location.requestPermission();
_serviceEnabled = await location.requestService();
} else {
///Do something here
}
LocationData _currentPosition = await location.getLocation();
longitude_data=_currentPosition.longitude.toString();
latitude_data=_currentPosition.latitude.toString();
///if you want you can save data to sharedPrefrence
SharedPrefrence().setLatitude(_currentPosition.latitude.toString());
SharedPrefrence().setLongitude(_currentPosition.longitude.toString());
}

Flutter: Check Internet connectivity and navigate based on output?

I am new to flutter, I want to check whether the internet is available or not and based on the condition, the screen has to change. I have written the code below (screen switch is working properly), but I am not able to get bool output(internet). When I removed the Future in check internet class, it throws an error. Can you please solve the issue:
class _ScreenState extends State<ChannelScreen> {
bool isInternet;
bool result;
#override
void initState() {
// TODO: implement initState
result = check();
super.initState();
}
#override
Widget _buildChild() {
print ("The output “);
print (result);
if (result != Null && result == true) {
// if internet is ON
return Container();
}
//if internet is off
return Container();
}
Widget build(BuildContext context) {
return new Container(child: _buildChild());
}
}
Future<bool> check() async{
var connectivityResult = await Connectivity().checkConnectivity();
if (connectivityResult == ConnectivityResult.mobile) {
print ("******* Mobile is ON ******");
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
print ("******* Wifi is ON ******");
return true;
}
print ("No connectivity");
return false;
}
You can use StreamBuilder
StreamBuilder(
stream: Connectivity().onConnectivityChanged,
builder: (context, snapshot) {
// Use this to avoid null exception
if (snapshot.connectionState == ConnectionState.none) {
return CircularProgressIndicator();
} else {
ConnectivityResult result = snapshot.data;
// Check Connectivity result here and display your widgets
if(ConnectivityResult.none) {
yourWidgetForNoInternet();
} else {
yourWidgetForInternet();
}
}
},
)
bool hasInternet = false, isChecking = true;
#override
void initState() {
super.initState();
check();
}
#override
Widget build(BuildContext context) {
return Container(
child: isChecking
? ListTile(
leading: CircularProgressIndicator(), title: Text('Checking...'))
: hasInternet
? ListTile(title: Text('Your widget here...'))
: ListTile(
leading: Icon(Icons.info),
title: Text('No Internet Conncetion')));
}
check() async {
var connectivityResult = await Connectivity().checkConnectivity();
if (connectivityResult == ConnectivityResult.mobile) {
print("******* Mobile is ON ******");
setState(() {
isChecking = false;
hasInternet = true;
//navigate to another screen.....
});
} else if (connectivityResult == ConnectivityResult.wifi) {
print("******* Wifi is ON ******");
setState(() {
isChecking = false;
hasInternet = true;
//navigate to another screen.....
});
} else {
setState(() {
isChecking = false;
hasInternet = false;
});
}
}
There is a plugin to use connectivity:
https://pub.dev/packages/connectivity#-readme-tab-
I use following code to check whether the internet is connected or not
static Future<bool> checkInternetConnectivity() async {
bool isConnected;
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
isConnected = true;
}
} on SocketException catch (_) {
isConnected = false;
}
return isConnected;
}