Tutoriel mobile : Utilisation de détecteurs d'emplacement (iOS et Android)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Tutoriels mobiles : Développement d'applications mobiles (iOS et Android)


Avant de commencer ce tutoriel, il est recommandé de lire et suivre les tutoriels suivants :

Remarque : Sur les périphériques Android, TLocationSensor requiert que des permissions d'utilisation spécifiques soient définies, notamment les permissions Accéder à un emplacement approximatif et Accéder à un emplacement précis.

Ce tutoriel décrit les étapes élémentaires pour localiser votre périphérique mobile (via la latitude et la longitude) et pour utiliser le Géocodage inversé afin de convertir une adresse lisible, comme sur l'image suivante :


IOSLocationDemo.PNG

Conception de l'interface utilisateur

Cette application de démonstration est conçue avec deux principaux composants : un TListBox (à gauche) et un TWebBrowser.

Remarque : Avant de poursuivre ce scénario, dans le Gestionnaire de projets, définissez la plate-forme cible active sur Périphérique iOS ou Android. Sinon, vous ne pourrez pas ajouter le composant TWebBrowser.

DesignLocationDemo.png

Déposez un composant TListBox et un composant TWebBrowser sur la fiche.

  • Dans le TListBox, définissez la propriété Align sur Left pour réserver le côté gauche de l'interface utilisateur. Puis créez les sous-composants suivants sous la zone de liste :
    • Un composant TListBoxHeader avec les sous-composants suivants :
      • Un composant TLabel avec le texte "Location Demo"
      • Un composant TSwitch (Switch1) pour sélectionner l'activation/désactivation de TLocationSensor
    • Un TListBoxGroupHeader avec le texte "Your Location"
    • Un TListBoxItem ayant le nom "ListBoxItemLatitude" et le texte "Latitude"
    • Un TListBoxItem ayant le nom "ListBoxItemLongitude" et le texte "Longitude"
    • Un TListBoxGroupHeader ayant le texte "Current Address"
    • Un TListBoxItem ayant le nom "ListBoxItemAdminArea" et le texte "AdminArea"
    • Un TListBoxItem ayant le nom "ListBoxItemCountryCode" et le texte "CountryCode"
    • Un TListBoxItem ayant le nom "ListBoxItemCountryName" et le texte "CountryName"
    • Un TListBoxItem ayant le nom "ListBoxItemFeatureName" et le texte "FeatureName"
    • Un TListBoxItem ayant le nom "ListBoxItemLocality" et le texte "Locality"
    • Un TListBoxItem ayant le nom "ListBoxItemPostalCode" et le texte "PostalCode"
    • Un TListBoxItem ayant le nom "ListBoxItemSubAdminArea" et le texte "SubAdminArea"
    • Un TListBoxItem ayant le nom "ListBoxItemSubLocality" et le texte "SubLocality"
    • Un TListBoxItem ayant le nom "ListBoxItemSubThoroughfare" et le texte "SubThoroughfare"
    • Un TListBoxItem ayant le nom "ListBoxItemThoroughfare" et le texte "Thoroughfare"
  • Un composant TWebBrowser (WebBrowser1) pour afficher la page Web (Google Maps). Définissez la propriété Align sur Client.

Après avoir créé ces composants, sélectionnez tous les éléments TListBoxItem et sélectionnez ensuite listboxitemleftdetail dans la propriété StyleLookup. TListBoxItem peut ainsi afficher à la fois un libellé et du texte détaillé.

Le détecteur d'emplacement

Le détecteur d'emplacement est encapsulé par le composant TLocationSensor.

TLocationSensor déclenche un événement OnLocationChanged lorsque le périphérique détecte un mouvement. Vous pouvez régler la sensibilité de TLocationSensor en utilisant les propriétés Distance et Accuracy.

  • La propriété Distance spécifie la distance minimale (en mètres) à laquelle le périphérique doit se déplacer pour que le détecteur d'emplacement localise à nouveau le périphérique et renvoie les nouvelles informations relatives à l'emplacement. Par exemple, si vous définissez Distance sur "10", TLocationSensor déclenche un événement OnLocationChanged lorsque vous effectuez un déplacement de "10 mètres".
  • La propriété Accuracy représente le niveau de précision (en mètres) auquel le détecteur localise géographiquement le périphérique par rapport au point géographique sur lequel il est situé.
Conseil : Spécifiez la précision la plus basse pour votre application ; plus la précision est élevée, plus le détecteur a besoin de temps et d'énergie pour déterminer l'emplacement. Valeurs recommandées : Distance=0 ; Accuracy=0.

Lecture des informations d'emplacement (Latitude, Longitude) à partir du composant LocationSensor

Le composant TLocationSensor doit d'abord être activé pour être utilisé. Vous pouvez activer/désactiver TLocationSensor en fonction de votre saisie, comme un composant TSwitch ou d'autres événements Application.

  1. Placez un composant TLocationSensor à partir de la palette d'outils.
  2. Sur le Concepteur de fiches, sélectionnez le composant TSwitch.
  3. Dans l'onglet Evénements de l'inspecteur d'objets, double-cliquez sur l'événement OnSwitch.
  4. Ajoutez le code suivant au gestionnaire d'événement OnSwitch :
Delphi :
procedure TForm1.Switch1Switch(Sender: TObject);
begin
  LocationSensor1.Active := Switch1.IsChecked;
end;
C++ :
void __fastcall TForm1::Switch1Switch(TObject *Sender)
{
        LocationSensor1->Active = Switch1->IsChecked;
}

Comme expliqué précédemment, TLocationSensor déclenche un événement OnLocationChanged lorsque vous déplacez le périphérique mobile. Vous pouvez afficher l'emplacement en cours (Latitude et Longitude) en utilisant des paramètres avec un gestionnaire d'événement.

  1. Sur le Concepteur de fiches, sélectionnez le TLocationSensor.
  2. Dans l'onglet Evénements de l'inspecteur d'objets, double-cliquez sur l'événement OnLocationChange.
  3. Ajoutez le code suivant au gestionnaire d'événement OnLocationChange :
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);
}

Affichage de l'emplacement en cours en utilisant Google Maps via un composant TWebBrowser

Comme expliqué dans le Tutoriel mobile : Utilisation du composant Navigateur Web (iOS et Android, le composant TWebBrowser encapsule un navigateur Web pour les plates-formes mobiles.

Vous pouvez appeler Google Maps depuis le composant TWebBrowser en utilisant les paramètres d'URL suivants :

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

Vous pouvez alors ajouter cette URL au gestionnaire d'événement que vous venez de créer, OnLocationChanged, en procédant comme suit :

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);
}

Utilisation du géocodage inversé

TGeocoder est un objet qui encapsule le service de géocodage (ou de Géocodage inversé).

Le Géocodage est le processus qui consiste à transformer des données géographiques, comme l'adresse et le code postal, en coordonnées géographiques. Le Géocodage inversé est le processus qui consiste à transformer des coordonnées géographiques en données géographiques comme l'adresse.

Dans ce cas, vous devez utiliser TGeocoder pour effectuer le "géocodage inversé" de votre emplacement (en Latitude et Longitude) en informations d'adresse lisibles.

Voici la séquence d'actions élémentaires relatives à TGeocoder :

  1. Créer une instance de TGeocoder.
  2. Définir un événement OnGeocodeReverse afin que vous puissiez par la suite recevoir l'événement.
  3. Définir les données pour exécuter le "Géocodage inversé".
  4. TGeocoder accède au service sur le réseau lui permettant de résoudre les informations d'adresse.
  5. TGeocoder déclenche un événement OnGeocodeReverse.
  6. Votre app iOS reçoit les informations d'adresse via le paramètre de l'événement OnGeocodeReverse et met à jour l'interface utilisateur.
Remarque : Comme TGeocoder n'est pas un composant (c'est simplement une classe), vous devez définir ces étapes via votre code (il n'est pas possible de déposer un composant ou d'assigner un gestionnaire d'événement via l'inspecteur d'objets).

Commencez par définir un nouveau champ "FGeocoder dans la section private de la fiche. Vous pouvez aussi définir une procédure "OnGeocodeReverseEvent" comme dans les extraits de code suivants.

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++ :

Remarque : Placez cet extrait de code dans le fichier d'en-tête (.h).
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);
};


Vous pouvez maintenant créer une instance de TGeocoder et la configurer avec des données en utilisant le code Delphi ou C++ suivant.

TGeocoder.Current donne le type de classe qui implémente le service de géocodage. Le code dans "TGeocoder.Current.Create" appelle le constructeur (Create) pour le type spécifié et l'enregistre dans le champ FGeocoder. Vous devez aussi spécifier un gestionnaire d'événement qui sera déclenché lorsque TGeocoder terminera le géocodage inversé. Assignez OnGeocodeReverseEvent (que vous venez de définir lors de l'étape précédente) à FGeocoder.OnGeocodeReverse.

Pour finir, si vous avez réussi à créer une instance de TGeocoder et que TGeocoder n'est pas exécuté, appelez TGeocoder.GeocodeReverse avec les informations d'emplacement. Lorsque TGeocoder reçoit des données, l'événement OnGeocodeReverseEvent est déclenché.

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";
    }

}

Affichage d'une adresse lisible dans le composant Zone de liste

Comme décrit précédemment, lorsque le géocodage inversé est terminé, un événement OnGeocodeReverseEvent est déclenché.

Assignez ensuite les propriétés dans le paramètre d'adresse TCivicAddress de façon à afficher des informations d'adresse lisibles dans les champs de la zone de liste :

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;
        }
}

Description de la raison pour laquelle votre application demande l'emplacement de l'utilisateur

Avant de déployer votre application finale, vous devez sélectionner Projet > Options > Informations de version en spécifiant un périphérique iOS comme cible, puis mettre à jour les valeurs de NSLocationAlwaysUsageDescription et NSLocationWhenInUseUsageDescription avec un message qui explique la raison pour laquelle votre application demande l'emplacement de l'utilisateur. Vos utilisateurs voient ce message lorsque votre application leur demande d'autoriser iOS à fournir l'emplacement de leur périphérique iOS.

Voir aussi

Exemples