Language: HTML | XAML

So wird’s gemacht: Anpassen der Entfernung für Standortupdates (XAML)

Applies to Windows and Windows Phone

Bei einigen Apps sind Standortaktualisierungen nur erforderlich, wenn der Benutzer eine große Entfernung zurückgelegt hat. In diesem Thema erfahren Sie, wie Sie eine App erstellen, mit der Benutzer die Entfernung zwischen Standortaktualisierungen anpassen können.

Die Entfernung zwischen Standortaktualisierungen wird als Bewegungsgrenze bezeichnet. Sie entspricht der Positionsänderung, die für ein Standortaktualisierungsereignis mindestens erforderlich ist. Bei Implementierung einer Bewegungsgrenze können Sie eine App erstellen, die nur lokale Informationen wie Nachrichten oder Wetter bereitstellt und für die keine Standortaktualisierungen erforderlich sind, solange der Benutzer sich am selben Ort befindet.

Der Code dieser App aktualisiert jedes Mal dann eine Tabelle, wenn ein Standortaktualisierungsereignis eintritt. Die Aktualisierungen erfolgen durch das Hinzufügen einer Zeile mit den neuen Koordinaten und der vom Benutzer seit der letzten Aktualisierung zurückgelegten Entfernung. Die zurückgelegte Entfernung wird mit der Semiversus-Formel berechnet.

Wird eine Bewegungsgrenze in das Eingabefeld eingegeben, werden Sie feststellen, dass die Entfernung, die bei jeder Ereignisauslösung zurückgelegt wurde, unterhalb der Bewegungsgrenze liegt.

Voraussetzungen

Sie sollten mit XAML, Visual C# und Ereignissen vertraut sein.

Der Zugriff auf die Position muss auf dem verwendeten Gerät aktiviert sein.

Anweisungen

Schritt 1: Öffnen von Microsoft Visual Studio

Öffnen Sie eine Instanz von Visual Studio.

Schritt 2: Erstellen eines neuen Projekts

Erstellen Sie ein neues Projekt, und wählen Sie aus den Projekttypen unter Visual C# > Store den Typ Anwendung aus.

Schritt 3: Aktivieren der Positionsfunktion

Öffnen Sie die Datei Package.appxmanifest Ihres Projekts, zeigen Sie die Registerkarte Capabilities an, und aktivieren Sie das Kontrollkästchen für die Funktion Standort.

Schritt 4: Ersetzen des XAML-Codes

Öffnen Sie die Datei BlankPage.xaml.cs des Projekts, und ersetzen Sie den vorhandenen Code durch den folgenden Code.


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Devices.Geolocation;
using Windows.UI.Core;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace App1
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private Geolocator geo = null;
        private CoreDispatcher _cd;
        private double prevLatitude = -1;
        private double prevLongitude = -1;
        private double totalDistance = 0;

        public MainPage()
        {
            this.InitializeComponent();
            _cd = Window.Current.CoreWindow.Dispatcher;
        }
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            if (geo == null)
            {
                geo = new Geolocator();
            }
            if (geo != null)
            {
                geo.MovementThreshold = float.Parse(tbThreshold.Text);

                geo.PositionChanged += new TypedEventHandler<Geolocator,
                    PositionChangedEventArgs>(geo_PositionChanged);
                geo.StatusChanged += new TypedEventHandler<Geolocator,
                    StatusChangedEventArgs>(geo_StatusChanged);

                tbThreshold.IsEnabled = false;
                TextBox1.Text = "Tracking Started " +
                                "(Time, Latitude, Longitude, Distance)\n";
            }
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            if (geo != null)
            {
                geo.PositionChanged -= new TypedEventHandler<Geolocator,
                    PositionChangedEventArgs>(geo_PositionChanged);
                geo.StatusChanged -= new TypedEventHandler<Geolocator,
                    StatusChangedEventArgs>(geo_StatusChanged);
                TextBox1.Text += "\nTracking Stopped.\n" +
                                 "Total Distance recorded: " +
                                 totalDistance.ToString("F2") + " m\n";
                tbThreshold.IsEnabled = true;
            }
        }

        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
        }

        async private void geo_PositionChanged(Geolocator sender, PositionChangedEventArgs e)
        {
            await _cd.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                Geoposition pos = e.Position;
                double updateDistance = 0;

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

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

                // display the results.
                TextBox1.Text += "Position Update: " +
                                 pos.Coordinate.Timestamp.ToString("T") + ", " +
                                 pos.Coordinate.Point.Position.Latitude.ToString("F3") + ", " +
                                 pos.Coordinate.Point.Position.Longitude.ToString("F3") + ", " +
                                 updateDistance.ToString("F2") + " m\n";
            });
        }

        async private void geo_StatusChanged(Geolocator sender, StatusChangedEventArgs args)
        {
            var newStatus = args.Status;
            var strStatus = "";

            switch (newStatus)
            {
                case PositionStatus.Ready:
                    strStatus = "Location is available.";
                    break;
                case PositionStatus.Initializing:
                    strStatus = "Geolocation service is initializing.";
                    break;
                case PositionStatus.NoData:
                    strStatus = "Location service data is not available.";
                    break;

                case PositionStatus.Disabled:
                    strStatus = "Location services are disabled. Use the " +
                                "Settings charm to enable them.";
                    break;

                case PositionStatus.NotInitialized:
                    strStatus = "Location status is not initialized because " +
                                "the app has not yet requested location data.";
                    break;

                case PositionStatus.NotAvailable:
                    strStatus = "Location services are not supported on your system.";
                    break;

                default:
                    strStatus = "Unknown PositionStatus value (" +
                                newStatus.ToString() + ").";
                    break;
            }

            await _cd.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                TextBox1.Text += strStatus + "\n";
            });

        }
    }
}



Sie müssen den Namespace im vorhergehenden Codeausschnitt durch den Namen ersetzen, den Sie für Ihr Projekt angegeben haben. Wenn Sie z. B. ein Projekt mit dem Namen GeolocationSample erstellt haben, ersetzen Sie namespace App1 durch namespace GeolocationSample.

Schritt 5: Ersetzen des XAML-Codes

Öffnen Sie die Datei MainPage.xaml, und kopieren Sie den folgenden XML-Code in die Datei (ersetzen Sie den ursprünglichen Inhalt).


<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBox x:Name="tbThreshold" HorizontalAlignment="Left" Text="3" 
            TextWrapping="Wrap" VerticalAlignment="Top" Margin="339,31,0,0" 
            ToolTipService.ToolTip="Movement threshold (meters)" 
            TextAlignment="Center"/>
        <Button Content="Start Tracking" HorizontalAlignment="Left" Width="155"  
            Margin="10,30,0,0" VerticalAlignment="Top" Click="Button_Click_1"/>
        <Button Content="Stop Tracking" HorizontalAlignment="Left" Width="155" 
            Margin="170,30,0,0" VerticalAlignment="Top" Click="Button_Click_2"/>
        <ScrollViewer HorizontalAlignment="Left" Height="256" Width="390" 
            Margin="10,255,0,156" VerticalScrollBarVisibility="Auto">
            <TextBox x:Name="TextBox1" TextWrapping="Wrap" 
               Text="&lt;Click Start Tracking to begin.&gt;" Width="366"/>
        </ScrollViewer>

    </Grid>
</Page>


Sie müssen den ersten Teil des Klassennamens im vorhergehenden Codeausschnitt durch den Namespace Ihrer App ersetzen. Wenn Sie z. B. ein Projekt mit dem Namen GeolocationSample erstellt haben, ersetzen Sie x:Class="App1.MainPage" durch x:Class="GeolocationSample.MainPage". Außerdem sollten Sie xmlns:local="using:App1" durch xmlns:local="using:GeolocationSample" ersetzen.

Schritt 6: Erstellen der App

Klicken Sie auf Erstellen > Projektmappe erstellen, um das Projekt zu erstellen.

Schritt 7: Testen der App

  1. Klicken Sie im Menü Debuggen auf Debugging starten, um die Projektmappe zu testen.
  2. 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.
  3. Klicken Sie auf die Schaltfläche Get Location, um die aktuelle Position abzurufen.

Hinweis  Wenn keine Standortdaten angezeigt werden, überprüfen Sie Folgendes:

  • Vergewissern Sie sich, dass Sie Zugriff auf Standortdaten haben, indem Sie im Projektmappen-Explorer die Datei package.appxmanifest öffnen und die Option Standort auf der Registerkarte Capabilities überprüfen.
  • Wenn die Standortdienste von einem Administrator deaktiviert wurden, hat Ihre App keinen Zugriff auf den Benutzerstandort. Öffnen Sie in der Systemsteuerung den Bereich "Standorteinstellungen ändern", und überprüfen Sie, ob Plattform für Windows-Position aktivieren aktiviert ist.
  • In Windows Phone kann der Benutzer die Position in der App "Einstellungen" deaktivieren. Navigieren Sie zur App "Einstellungen", wählen Sie Ortung aus, und stellen Sie sicher, dass der Schalter für Ortungsdienste aktiviert ist.

Anmerkungen

Hinweis  Die Windows-Positionssuche bestimmt den Standort anhand von WiFi-Informationen. Ist kein WiFi verfügbar, wird stattdessen die IP-Adresse herangezogen. Wenn der Computer nicht WiFi-fähig ist, erhalten Sie möglicherweise keinerlei Standortupdateereignisse, da die IP-Adressdaten nur gelegentlich aktualisiert werden.

Verwandte Themen

Geolocation-Beispiel
Windows.Devices.Geolocation
Richtlinien für standortabhängige Anwendungen

 

 

Anzeigen:
© 2014 Microsoft