Windows Dev Center

Reagieren auf entfernungsbasierte Positionsupdates (XAML)

[Diese Dokumentation ist vorläufig. Änderungen vorbehalten.]

Hier erfahren Sie, wie Sie Updates erhalten, wenn der Benutzer eine Strecke zurücklegt, die über eine bestimmte Entfernung hinausgeht. Die Entfernung zwischen Positionsupdates wird als Bewegungsgrenze bezeichnet. In diesem Thema werden Codebeispiele verwendet, die den Teil zur Positionsnachverfolgung des Geolocation-Beispiels erweitern. Laden Sie das Beispiel herunter, und folgen Sie den Anweisungen, um zu erfahren, wie Sie die Häufigkeit von Positionsupdates mithilfe der Bewegungsgrenze steuern.

Roadmap: Wie hängt dieses Thema mit anderen zusammen? Weitere Informationen:

Schritt 1: Herunterladen des Geolocation-Beispiels, Hinzufügen der Benutzeroberfläche und Definieren neuer Eigenschaften

Laden Sie das Geolocation-Beispiel für Windows 10 Technical Preview herunter, und öffnen Sie die Datei Scenario1_TrackPosition.xaml. In diesem Schritt fügen Sie UI-Elemente zum Festlegen der Bewegungsgrenze hinzu.

Fügen Sie zunächst am Ende des <Grid.RowDefinitions>-Elements ein RowDefinition-Element für die Bewegungsgrenzenoberfläche hinzu, wie hier abgebildet.


<Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <!--Added for entering movement threshold-->
    <RowDefinition Height="Auto" />
</Grid.RowDefinitions>

Fügen Sie dann nach dem ScenarioOutput_Accuracy-Textblock und vor dem Ende von </Grid> die folgenden UI-Elemente hinzu.


<!--Added for entering movement threshold-->
<TextBlock TextWrapping="Wrap" Margin="0,0,10,0" Grid.Row="4" 
            Grid.Column="0" Style="{StaticResource BasicTextStyle}" 
            HorizontalAlignment="Left" VerticalAlignment="Center" 
            Text="Movement threshold (meters): " />
                
<TextBox x:Name="ScenarioIntput_MovementThreshold" 
            TextWrapping="Wrap" Grid.Row="4" Grid.Column="1" 
            HorizontalAlignment="Left" VerticalAlignment="Center" Text="3" />

Öffnen Sie als Nächstes die Datei Scenario1_TrackPosition.xaml.cs, und fügen Sie der partiellen Scenario1:Page-Klasse die privaten Klassenvariablen prevLatitude, prevLongitude und totalDistance hinzu, wie unten dargestellt. Mithilfe dieser Variablen wird die zurückgelegte Entfernung nachverfolgt.


public sealed partial class Scenario1 : Page
{
    // Proides access to location data
    private Geolocator _geolocator = null;

    // A pointer to the main page
    private MainPage _rootPage = MainPage.Current;

    // Distance tracking variables
    private double prevLatitude = -1;
    private double prevLongitude = -1;
    private double totalDistance = 0;

...
...

Schritt 2: Überprüfen, ob Positionsdienste aktiviert sind

Bevor Ihre App auf Positionsdaten zugreifen kann, muss Position auf dem Gerät aktiviert sein. Vergewissern Sie sich in der Einstellungs-App, dass die folgenden Datenschutzeinstellungen für den Standort aktiviert sind:

  • Position hat die Einstellung Ein
  • Die Einstellung Let Windows and apps you choose use your location and location history ist auf Ein festgelegt
  • Ihre App hat unter Diese Apps dürfen meinen Standort verwenden die Einstellung Ein

Hinweis  In einigen Fällen sind die Einstellungen Position und Diese Apps dürfen meinen Standort verwenden möglicherweise nicht verfügbar.

Schritt 3: Aktivieren der Positionsfunktion

Die Positionsfunktion ist im Geolocation-Beispiel bereits aktiviert. Dieser Schritt dient nur als Erinnerung für neue Apps. Um diese Funktion hinzuzufügen, doppelklicken Sie im Projektmappen-Explorer auf package.appxmanifest und wählen die Registerkarte Funktionen aus. Aktivieren Sie dann in der Liste Funktionen die Option Position. Dadurch wird der Paketmanifestdatei die Gerätefunktion Location hinzugefügt.


  <Capabilities>
    <!-- DeviceCapability elements must follow Capability elements (if present) -->
    <DeviceCapability Name="location"/>
  </Capabilities>

Schritt 4: Anfordern des Zugriffs auf die Position des Benutzers

Die Datei Scenario1_TrackPosition.xaml.cs des Geolocation-Beispiels verdeutlicht, dass es wichtig ist, mithilfe der RequestAccessAsync-Methode den Zugriff auf die Position des Benutzers anzufordern.

Wichtig  Rufen Sie RequestAccessAsync auf, bevor Sie auf die Position des Benutzers zugreifen. Zu diesem Zeitpunkt muss sich Ihre App im Vordergrund befinden, und RequestAccessAsync muss vom UI-Thread aufgerufen werden. Solange der Benutzer Ihrer App keinen Zugriff auf seine Position gewährt hat, kann Ihre App nicht auf Positionsdaten zugreifen.


using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();

Die RequestAccessAsync-Methode fordert vom Benutzer die Berechtigung für den Zugriff auf seine Position an. Der Benutzer wird nur einmal (pro App) aufgefordert. Nachdem die Berechtigung erstmalig gewährt oder verweigert wurde, fordert die Methode keine Berechtigung mehr an. Um dem Benutzer das Ändern von Positionsberechtigungen nach der Aufforderung zu erleichtern, empfehlen wir, einen Link zu den Positionseinstellungen bereitzustellen, wie weiter unten in diesem Thema beschrieben.

Schritt 5: Definieren der Bewegungsgrenze und Registrieren für Positionsupdates

Ersetzen Sie in der Datei Scenario1_TrackPosition.xaml.cs des Geolocation-Beispiels die StartTracking-Methode und StopTracking-Methode durch den Code aus dem nächsten Beispiel. Dieser neue Code verwendet die MovementThreshold-Eigenschaft, um anzugeben, wie weit sich die Position ändern muss, damit das PositionChanged-Ereignis ausgelöst wird. In diesem Fall wird der Wert für die Bewegungsgrenze aus dem in einem vorherigen Schritt hinzugefügten ScenarioIntput_MovementThreshold-Textfeld verwendet.

Eine switch-Anweisung wird mit der accessStatus-Eigenschaft verwendet. Sie wird nur aktiv, wenn der Zugriff auf die Position zulässig ist. Sofern zulässig, werden vom Code ein Geolocator-Objekt erstellt, der Nachverfolgungstyp angegeben und eine Registrierung für Positionsupdates ausgeführt.



 private async void StartTracking(object sender, RoutedEventArgs e)
{
    // Request permission to access location
    var accessStatus = await Geolocator.RequestAccessAsync();

    switch (accessStatus)
    {
        case GeolocationAccessStatus.Allowed:

            // Disable movement threshold textbox
            ScenarioIntput_MovementThreshold.IsEnabled = false;

            // Create Geolocator and define the movement threshold (in meters)
            _geolocator = new Geolocator();
            _geolocator.MovementThreshold = float.Parse(ScenarioIntput_MovementThreshold.Text);

            // Subscribe to PositionChanged event to get updated tracking positions
            _geolocator.PositionChanged += OnPositionChanged;

            // Subscribe to StatusChanged event to get updates of location status changes
            _geolocator.StatusChanged += OnStatusChanged;
                    
            _rootPage.NotifyUser("Waiting for update...", NotifyType.StatusMessage);
            LocationDisabledMessage.Visibility = Visibility.Collapsed;
            StartTrackingButton.IsEnabled = false;
            StopTrackingButton.IsEnabled = true;
            break;

        case GeolocationAccessStatus.Denied:
            _rootPage.NotifyUser("Access to location is denied.", NotifyType.ErrorMessage);
            LocationDisabledMessage.Visibility = Visibility.Visible;
            break;

        case GeolocationAccessStatus.Unspecified:
            _rootPage.NotifyUser("Unspecificed error!", NotifyType.ErrorMessage);
            LocationDisabledMessage.Visibility = Visibility.Collapsed;
            break;
    }
}


private void StopTracking(object sender, RoutedEventArgs e)
{
    _geolocator.PositionChanged -= OnPositionChanged;
    _geolocator.StatusChanged -= OnStatusChanged;
    _geolocator = null;

    StartTrackingButton.IsEnabled = true;
    StopTrackingButton.IsEnabled = false;

    // Enable movement threshold textbox
    ScenarioIntput_MovementThreshold.IsEnabled = true;

    // Clear status
    _rootPage.NotifyUser("Tracking stopped.", NotifyType.StatusMessage);
}

Schritt 6: Behandeln von Positionsupdates

Ersetzen Sie in der Datei Scenario1_TrackPosition.xaml.cs des Geolocation-Beispiels die OnPositionChanged-Methode durch den Code aus dem nächsten Beispiel. Dieser neue Code verwendet die aktuelle Position zum Berechnen der Entfernung seit dem letzten Update (updateDistance) und der Gesamtentfernung seit Beginn der Nachverfolgung (totalDistance).

Das Geolocator-Objekt löst das PositionChanged-Ereignis aus, um anzugeben, dass sich die Position des Benutzers geändert hat. Das Ereignis übergibt die entsprechende Position über die Position-Argumenteigenschaft (vom Typ Geoposition). Wie in diesem Beispiel veranschaulicht, wird die Methode nicht vom UI-Thread aufgerufen, die UI-Änderungen werden tatsächlich durch das Dispatcher-Objekt aufgerufen.


async private void OnPositionChanged(Geolocator sender, PositionChangedEventArgs e)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        double updateDistance = 0;

        // Calculate distance;
        if ((prevLatitude == -1) || (prevLongitude == -1))
        {
            updateDistance = 0;
        }
        else
        {
            updateDistance = CalculateDistance(prevLatitude, prevLongitude,
               e.Position.Coordinate.Point.Position.Latitude, 
               e.Position.Coordinate.Point.Position.Longitude);
        }

        // Update tracking
        prevLatitude = e.Position.Coordinate.Point.Position.Latitude;
        prevLongitude = e.Position.Coordinate.Point.Position.Longitude;
        totalDistance += updateDistance;

        // Update UI
        _rootPage.NotifyUser("Latest distance: " + 
            updateDistance.ToString("F2") +
            " meters,  Total distance: " +
            totalDistance.ToString("F2") +
            " meters", 
            NotifyType.StatusMessage);

        UpdateLocationData(e.Position);
    });
}

Schritt 7: Berechnen der Entfernung

Fügen Sie in der Datei Scenario1_TrackPosition.xaml.cs des Geolocation-Beispiels die im nächsten Beispiel gezeigte CalculateDistance-Methode hinzu. Diese Methode verwendet die Semiversus-Formel, um die Entfernung zwischen zwei geografischen Standorten zu berechnen.


private double CalculateDistance(double prevLat, double prevLong, double currLat, double currLong)
{
    const double degreesToRadians = (Math.PI / 180.0);
    const double earthRadius = 6371; // kilometers

    // convert latitude and longitude values to radians
    var prevRadLat = prevLat * degreesToRadians;
    var prevRadLong = prevLong * degreesToRadians;
    var currRadLat = currLat * degreesToRadians;
    var currRadLong = currLong * degreesToRadians;

    // calculate radian delta between each position.
    var radDeltaLat = currRadLat - prevRadLat;
    var radDeltaLong = currRadLong - prevRadLong;

    // calculate distance
    var expr1 = (Math.Sin(radDeltaLat / 2.0) *
                    Math.Sin(radDeltaLat / 2.0)) +

                (Math.Cos(prevRadLat) *
                    Math.Cos(currRadLat) *
                    Math.Sin(radDeltaLong / 2.0) *
                    Math.Sin(radDeltaLong / 2.0));

    var expr2 = 2.0 * Math.Atan2(Math.Sqrt(expr1),
                                    Math.Sqrt(1 - expr1));

    var distance = (earthRadius * expr2);
    return distance * 1000;  // return results as meters
}

Schritt 8: Behandeln von Änderungen an Positionsberechtigungen

Wie am Geolocation-Beispiel erkennbar, kann mithilfe von PositionStatus der aktuelle Status von Berechtigungen für Positionsdaten überprüft werden. Diese Überprüfung ist für den Fall wichtig, dass sich die Positionseinstellungen des Benutzers ändern, während Ihre App im Vordergrund ausgeführt wird. Auch hier wird die Methode nicht vom UI-Thread aufgerufen, die UI-Änderungen werden tatsächlich durch das Dispatcher-Objekt aufgerufen.



using Windows.UI.Core;
...
async private void OnStatusChanged(Geolocator sender, StatusChangedEventArgs e)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        // Show the location setting message only if status is disabled.
        LocationDisabledMessage.Visibility = Visibility.Collapsed;

        switch (e.Status)
        {
            case PositionStatus.Ready:
                // Location platform is providing valid data.
                ScenarioOutput_Status.Text = "Ready";
                _rootPage.NotifyUser("Location platform is ready.", NotifyType.StatusMessage);
                break;

            case PositionStatus.Initializing:
                // Location platform is attempting to acquire a fix. 
                ScenarioOutput_Status.Text = "Initializing";
                _rootPage.NotifyUser("Location platform is attempting to obtain a position.", NotifyType.StatusMessage);
                break;

            case PositionStatus.NoData:
                // Location platform could not obtain location data.
                ScenarioOutput_Status.Text = "No data";
                _rootPage.NotifyUser("Not able to determine the location.", NotifyType.ErrorMessage);
                break;

            case PositionStatus.Disabled:
                // The permission to access location data is denied by the user or other policies.
                ScenarioOutput_Status.Text = "Disabled";
                _rootPage.NotifyUser("Access to location is denied.", NotifyType.ErrorMessage);

                // Show message to the user to go to location settings
                LocationDisabledMessage.Visibility = Visibility.Visible;

                // Clear cached location data if any
                UpdateLocationData(null);
                break;

            case PositionStatus.NotInitialized:
                // The location platform is not initialized. This indicates that the application 
                // has not made a request for location data.
                ScenarioOutput_Status.Text = "Not initialized";
                _rootPage.NotifyUser("No request for location is made yet.", NotifyType.StatusMessage);
                break;

            case PositionStatus.NotAvailable:
                // The location platform is not available on this version of the OS.
                ScenarioOutput_Status.Text = "Not available";
                _rootPage.NotifyUser("Location is not available on this version of the OS.", NotifyType.ErrorMessage);
                break;

            default:
                ScenarioOutput_Status.Text = "Unknown";
                _rootPage.NotifyUser(string.Empty, NotifyType.StatusMessage);
                break;
        }
    });
}

Schritt 9: Unterstützen des Benutzers beim Ändern von Positionseinstellungen

Wenn Ihre App gemäß den Positionseinstellungen nicht auf die Position des Benutzers zugreifen darf, wird empfohlen, einen praktischen Link zu den Datenschutzeinstellungen für den Standort in der Einstellungs-App bereitzustellen. Im Geolocation-Beispiel wird ein Hyperlink-Steuerelement (unten abgebildet) verwendet, um zum ms-settings://privacy/location-URI zu navigieren.


        <TextBlock x:Name="LocationDisabledMessage" FontStyle="Italic" 
                   Visibility="Collapsed" Margin="0,15,0,0" TextWrapping="Wrap" >
            <Run Text="This app is not able to get location data. Go to" />
                <Hyperlink NavigateUri="ms-settings://privacy/location">
                    <Run Text="Settings" />
                </Hyperlink>
            <Run Text="to check the location privacy settings."/>

Alternativ kann Ihre App die LaunchUriAsync-Methode aufrufen, um die Einstellungs-App über den Code zu starten. Weitere Informationen finden Sie unter So wird's gemacht: Anzeigen integrierter Einstellungsseiten mit dem ms-settings-Protokoll.


using Windows.System;
...
bool result = await Launcher.LaunchUriAsync(new Uri("ms-settings://privacy/location"));

Schritt 10: Testen des neuen Codes

Bevor Sie mit den App-Tests beginnen, sollten Sie Folgendes beachten:

  • Um eine Bewegungsgrenze zum Auslösen von Positionsupdates zu verwenden, muss das Gerät physisch bewegt oder mit dem Emulator eine neue Position simuliert werden. Weitere Informationen zum Simulieren von Positionen finden Sie unter Festlegen der simulierten geografischen Position des Geräts.
  • Abhängig von der Quelle der Positionsdaten kann die Position wesentlich ungenauer als die angegebene Bewegungsgrenze sein. Eine anhand von WLAN-Daten ermittelte Position kann etwa um 30 bis 500 Meter variieren. Weitere Informationen zu Quellen für Positionsdaten finden Sie unter Windows.Devices.Geolocation.

So testen Sie den neuen Code:

  1. Klicken Sie im Menü Debuggen auf Debugging starten, um die Projektmappe zu testen.
  2. Wählen Sie Track Position, um die geänderte Seite Scenario1_TrackPosition.xaml.cs anzuzeigen.
  3. Drücken Sie Ablaufverfolgung starten, um die bewegungsbasierte Nachverfolgung zu starten.
  4. Wenn Sie das Beispiel zum ersten Mal ausführen, werden Sie gefragt, ob die App Ihre Position verwenden kann. Wählen Sie die Option Zulassen aus.
  5. Bewegen Sie Ihr Gerät (unter Berücksichtigung der Standortgenauigkeit) über die angegebene Bewegungsgrenze hinweg, und beachten Sie, wie sich der updateDistance-Wert und der totalDistance-Wert in der Benutzeroberfläche ändern.

Verwandte Themen

Geolocation-Beispiel für Windows 10 Technical Preview
Geolocation-Beispiel für Windows 8.1
Bing Karten SDK – Beispiele
Windows.Devices.Geolocation
Richtlinien für die Verwendung von sensorischen Geräten

 

 

Anzeigen:
© 2015 Microsoft