Mobile-Tutorial: Verwenden von Positionssensoren (iOS und Android)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Mobile-Tutorials: Mobile Anwendungsentwicklung (iOS und Android)


Bevor Sie mit diesem Tutorial beginnen, sollten Sie die folgenden Tutorials durcharbeiten:

Hinweis: Auf Android-Geräten müssen für TLocationSensor spezielle Berechtigungen festgelegt werden, vor allem Auf ungefähren Standort zugreifen und Auf genauen Standort zugreifen.

In diesem Tutorial sind die grundlegenden Schritte zum Lokalisieren Ihres mobilen Gerätes (anhand der geografischen Breite und Länge) und zum Verwenden der Rückwärts-Georeferenzierung für die Umwandlung dieser Daten in eine lesbare Adresse beschrieben, wie in der folgenden Abbildung dargestellt:


IOSLocationDemo.PNG

Entwerfen der Benutzeroberfläche

Diese Demo-Anwendung enthält zwei Hauptkomponenten: eine TListBox (auf der linken Seite) und einen TWebBrowser.

Hinweis: Setzen Sie, bevor Sie mit diesem Szenario fortfahren, in der Projektverwaltung die aktive Zielplattform auf iOS-Gerät oder Android. Ansonsten können Sie die TWebBrowser-Komponente nicht hinzufügen.

DesignLocationDemo.png

Ziehen Sie eine TListBox- und eine TWebBrowser-Komponente auf das Formular.

  • Setzen Sie für TListBox die Eigenschaft Align auf Left, um die linke Seite der UI für die Komponente zu reservieren. Erstellen Sie anschließend die folgenden Unterkomponenten für die ListBox:
    • Eine TListBoxHeader-Komponente mit den folgenden Unterkomponenten:
      • Eine TLabel-Komponente mit dem Text "Location Demo"
      • Eine Switch-Komponente (Switch1) zum Ein- und Ausschalten von TLocationSensor
    • Eine TListBoxGroupHeader-Komponente mit dem Text "Your Location"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemLatitude" und dem Text "Latitude"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemLongitude" und dem Text "Longitude"
    • Eine TListBoxGroupHeader-Komponente mit dem Text "Current Address"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemAdminArea" und dem Text "AdminArea"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemCountryCode" und dem Text "CountryCode"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemCountryName" und dem Text "CountryName"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemFeatureName" und dem Text "FeatureName"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemLocality" und dem Text "Locality"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemPostalCode" und dem Text "PostalCode"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemSubAdminArea" und dem Text "SubAdminArea"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemSubLocality" und dem Text "SubLocality"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemSubThoroughfare" und dem Text "SubThoroughfare"
    • Eine TListBoxItem-Komponente mit dem Namen "ListBoxItemThoroughfare" und dem Text "Thoroughfare"
  • Eine TWebBrowser-Komponente (WebBrowser1) zum Anzeigen der Webseite (Google Maps). Setzen Sie die Eigenschaft Align auf Client.

Wählen Sie nach dem Erstellen dieser Komponenten alle TListBoxItem-Elemente und in der Eigenschaft StyleLookup den Eintrag listboxitemleftdetail aus. Damit legen Sie fest, dass in TListBoxItem eine Beschriftung und detaillierter Text angezeigt werden kann.

Der Positionssensor

Der Positionssensor ist in der Komponente TLocationSensor gekapselt.

TLocationSensor löst ein OnLocationChanged-Ereignis aus, wenn das Gerät eine Bewegung erkennt. Die Empfindlichkeit von TLocationSensor können Sie mit den Eigenschaften Distance und Accuracy einstellen.

  • Die Eigenschaft Distance gibt die Entfernung (in Meter) an, die das Gerät mindestens bewegt werden muss, damit der Positionssensor eine neue Ortung des Geräts vornimmt und neue Positionsdaten zurückgibt. Wenn Sie Distance beispielsweise auf "10" setzen, löst TLocationSensor ein OnLocationChanged-Ereignis aus, wenn Sie sich 10 Meter von der aktuellen Position weg bewegen.
  • Die Eigenschaft Accuracy repräsentiert die Genauigkeit (in Meter), mit der der Sensor das Gerät geografisch ortet, relativ zu dem geografischen Punkt, an dem sich das Gerät tatsächlich befindet.
Tipp: Sie sollten die geringste Genauigkeit, die für Ihre Anwendung ausreichend ist, angeben; je höher die Genauigkeit ist, desto größer ist der Zeitbedarf und der Energieverbrauch, den der Sensor zur Bestimmung der Position benötigt. Empfohlene Werte: Distance=0; Accuracy=0.

Abrufen der Positionsinformationen (geografische Breite und Länge) von der LocationSensor-Komponente

Die TLocationSensor-Komponente muss vor der Verwendung aktiviert werden. Sie können TLocationSensor auf Basis Ihrer Eingabe, wie z. B. einer TSwitch-Komponente, oder anderer Anwendungsereignisse ein- und ausschalten.

  1. Ziehen Sie aus der Tool-Palette eine TLocationSensor-Komponente auf das Formular.
  2. Wählen Sie im Formular-Designer die Komponente TSwitch aus.
  3. Doppelklicken Sie im Objektinspektor auf der Registerkarte Ereignisse auf das Ereignis OnSwitch.
  4. Fügen Sie der OnSwitch-Ereignisbehandlungsroutine den folgenden Code hinzu:
Delphi:
procedure TForm1.Switch1Switch(Sender: TObject);
begin
  LocationSensor1.Active := Switch1.IsChecked;
end;
C++:
void __fastcall TForm1::Switch1Switch(TObject *Sender)
{
        LocationSensor1->Active = Switch1->IsChecked;
}

Wie bereits weiter oben erwähnt, löst TLocationSensor ein OnLocationChanged-Ereignis aus, wenn das mobile Gerät bewegt wird. Sie können die aktuelle Position (geografische Breite und Länge) anzeigen, indem Sie in einer Ereignisbehandlungsroutine Parameter verwenden.

  1. Wählen Sie im Formular-Designer die Komponente TLocationSensor aus.
  2. Doppelklicken Sie im Objektinspektor auf der Registerkarte Ereignisse auf das Ereignis OnLocationChange.
  3. Fügen Sie der OnLocationChange-Ereignisbehandlungsroutine den folgenden Code hinzu:
Delphi:
procedure TForm1.LocationSensor1LocationChanged(Sender: TObject;
  const OldLocation, NewLocation: TLocationCoord2D);
var
  LDecSeparator: String;
begin
  LDecSeparator := FormatSettings.DecimalSeparator;
  FormatSettings.DecimalSeparator := '.';
  // Show current location
  ListBoxItemLatitude.ItemData.Detail  := Format('%2.6f', [NewLocation.Latitude]);
  ListBoxItemLongitude.ItemData.Detail := Format('%2.6f', [NewLocation.Longitude]);
end;
C++:
void __fastcall TForm1::LocationSensor1LocationChanged(TObject *Sender, const TLocationCoord2D &OldLocation,
                  const TLocationCoord2D &NewLocation)
{
        char LDecSeparator = FormatSettings.DecimalSeparator;
        FormatSettings.DecimalSeparator = '.';
        // Show current location
        ListBoxItemLatitude->ItemData->Detail = ListBoxItemLatitude->ItemData->Detail.sprintf(L"%2.6f", NewLocation.Latitude);
        ListBoxItemLongitude->ItemData->Detail = ListBoxItemLongitude->ItemData->Detail.sprintf(L"%2.6f", NewLocation.Longitude);
}

Anzeigen der aktuellen Position mit Google Maps über eine TWebBrowser-Komponente

Wie im Mobile-Tutorial: Verwenden von Webbrowser-Komponenten (iOS und Android) erläutert, kapselt die TWebBrowser-Komponente einen Webbrowser für mobile Plattformen.

Sie können Google Maps aus der TWebBrowser-Komponente mit den folgenden URL-Parametern aufrufen:

 https://maps.google.com/maps?q=(Latitude-value),(Longitude-value)

Diesen URL können Sie der zuvor erstellten OnLocationChanged-Ereignisbehandlungsroutine wie folgt hinzufügen:

Delphi:
procedure TForm1.LocationSensor1LocationChanged(Sender: TObject;
  const OldLocation, NewLocation: TLocationCoord2D);
var
  URLString: String;
begin
  // code for previous step goes here

  // Show Map using Google Maps
  URLString := Format(
    'https://maps.google.com/maps?q=%s,%s',
      [Format('%2.6f', [NewLocation.Latitude]), Format('%2.6f', [NewLocation.Longitude])]);
  WebBrowser1.Navigate(URLString);
end;
C++:
void __fastcall TForm1::LocationSensor1LocationChanged(TObject *Sender, const TLocationCoord2D &OldLocation,
                  const TLocationCoord2D &NewLocation)
{
        // code for previous step goes here

        // Show Map using Google Maps
        String LLongitude = FloatToStr(NewLocation.Longitude, FormatSettings);
        String URLString = "";
        URLString = URLString.sprintf(L"https://maps.google.com/maps?q=%2.6f,%2.6f",
                NewLocation.Latitude, NewLocation.Longitude);

        FormatSettings.DecimalSeparator = LDecSeparator;
        WebBrowser1->Navigate(URLString);
}

Verwenden der Rückwärts-Georeferenzierung

TGeocoder ist ein Objekt, das den Georeferenzierungsdienst (oder den Rückwärts-Georeferenzierungsdienst) kapselt.

Georeferenzierung ist der Vorgang des Umwandelns von geografischen Daten, wie Adresse und Postleitzahl, in geografische Koordinaten. Rückwärts-Georeferenzierung ist der Vorgang des Umwandelns von geografischen Koordinaten in andere geografische Daten, wie eine Adresse.

In diesem Beispiel wird mit TGeocoder die Position (geografische Breite und Länge) per "Rückwärts-Georeferenzierung" in lesbare Adressdaten umgewandelt.

Dafür wird für TGeocoder der folgende grundlegende Aktionsablauf durchgeführt:

  1. Erstellen einer Instanz von TGeocoder.
  2. Definieren eines OnGeocodeReverse-Ereignisses, damit das Ereignis später empfangen werden kann.
  3. Festlegen von Daten für die Ausführung der "Rückwärts-Georeferenzierung".
  4. TGeocoder greift auf den Dienst im Netzwerk zu, um die Adressinformationen aufzulösen.
  5. TGeocoder löst ein OnGeocodeReverse-Ereignis aus.
  6. Die iOS-App empfängt die Adressinformationen über die Parameter im OnGeocodeReverse-Ereignis und aktualisiert die Benutzeroberfläche.
Hinweis:
Weil TGeocoder keine Komponente (sondern nur eine Klasse) ist, müssen Sie diese Schritte im Code festlegen (Sie können auf dem Formular weder eine Komponente ablegen, noch im Objektinspektor eine Ereignisbehandlungsroutine zuweisen).

Zuerst definieren Sie im private-Abschnitt des Formulars ein neues "FGeocoder"-Feld. Sie können auch eine "OnGeocodeReverseEvent"-Prozedur wie im folgenden Codefragment definieren.

Delphi:
type
  TForm1 = class(TForm)
    // IDE defines visible (or non-visual) components here automatically
  private
    { Private declarations }
    FGeocoder: TGeocoder;
    procedure OnGeocodeReverseEvent(const Address: TCivicAddress);
  public
    { Public declarations }
  end;

C++:

Hinweis: Fügen Sie dieses Codefragment in die Header-Datei (.h) ein.
class TForm1 : public TForm
{
        // IDE defines visible (or non-visual) components here automatically
private:        // User declarations
        TGeocoder *FGeocoder;
        void __fastcall OnGeocodeReverseEvent(TCivicAddress* const Address);
public:         // User declarations
        __fastcall TForm1(TComponent* Owner);
};


Jetzt können Sie eine Instanz von TGeocoder erstellen und sie mit dem folgenden Delphi- oder C++-Code mit Daten einrichten.

TGeocoder.Current gibt den Typ der Klasse an, die den Georeferenzierungsdienst implementiert. Der Code in TGeocoder.Current.Create ruft den Konstruktor (Create) für den angegebenen Typ auf und speichert ihn im Feld FGeocoder. Sie sollten auch eine Ereignisbehandlungsroutine festlegen, die ausgelöst wird, wenn TGeocoder die Rückwärts-Georeferenzierung ausgeführt hat. Weisen Sie OnGeocodeReverseEvent (im vorherigen Schritt definiert) zu FGeocoder.OnGeocodeReverse zu.

Wenn Sie erfolgreich eine Instanz von TGeocoder erstellt haben und TGeocoder nicht ausgeführt wird, rufen Sie TGeocoder.GeocodeReverse mit den Positionsinformationen auf. Wenn TGeocoder Daten empfängt, wird das Ereignis OnGeocodeReverseEvent ausgelöst.

Delphi:
procedure TForm1.LocationSensor1LocationChanged(Sender: TObject;
  const OldLocation, NewLocation: TLocationCoord2D);
begin
  // code for previous steps goes here
try
    // Setup an instance of TGeocoder
    if not Assigned(FGeocoder) then
    begin
      if Assigned(TGeocoder.Current) then
        FGeocoder := TGeocoder.Current.Create;
      if Assigned(FGeocoder) then
        FGeocoder.OnGeocodeReverse := OnGeocodeReverseEvent;
    end;

    // Translate location to address
    if Assigned(FGeocoder) and not FGeocoder.Geocoding then
      FGeocoder.GeocodeReverse(NewLocation);
  except
    ListBoxGroupHeader1.Text := 'Geocoder service error';
  end;
end;

C++:

void __fastcall TForm1::LocationSensor1LocationChanged(TObject *Sender, const TLocationCoord2D &OldLocation,
                  const TLocationCoord2D &NewLocation)
{
        // code for previous steps goes here

                // Setup an instance of TGeocoder
        try {
        if (FGeocoder == NULL) {
            if (TGeocoder::Current != NULL) {
                FGeocoder = (TGeocoder*)new TGeocoderClass(TGeocoder::Current);
            }
            if (FGeocoder != NULL) {
                FGeocoder->OnGeocodeReverse = OnGeocodeReverseEvent;
            }
        }
        // Translate location to address

        if ((FGeocoder != NULL) && (!(FGeocoder->Geocoding()))) {
            FGeocoder->GeocodeReverse(NewLocation);
        }
    }
    catch (...) {
        ListBoxGroupHeader1->Text = "Geocoder service error";
    }

}

Anzeigen einer lesbaren Adresse in der ListBox-Komponente

Wie weiter oben beschrieben, wird ein OnGeocodeReverseEvent-Ereignis ausgelöst, nachdem die Rückwärts-Georeferenzierung abgeschlossen ist.

Als Nächstes weisen Sie im Adressparameter TCivicAddress Eigenschaften zu, um lesbare Adressdaten in den Feldern des Listenfeldes anzuzeigen:

Delphi:
procedure TForm1.OnGeocodeReverseEvent(const Address: TCivicAddress);
begin
  ListBoxItemAdminArea.ItemData.Detail       := Address.AdminArea;
  ListBoxItemCountryCode.ItemData.Detail     := Address.CountryCode;
  ListBoxItemCountryName.ItemData.Detail     := Address.CountryName;
  ListBoxItemFeatureName.ItemData.Detail     := Address.FeatureName;
  ListBoxItemLocality.ItemData.Detail        := Address.Locality;
  ListBoxItemPostalCode.ItemData.Detail      := Address.PostalCode;
  ListBoxItemSubAdminArea.ItemData.Detail    := Address.SubAdminArea;
  ListBoxItemSubLocality.ItemData.Detail     := Address.SubLocality;
  ListBoxItemSubThoroughfare.ItemData.Detail := Address.SubThoroughfare;
  ListBoxItemThoroughfare.ItemData.Detail    := Address.Thoroughfare;
end;

C++:

void __fastcall TForm1::OnGeocodeReverseEvent(TCivicAddress* const Address)
{
          if (Address != NULL){
                ListBoxItemAdminArea->ItemData->Detail       = Address->AdminArea;
                ListBoxItemCountryCode->ItemData->Detail     = Address->CountryCode;
                ListBoxItemCountryName->ItemData->Detail     = Address->CountryName;
                ListBoxItemFeatureName->ItemData->Detail     = Address->FeatureName;
                ListBoxItemLocality->ItemData->Detail        = Address->Locality;
                ListBoxItemPostalCode->ItemData->Detail      = Address->PostalCode;
                ListBoxItemSubAdminArea->ItemData->Detail    = Address->SubAdminArea;
                ListBoxItemSubLocality->ItemData->Detail     = Address->SubLocality;
                ListBoxItemSubThoroughfare->ItemData->Detail = Address->SubThoroughfare;
                ListBoxItemThoroughfare->ItemData->Detail    = Address->Thoroughfare;
        }
}

Beschreiben, warum die Anwendung den Standort des Benutzers benötigt

Vor der Bereitstellung der endgültigen Anwendung sollten Sie Projekt > Optionen > Versionsinformationen mit iOS-Gerät als Zielplattform wählen und die Werte von NSLocationAlwaysUsageDescription und NSLocationWhenInUseUsageDescription mit einer Meldung aktualisieren, die erklärt, warum die Anwendung den Benutzer zur Angabe seines Standorts auffordert. Diese Meldung wird angezeigt, wenn die Anwendung den Benutzer auffordert, iOS zur Übermittlung des iOS-Gerätestandorts an die Anwendung zu autorisieren.

Siehe auch

Beispiele