Reputation: 398
I am using CrossGeolocator to retrieve the current latitude and longitude of the device. However I am using it inside an OnAppearing override method and it is not working. The GetPositionAsync method hangs the App.
protected override void OnAppearing()
{
base.OnAppearing();
var position = GetPosition().Result;
var lat = position.Latitude;
var lon = position.Longitude;
}
private static async Task<Position> GetPosition()
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(10000);
return position;
}
Detail is that I am using this same GetPosition method in buttons in the application and works perfectly.
Could someone help me in this matter?
Upvotes: 9
Views: 6854
Reputation: 31
I solved my problem just adding the parameters in GetPositionAsync: null and true.
var location = await locator.GetPositionAsync(TimeSpan.FromSeconds(20), null, true);
and turn on the GPS
My problem was on Android 4.4
Upvotes: 0
Reputation: 1
latest 2018-07-10 version update,
To support iOS 11 and earlier, you can include all three keys:
I use Xamarin to write app, and it works fine in my iOS project
reference : https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/map
Upvotes: 0
Reputation: 41
Things to take care is
calling the method in constructor. have available lat long if exists. VERY IMP have try catch, without try catch the application crashes. Not writing any thing in catch as don;t want to catch exception.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Foundation;
using UIKit;
using System.Threading.Tasks;
using Plugin.Geolocator.Abstractions;
using Plugin.Geolocator;
using System.Diagnostics;
using Xamarin.Forms;
using abcde.iOS;
[assembly: Xamarin.Forms.Dependency(typeof(GPSLocation_iOS))]
namespace abcde.iOS
{
public class GPSLocation_iOS : IGPSLocation
{
public Position _position;
public GPSLocation_iOS()
{
GetPosition();
}
public Dictionary<string, string> GetGPSLocation()
{
Dictionary<string, string> dictPosition = new Dictionary<string, string>();
dictPosition.Add("latitude", _position.Latitude.ToString());
dictPosition.Add("longitude", _position.Longitude.ToString());
return dictPosition;
}
public async void GetPosition()
{
try
{
var locator = CrossGeolocator.Current;
_position = await locator.GetLastKnownLocationAsync();
if (_position == null)
{
locator.DesiredAccuracy = 50;
var myPosition = await locator.GetPositionAsync();
_position = new Position(myPosition.Latitude, myPosition.Longitude);
}
}
catch (Exception ex)
{
}
}
Upvotes: 1
Reputation: 181
This worked for me.
Set up the xamarin forms maps as stated in the link. https://developer.xamarin.com/guides/xamarin-forms/user-interface/map/
set permissions as stated in below link https://jamesmontemagno.github.io/GeolocatorPlugin/GettingStarted.html
you may make use of https://jamesmontemagno.github.io/GeolocatorPlugin/CurrentLocation.html
using Plugin.Geolocator;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Xaml;
namespace MapApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MapPage : ContentPage
{
private Position _position;
public MapPage()
{
InitializeComponent();
var map = new Map(
MapSpan.FromCenterAndRadius(
new Position(37, -122), Distance.FromMiles(0.3)))
{
IsShowingUser = true,
HeightRequest = 100,
WidthRequest = 960,
VerticalOptions = LayoutOptions.FillAndExpand
};
if (IsLocationAvailable())
{
GetPosition();
map.MoveToRegion(MapSpan.FromCenterAndRadius(_position, Distance.FromMiles(1)));
}
map.MapType = MapType.Street;
var stack = new StackLayout { Spacing = 0 };
stack.Children.Add(map);
Content = stack;
}
public bool IsLocationAvailable()
{
if (!CrossGeolocator.IsSupported)
return false;
return CrossGeolocator.Current.IsGeolocationAvailable;
}
public async void GetPosition()
{
Plugin.Geolocator.Abstractions.Position position = null;
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 100;
position = await locator.GetLastKnownLocationAsync();
if (position != null)
{
_position = new Position(position.Latitude, position.Longitude);
//got a cahched position, so let's use it.
return;
}
if (!locator.IsGeolocationAvailable || !locator.IsGeolocationEnabled)
{
//not available or enabled
return;
}
position = await locator.GetPositionAsync(TimeSpan.FromSeconds(20), null, true);
}
catch (Exception ex)
{
throw ex;
//Display error as we have timed out or can't get location.
}
_position = new Position(position.Latitude, position.Longitude);
if (position == null)
return;
}
}
}
Upvotes: 4
Reputation: 2006
Try this:
Create a global variable:
private Position _position;
Then call ur method to get the position on constructor. Re-write ur method like this:
public async void GetPosition()
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
var myPosition = await locator.GetPositionAsync();
_position = new Position(myPosition.Latitude, myPosition.Longitude);
}
Then make a while where u want to use this:
while(_position == new Postion(0,0))
GetPosition();
Upvotes: 5