Données de localisation

La détection de la position est l'une des fonctionnalités propres aux applications mobiles. Les utilisateurs emportent leurs appareils mobiles partout où ils vont. Aussi, l'ajout d'une fonctionnalité de détection de la position à votre application leur offre une expérience plus contextuelle.

Exemples de code

Le dépôt ApiDemos sur GitHub inclut des exemples qui montrent comment utiliser la localisation sur une carte :

Java

Kotlin

Utiliser les données de localisation

Les données de localisation disponibles pour un appareil Android incluent la position actuelle de l'appareil, calculée à l'aide d'une combinaison de technologies, la direction et le moyen de déplacement, et si l'appareil s'est déplacé dans une limite géographique prédéfinie (zone de géorepérage). En fonction des besoins de votre application, vous pouvez choisir d'utiliser les données de localisation de plusieurs façons :

  • Le calque Ma position permet d'afficher facilement la position d'un appareil sur la carte. Il ne fournit pas de données.
  • L'API de localisation des services Google Play est recommandée pour toutes les requêtes de données de localisation par programmatique.
  • L'interface LocationSource vous permet de recourir à un fournisseur de localisation personnalisé.

Autorisations de géolocalisation

Si votre application a besoin de géolocaliser l'utilisateur, vous devez demander l'autorisation en ajoutant l'autorisation de géolocalisation Android appropriée à votre application.

Android propose deux autorisations de géolocalisation : ACCESS_COARSE_LOCATION et ACCESS_FINE_LOCATION. L'autorisation que vous choisissez détermine la précision de la position renvoyée par l'API. Vous ne devez demander qu'une seule autorisation de géolocalisation Android, selon le niveau de précision requis :

  • android.permission.ACCESS_COARSE_LOCATION : autorise l'API à utiliser le Wi-Fi ou les données du réseau de téléphonie mobile (ou les deux) pour déterminer la position de l'appareil. L'API renvoie le lieu avec une précision équivalente à environ un pâté de maisons.
  • android.permission.ACCESS_FINE_LOCATION : permet à l'API de déterminer une position aussi précise que possible à partir des fournisseurs de géolocalisation disponibles, y compris le GPS (Global Positioning System), le Wi-Fi et les données des réseaux de téléphonie mobile.

Ajouter les autorisations au fichier manifeste de l'application

Ajoutez une des autorisations suivantes en tant qu'enfant de l'élément <manifest> dans votre fichier manifeste Android. Soit l'autorisation de géolocalisation approximative :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp" >
  ...
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  ...
</manifest>

Soit l'autorisation de géolocalisation précise :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp" >
  ...
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  ...
</manifest>

Demander des autorisations d'exécution

Android 6.0 (Marshmallow) introduit un nouveau modèle de gestion des autorisations, qui permet de rationaliser le processus pour les utilisateurs lors de l'installation et de la mise à niveau des applications. Si votre application cible une API niveau 23 ou version ultérieure, vous pouvez utiliser le nouveau modèle d'autorisations.

Si votre application prend en charge le nouveau modèle d'autorisations et que l'appareil exécute Android 6.0 (Marshmallow) ou une version ultérieure, l'utilisateur n'a pas besoin d'accorder une autorisation lors de l'installation ou de la mise à niveau de l'application. L'application doit vérifier qu'il dispose de l'autorisation nécessaire au moment de l'exécution, et demander l'autorisation si ce n'est pas le cas. Le système affiche une boîte de dialogue pour demander l'autorisation à l'utilisateur.

Pour une meilleure expérience utilisateur, il est important de demander l'autorisation dans le contexte. Si la géolocalisation est essentielle au bon fonctionnement de votre application, vous devez alors demander l'autorisation de géolocalisation au démarrage de l'application. Un bon moyen de procéder est d'afficher un écran de bienvenue ou un assistant qui explique aux utilisateurs pourquoi cette autorisation est requise.

Si l'application nécessite l'autorisation pour certaines de ses fonctionnalités uniquement, vous devez alors demander l'autorisation de géolocalisation au moment où l'application effectue l'action qui requiert l'autorisation en question.

L'application doit gérer facilement le cas où l'utilisateur ne donne pas son autorisation. Par exemple, si l'autorisation est nécessaire pour une fonctionnalité particulière, l'application peut la désactiver. Si l'autorisation est essentielle au fonctionnement de l'application, celle-ci peut désactiver toutes ses fonctionnalités et informer l'utilisateur qu'il est nécessaire qu'il donne son autorisation.

L'exemple de code suivant vérifie l'autorisation à l'aide de la bibliothèque Support avant d'activer le calque "Ma position" : Il permet ensuite de gérer le résultat de la demande d'autorisation en ajoutant le ActivityCompat.OnRequestPermissionsResultCallback à partir de la bibliothèque Support :

Java

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.example.mapdemo;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener;
import com.google.android.gms.maps.GoogleMap.OnMyLocationClickListener;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.widget.Toast;

/**
 * This demo shows how GMS Location can be used to check for changes to the users location.  The
 * "My Location" button uses GMS Location to set the blue dot representing the users location.
 * Permission for {@link android.Manifest.permission#ACCESS_FINE_LOCATION} is requested at run
 * time. If the permission has not been granted, the Activity is finished with an error message.
 */
public class MyLocationDemoActivity extends AppCompatActivity
        implements
        OnMyLocationButtonClickListener,
        OnMyLocationClickListener,
        OnMapReadyCallback,
        ActivityCompat.OnRequestPermissionsResultCallback {

    /**
     * Request code for location permission request.
     *
     * @see #onRequestPermissionsResult(int, String[], int[])
     */
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;

    /**
     * Flag indicating whether a requested permission has been denied after returning in
     * {@link #onRequestPermissionsResult(int, String[], int[])}.
     */
    private boolean permissionDenied = false;

    private GoogleMap map;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_location_demo);

        SupportMapFragment mapFragment =
                (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        map = googleMap;
        map.setOnMyLocationButtonClickListener(this);
        map.setOnMyLocationClickListener(this);
        enableMyLocation();
    }

    /**
     * Enables the My Location layer if the fine location permission has been granted.
     */
    private void enableMyLocation() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            if (map != null) {
                map.setMyLocationEnabled(true);
            }
        } else {
            // Permission to access the location is missing. Show rationale and request permission
            PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
                Manifest.permission.ACCESS_FINE_LOCATION, true);
        }
    }

    @Override
    public boolean onMyLocationButtonClick() {
        Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT).show();
        // Return false so that we don't consume the event and the default behavior still occurs
        // (the camera animates to the user's current position).
        return false;
    }

    @Override
    public void onMyLocationClick(@NonNull Location location) {
        Toast.makeText(this, "Current location:\n" + location, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode != LOCATION_PERMISSION_REQUEST_CODE) {
            return;
        }

        if (PermissionUtils.isPermissionGranted(permissions, grantResults, Manifest.permission.ACCESS_FINE_LOCATION)) {
            // Enable the my location layer if the permission has been granted.
            enableMyLocation();
        } else {
            // Permission was denied. Display an error message
            // Display the missing permission error dialog when the fragments resume.
            permissionDenied = true;
        }
    }

    @Override
    protected void onResumeFragments() {
        super.onResumeFragments();
        if (permissionDenied) {
            // Permission was not granted, display error dialog.
            showMissingPermissionError();
            permissionDenied = false;
        }
    }

    /**
     * Displays a dialog with error message explaining that the location permission is missing.
     */
    private void showMissingPermissionError() {
        PermissionUtils.PermissionDeniedDialog
                .newInstance(true).show(getSupportFragmentManager(), "dialog");
    }

}

Kotlin

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.example.kotlindemos

import android.Manifest
import android.content.pm.PackageManager
import android.location.Location
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback
import androidx.core.content.ContextCompat
import com.example.kotlindemos.PermissionUtils.PermissionDeniedDialog.Companion.newInstance
import com.example.kotlindemos.PermissionUtils.isPermissionGranted
import com.example.kotlindemos.PermissionUtils.requestPermission
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener
import com.google.android.gms.maps.GoogleMap.OnMyLocationClickListener
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment

/**
 * This demo shows how GMS Location can be used to check for changes to the users location.  The
 * "My Location" button uses GMS Location to set the blue dot representing the users location.
 * Permission for [Manifest.permission.ACCESS_FINE_LOCATION] is requested at run
 * time. If the permission has not been granted, the Activity is finished with an error message.
 */
class MyLocationDemoActivity : AppCompatActivity(), OnMyLocationButtonClickListener,
    OnMyLocationClickListener, OnMapReadyCallback, OnRequestPermissionsResultCallback {
    /**
     * Flag indicating whether a requested permission has been denied after returning in
     * [.onRequestPermissionsResult].
     */
    private var permissionDenied = false
    private lateinit var map: GoogleMap
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.my_location_demo)
        val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
        mapFragment?.getMapAsync(this)
    }

    override fun onMapReady(googleMap: GoogleMap?) {
        map = googleMap ?: return
        googleMap.setOnMyLocationButtonClickListener(this)
        googleMap.setOnMyLocationClickListener(this)
        enableMyLocation()
    }

    /**
     * Enables the My Location layer if the fine location permission has been granted.
     */
    private fun enableMyLocation() {
        if (!::map.isInitialized) return
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {
            map.isMyLocationEnabled = true
        } else {
            // Permission to access the location is missing. Show rationale and request permission
            requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
                Manifest.permission.ACCESS_FINE_LOCATION, true
            )
        }
    }

    override fun onMyLocationButtonClick(): Boolean {
        Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT).show()
        // Return false so that we don't consume the event and the default behavior still occurs
        // (the camera animates to the user's current position).
        return false
    }

    override fun onMyLocationClick(location: Location) {
        Toast.makeText(this, "Current location:\n$location", Toast.LENGTH_LONG).show()
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        if (requestCode != LOCATION_PERMISSION_REQUEST_CODE) {
            return
        }
        if (isPermissionGranted(permissions, grantResults, Manifest.permission.ACCESS_FINE_LOCATION)) {
            // Enable the my location layer if the permission has been granted.
            enableMyLocation()
        } else {
            // Permission was denied. Display an error message
            // Display the missing permission error dialog when the fragments resume.
            permissionDenied = true
        }
    }

    override fun onResumeFragments() {
        super.onResumeFragments()
        if (permissionDenied) {
            // Permission was not granted, display error dialog.
            showMissingPermissionError()
            permissionDenied = false
        }
    }

    /**
     * Displays a dialog with error message explaining that the location permission is missing.
     */
    private fun showMissingPermissionError() {
        newInstance(true).show(supportFragmentManager, "dialog")
    }

    companion object {
        /**
         * Request code for location permission request.
         *
         * @see .onRequestPermissionsResult
         */
        private const val LOCATION_PERMISSION_REQUEST_CODE = 1
    }
}

Calque "Ma position"

Vous pouvez utiliser le calque et le bouton Ma position pour permettre à l'utilisateur de connaître sa position actuelle sur la carte. Appelez mMap.setMyLocationEnabled() pour activer le calque "Ma position" sur la carte.

L'exemple suivant illustre une utilisation simple du calque "Ma position" :

Java

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.maps.example;

import android.annotation.SuppressLint;
import android.location.Location;
import android.os.Bundle;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;

class MyLocationLayerActivity extends AppCompatActivity
    implements GoogleMap.OnMyLocationButtonClickListener,
    GoogleMap.OnMyLocationClickListener,
    OnMapReadyCallback {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_location);

        SupportMapFragment mapFragment =
            (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @SuppressLint("MissingPermission")
    @Override
    public void onMapReady(GoogleMap map) {
        // TODO: Before enabling the My Location layer, you must request
        // location permission from the user. This sample does not include
        // a request for location permission.
        map.setMyLocationEnabled(true);
        map.setOnMyLocationButtonClickListener(this);
        map.setOnMyLocationClickListener(this);
    }

    @Override
    public void onMyLocationClick(@NonNull Location location) {
        Toast.makeText(this, "Current location:\n" + location, Toast.LENGTH_LONG)
            .show();
    }

    @Override
    public boolean onMyLocationButtonClick() {
        Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT)
            .show();
        // Return false so that we don't consume the event and the default behavior still occurs
        // (the camera animates to the user's current position).
        return false;
    }
}

      

Kotlin

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.maps.example.kotlin

import android.annotation.SuppressLint
import android.location.Location
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener
import com.google.android.gms.maps.GoogleMap.OnMyLocationClickListener
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.maps.example.R

internal class MyLocationLayerActivity : AppCompatActivity(),
    OnMyLocationButtonClickListener,
    OnMyLocationClickListener,
    OnMapReadyCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_my_location)
        val mapFragment =
            supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

    @SuppressLint("MissingPermission")
    override fun onMapReady(map: GoogleMap) {
        // TODO: Before enabling the My Location layer, you must request
        // location permission from the user. This sample does not include
        // a request for location permission.
        map.isMyLocationEnabled = true
        map.setOnMyLocationButtonClickListener(this)
        map.setOnMyLocationClickListener(this)
    }

    override fun onMyLocationClick(location: Location) {
        Toast.makeText(this, "Current location:\n$location", Toast.LENGTH_LONG)
            .show()
    }

    override fun onMyLocationButtonClick(): Boolean {
        Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT)
            .show()
        // Return false so that we don't consume the event and the default behavior still occurs
        // (the camera animates to the user's current position).
        return false
    }
}

      

Lorsque le calque "Ma position" est activé, le bouton "Ma position" apparaît dans l'angle supérieur droit de la carte. Dès qu'un utilisateur clique sur ce bouton, la caméra centre la carte sur la position actuelle de l'appareil, si celle-ci est connue. Cette position est indiquée sur la carte par un petit point bleu si l'appareil est fixe, ou sous forme de chevron si l'appareil est en mouvement.

La capture d'écran suivante montre le bouton Ma position en haut à droite et le point bleu Ma position au centre de la carte :

Vous pouvez empêcher l'affichage du bouton Ma position en appelant UiSettings.setMyLocationButtonEnabled(false).

Votre application peut répondre aux événements suivants :

Selon nos conditions d'utilisation

Protégez la confidentialité des utilisateurs,
tenez-les informés

Informez toujours les utilisateurs de la façon dont vous allez utiliser leurs données, et veillez à ce qu'il ne soit pas possible d'identifier des utilisateurs individuels. Obtenez l'autorisation de l'utilisateur avant d'utiliser sa position et offrez-lui la possibilité de révoquer son consentement à tout moment.

En savoir plus

API de localisation des services Google Play

L'API de localisation des services Google Play est la méthode recommandée pour ajouter la détection de la position à votre application Android. Ses fonctionnalités vous permettent d'effectuer les opérations suivantes :

  • Déterminer la position géographique de l'appareil
  • Écouter les changements de localisation
  • Déterminer le mode de transport, si l'appareil est en mouvement
  • Créer et surveiller des régions géographiques prédéfinies, appelées zones de géorepérage

Grâce aux API de localisation, vous pouvez créer facilement des applications de géolocalisation économes en énergie. Comme le SDK Maps pour Android, l'API de localisation est intégrée au SDK des services Google Play. Pour plus d'informations sur l'API Location, consultez la formation Android Making Your App Location Aware ou la documentation de référence de l'API Location. Des exemples de code sont inclus dans le SDK des services Google Play.