Geolocator seems to simply not work on WP8 when it should. (But for some strange reason works perfectly fine on 8.1)... I'm in optimal conditions - LTE, FiOS Wifi... No obstructions. No reason why it shouldn't work. However, it seems to just hang and never return the current location or even an exeption.
I have tried to disable the reverse geocode and it does not work. I've narrowed it down to being the actual service that gets the location (Geolocator or GeoPosition)
ID_CAP_LOCATION is enabled. Phone location services are enabled. I'm targeting WP8.
Code:
private async void getlocation()
{
try
{
Geolocator gl = new Geolocator(); gl.DesiredAccuracyInMeters = 50;
Geoposition geoposition = await gl.GetGeopositionAsync(maximumAge: TimeSpan.FromMinutes(5), timeout: TimeSpan.FromSeconds(60));
latitude = geoposition.Coordinate.Latitude.ToString(); longitude = geoposition.Coordinate.Longitude.ToString();
//Location to physical address
List<MapLocation> locations;
ReverseGeocodeQuery query = new ReverseGeocodeQuery();
query.GeoCoordinate = new GeoCoordinate(geoposition.Coordinate.Latitude, geoposition.Coordinate.Longitude);
//Set address to tecxtblock
query.QueryCompleted += (s, e) =>
{
locations = e.Result as List<MapLocation>;
address = locations[0].Information.Address.City.ToString();
ts.Center = new GeoCoordinate(geoposition.Coordinate.Latitude, geoposition.Coordinate.Longitude);
ts.ZoomLevel = 7;
location.Text = address.ToUpper(); //Location
//Successful, now get weather for current location
getforecast();
};
query.QueryAsync();
}
catch
{
MessageBox.Show("Location services appear to be turned off. To use Atmosphere, turn location services on.");
}
}
I've encountered issues on WP8 with background tracking where it would only update the the position when the app was bought to the foreground. Very confusing as I knew it was working on other devices without issue.
In the end I simply un-installed the app completely and re-installed, this solved the issue. Just in case you haven't tried it - just completely remove the app and re-install / re-deploy using Visual Studio. Issue might resolve itself.
I had the same problem. The same code works in 8.1 but does not in 8.0
I was able to make it work when i called the function from a button click instead of the constructor of the Page or in Page_loaded event.
Related
I have been working on a location-oriented project that I need to be able to track a user's location while the app is terminated.
I have a background service in my Android project and the Geolocator Plugin.
Just for reference, here are my Geolocator settings:
App.xaml.cs
public static async void StartListening()
{
if (CrossGeolocator.Current.IsListening)
return;
CrossGeolocator.Current.DesiredAccuracy = 10;
await CrossGeolocator.Current.StartListeningAsync(TimeSpan.FromSeconds(LOCATION_PING_SECONDS), 1, true, new Plugin.Geolocator.Abstractions.ListenerSettings
{
AllowBackgroundUpdates = true,
PauseLocationUpdatesAutomatically = false
});
CrossGeolocator.Current.PositionChanged += PositionChanged;
CrossGeolocator.Current.PositionError += PositionError;
}
This + my location service for Android work like a charm while the app is running and backgrounded, but obviously everything stops when the app is terminated.
Android/MainActivity.cs
public void StartLocationService()
{
powerManager = (PowerManager) GetSystemService(PowerService);
wakeLock = powerManager.NewWakeLock(WakeLockFlags.Full, "LocationHelper");
// create a new service connection so we can get a binder to the service
locationServiceConnection = new LocationServiceConnection(null);
// this event will fire when the Service connectin in the OnServiceConnected call
locationServiceConnection.ServiceConnected += (object sender, ServiceConnectedEventArgs e) => {
Console.WriteLine("Service Connected");
};
// Starting a service like this is blocking, so we want to do it on a background thread
new Task(() => {
// Start our main service
Console.WriteLine("App", "Calling StartService");
Android.App.Application.Context.StartService(new Intent(Android.App.Application.Context, typeof(LocationService)));
// bind our service (Android goes and finds the running service by type, and puts a reference
// on the binder to that service)
// The Intent tells the OS where to find our Service (the Context) and the Type of Service
// we're looking for (LocationService)
Intent locationServiceIntent = new Intent(Android.App.Application.Context, typeof(LocationService));
Console.WriteLine("App", "Calling service binding");
// Finally, we can bind to the Service using our Intent and the ServiceConnection we
// created in a previous step.
Android.App.Application.Context.BindService(locationServiceIntent, locationServiceConnection, Bind.AutoCreate);
}).Start();
Console.WriteLine("Aquiring Wake Lock");
wakeLock.Acquire();
}
Does anyone know of any tutorials for getting location updates even when the app is terminated? Is this even possible?
Thanks!
Also, I found this Xamarin forum post... The last post says he is able to get updates while the app is terminated from a service, but I have not been able to get the same outcome.
I am using Geoposition and a Postition changed event to grab Coordinates of the device location.
private async void StartGpsMonitoring()
{
if (locator == null)
{
locator = new Geolocator();
}
if (locator.LocationStatus == PositionStatus.Disabled)
{
//throw new Exception();
MessageDialog noGpsDialog = new MessageDialog("Location services are disabled, please enable location services");
noGpsDialog.Commands.Add(new UICommand("Location Settings", new UICommandInvokedHandler(this.CommandInvokedHandler), 0));
noGpsDialog.Commands.Add(new UICommand("Cancel", new UICommandInvokedHandler(this.CommandInvokedHandler), 1));
await noGpsDialog.ShowAsync();
}
if (locator != null)
{
//locator.MovementThreshold = 3;
locator.ReportInterval = 1;
locator.DesiredAccuracy = PositionAccuracy.High;
locator.PositionChanged +=
new TypedEventHandler<Geolocator,
PositionChangedEventArgs>(locator_PositionChanged);
}
}
private async void locator_PositionChanged(Geolocator sender, PositionChangedEventArgs e)
{
string speed = string.Empty;
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Geoposition geoPosition = e.Position;
if (e.Position.Coordinate.Speed != null)
{
speed = e.Position.Coordinate.Speed.Value.ToString(); // always 5.8
}
geolocation = geoPosition.Coordinate.Point.Position.Latitude.ToString() + " " +
geoPosition.Coordinate.Point.Position.Longitude.ToString() + "Speed = " +
speed;
var textBlockStatus =
ControlHelper.FindChildControl<TextBlock>(JourneyTrackerSection, "TextBlockStatus") as TextBlock;
textBlockStatus.Text = geolocation;
});
}
I am also trying to get the speed value. But when using the emulator I am always getting 5.8 regardless of if I have speed limit/walking/biking set on the emulator, and still get 5.8 from a static position.
Can anybody shed some light as to why? Is it just the emulator? Would I get an accurate result if I used a real device?
Its hard to develop a location speed application where I have to run out side every time I want to debug/run it.
Any help much appreciated.
Thought I would post some details as to what I have managed to find out in case anyone comes across this in the future. Looks like this is because it is running on the emulator. Managed to come across some limited details about using the geopositioning code and some details about it being hardware specific. After I have managed to get hold of a windows phone for testing the emulator cannot do the speed. Works perfect on an actual device.
This is extremely annoying by Microsoft. means that every time I need to test my app I have to go out driving. Rendering the GPS emulator completely useless!
System Information
Windows 10 Technical Preview (build 9926)
Visual Studio Community 2013Attempting to debug on:
[AT&T] Lumia 635 (Windows 10 Technical Preview for phones build 9941 w/ Lumia Cyan)
[AT&T] Lumia 1520 (Windows Phone 8.1 with Lumia Denim and PfD)
[Unlocked] BLU Win Jr (Windows Phone 8.1 with PfD)
[Verizon] Lumia Icon (Windows Phone 8.1 with Lumia Denim and PfD)
I trying to get location services working in my app. Previously, I had Visual Studio throw the error. It was an ArgumentException with the message "Use of undefined keyword value 1 for event TaskScheduled in async". Googling didn't turn up any solutions.
Here is the code:
Geolocator Locator = new Geolocator();
Geoposition Position = await Locator.GetGeopositionAsync();
Geocoordinate Coordinate = Position.Coordinate;
When I could get the error to be thrown, the exception was thrown on the 2nd or 3rd line in the sample above.
I simplified the original code to try and fix it, but this is the original:
Geolocator Locator = new Geolocator();
Geocoordinate Coordinate = (await Locator.GetGeopositionAsync()).Position.Coordinate;
The entire app works when debugging, but crashes almost instantaneously otherwise.
This is a Windows 8.1 Universal project, focusing on the phone project.
Thanks in advance
EDIT: As requested, here is the full method:
private static bool CheckConnection()
{
ConnectionProfile connections = NetworkInformation.GetInternetConnectionProfile();
bool internet = connections != null && connections.GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess;
return internet;
}
public static async Task<double> GetTemperature(bool Force)
{
if (CheckConnection() || Force)
{
Geolocator Locator = new Geolocator();
await Task.Yield(); //Error occurs here
Geoposition Position = await Locator.GetGeopositionAsync();
Geocoordinate Coordinate = Position.Coordinate;
HttpClient Client = new HttpClient();
double Temperature;
Uri u = new Uri(string.Format("http://api.worldweatheronline.com/free/v1/weather.ashx?q={0},{1}&format=xml&num_of_days=1&date=today&cc=yes&key={2}",
Coordinate.Point.Position.Latitude,
Coordinate.Point.Position.Longitude,
"API KEY"),
UriKind.Absolute);
string Raw = await Client.GetStringAsync(u);
XElement main = XElement.Parse(Raw), current_condition, temp_c;
current_condition = main.Element("current_condition");
temp_c = current_condition.Element("temp_C");
Temperature = Convert.ToDouble(temp_c.Value);
switch (Memory.TempUnit)
{
case 0:
Temperature = Convertions.Temperature.CelsiusToFahrenheit(Temperature);
break;
case 2:
Temperature = Convertions.Temperature.CelsiusToKelvin(Temperature);
break;
}
return Temperature;
}
else
{
throw new InvalidOperationException("Cannot connect to the weather server.");
}
}
EDIT 2: I've asked for help on Twitter, and received a reply asking for a repro project. I recreated the major portion of the original app, but I could not get the error. However, errors may occur for you so here's the project.
EDIT 3: If it helps at all, here are the exception details:
System.ArgumentException occurred
_HResult=-2147024809
_message=Use of undefined keyword value 1 for event TaskScheduled.
HResult=-2147024809
IsTransient=false
Message=Use of undefined keyword value 1 for event TaskScheduled.
Source=mscorlib
StackTrace:
at System.Diagnostics.Tracing.ManifestBuilder.GetKeywords(UInt64 keywords, String eventName)
InnerException:
Having checked this and this, I believe this is a bug in .NET async/await infrastructure for WinRT. I couldn't repro it, but I encourage you to try the following workaround, see if it works for you.
Factor out all asynchronous awaitable calls from OnNavigatedTo into a separate async Task method, e.g. ContinueAsync:
async Task ContinueAsync()
{
Geolocator Locator = new Geolocator();
Geoposition Position = await Locator.GetGeopositionAsync();
Geocoordinate Coordinate = Position.Coordinate;
// ...
var messageDialog = new Windows.UI.Popups.MessageDialog("Hello");
await messageDialog.ShowAsync();
// ...
}
Remove async modifier from OnNavigatedTo and call ContinueAsync from OnNavigatedTo like this:
var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(
() => ContinueAsync(),
CancellationToken.None, TaskCreationOptions.None, scheduler).
Unwrap().
ContinueWith(t =>
{
try
{
t.GetAwaiter().GetResult();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
throw; // re-throw or handle somehow
}
},
CancellationToken.None,
TaskContinuationOptions.NotOnRanToCompletion,
scheduler);
Let us know if it helps :)
Updated, apparently, the bug is somewhere in the TPL logging provider, TplEtwProvider. You can see it's getting created if you add the below code. So far, I couldn't find a way to disable this event source (either directly or via Reflection):
internal class MyEventListener : EventListener
{
protected override void OnEventSourceCreated(EventSource eventSource)
{
base.OnEventSourceCreated(eventSource);
if (eventSource.Name == "System.Threading.Tasks.TplEventSource")
{
var enabled = eventSource.IsEnabled();
// trying to disable - unsupported command :(
System.Diagnostics.Tracing.EventSource.SendCommand(
eventSource, EventCommand.Disable, new System.Collections.Generic.Dictionary<string, string>());
}
}
}
// ...
public sealed partial class App : Application
{
static MyEventListener listener = new MyEventListener();
}
Using the 8.1 MediaCapture classes for Windows Phone.
Have declared the capabilities for "Audio" and "Webcam", which 90% is what would be the cause of the exception.
Kicker is, it works perfectly in the WP emulator, but breaks on an actual device.
Exact exception is here :
I have added a mountain of checks to make sure we aren't re-initializing the already initialized camera or trying to read before the initializations.. etc (as I assumed the issue was being caused by) So it is very unlikely to be that.
private async Task InitializeCameraAsync()
{
if (_isInitialized)
{
Debug.WriteLine("Skipping unnecessary initialization");
return;
}
Debug.WriteLine("Initializing camera media capture...");
_deviceCapture = new MediaCapture();
await _deviceCapture.InitializeAsync(new MediaCaptureInitializationSettings
{
VideoDeviceId = _cameraInfoCollection[_currentVideoDevice].Id,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview,
AudioDeviceId = _microphoneInfoCollection[_currentAudioDevice].Id
StreamingCaptureMode = StreamingCaptureMode.Video
});
Debug.WriteLine("Initialized camera media capture!");
// For code completion only, unlikely to be relevant
// Set up low-lag photo capture
if (IsNotUsingInstantCapture)
{
Debug.WriteLine("Preparing low-lag photo capture");
var imageEncoding = ImageEncodingProperties.CreateJpeg();
imageEncoding.Width = PhotoCaptureWidth;
imageEncoding.Height = PhotoCaptureHeight;
_lowLagPhotoCapture = await _deviceCapture.PrepareLowLagPhotoCaptureAsync(imageEncoding);
}
_isInitialized = true;
Debug.WriteLine("Initialized camera!");
}
_mediacapture is then being bound to the .source of a xaml CaptureElement to show a preview.
It was a temporary bug with the Windows api. It was fixed with the Windows Phone 8.1 update that was released the 24th of september 2014.
I'm developing a Windows Store App where I'm using the Bing Maps control. I created a method that use the Geolocator and GeoPosition to get the users current position.
Also, I enabled the location capability from the manifiest file.
However, everytime when I run the App, the first time I click on the button to get the position I got the following error message: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
When I click the second time in the same button to perform the same action, now the error messages disappear and the Bing Maps work properly showing me my current position. But, I'm a little concerned why I got the error messages always the firsr time I try to get the location.
Here are the two methods I execute to get the position:
private async Task SetMyLocation()
{
var position = await GetCurrentPosition();
if (position != null)
{
this.DataContext = position;
this.myLocation = new Location(position.Latitude, position.Longitude);
this.myMap.Center = this.myLocation;
//this.myMap.ZoomLevel = 20;
this.myMap.SetView(myLocation, 12, MapAnimationDuration.Default);
this.AddMyLocationPushpin();
}
}
private async Task<Position> GetCurrentPosition()
{
try
{
Geolocator geolocator = new Geolocator();
geolocator.DesiredAccuracy = PositionAccuracy.High;
geolocator.MovementThreshold = 0;
Geoposition location = await geolocator.GetGeopositionAsync(
maximumAge: TimeSpan.FromMinutes(5),
timeout: TimeSpan.FromSeconds(10)
);
var postion = new Position
{
Latitude = location.Coordinate.Latitude,
Longitude = location.Coordinate.Longitude
};
return postion;
}
catch (Exception ex)
{
. . .
return null;
}
}
Any suggestion, comment why I am getting the above error message? Any clue and/or solution would be OK?
Regards!
Ensure that you have allowed your app to access the user location. Open the Package manifest and go to the capabilities tab. Make sure the Location option is checked. Re-run your app, you will be prompted to allow the app to access your location, allow it. It should then work for you. You can find a blog post example on this here: http://www.bing.com/blogs/site_blogs/b/maps/archive/2012/11/05/getting-started-with-bing-maps-windows-store-apps-native.aspx