Recherche…


Introduction

Les API d'emplacement Android sont utilisées dans une grande variété d'applications à des fins différentes, telles que la localisation de l'utilisateur, la notification d'un utilisateur ayant quitté un espace général (Geofencing) et l'interprétation des activités des utilisateurs (marche, course, conduite, etc.).

Cependant, les API d'emplacement Android ne sont pas le seul moyen d'acquérir l'emplacement de l'utilisateur. Les exemples suivants expliquent comment utiliser LocationManager d'Android et d'autres bibliothèques d'emplacement courantes.

Remarques

Pour créer des applications prenant en compte l'emplacement dans Android, il existe deux chemins:

LocationManager

Avantages

  • Contrôle plus granulaire
  • Disponible dans tous les appareils
  • Partie du framework Android

Les inconvénients

  • La perte de batterie est un problème, si elle n'est pas gérée correctement
  • Nécessite une logique pour changer de fournisseur de localisation, si le périphérique ne parvient pas à trouver un emplacement (par exemple, mauvais GPS dans un bâtiment)

Caractéristiques

  • Auditeur NMEA
  • Écouteur d'état GPS
  • Écoutez les changements de statut du fournisseur (par exemple, le GPS est désactivé par l'utilisateur)
  • Liste de fournisseurs pour choisir la source de localisation de

Fournisseurs

GPS

  • Autorisations requises:
  • Précision: 10m - 100m
  • Exigences de puissance: ÉLEVÉ
  • Disponibilité: Dans le monde entier (avec une vue dégagée du ciel)
  • NOTES :
    • Les mises à jour de localisation interviennent généralement une fois par seconde, mais dans les situations où le GPS n’a pas été utilisé depuis un certain temps et où A-GPS n’est pas disponible, il faut plusieurs minutes pour recevoir un emplacement.
    • Dans les cas où une vue dégagée du ciel est obstruée, les points GPS ne se regrouperont pas très bien (les points d'emplacement "sautent") et la précision peut induire en erreur dans certaines zones en raison de l'effet " Urban Canyon ".

Réseau

  • Autorisations requises:
  • Précision: 100m - 1000m +
  • Exigences de puissance: BAS - MOYEN
  • Disponibilité: À portée de la tour cellulaire ou du signal wifi
  • REMARQUES:
    • Les mises à jour de localisation se produisent moins fréquemment que le GPS
    • Les mises à jour d'emplacement ne sont généralement pas bien groupées (les points d'emplacement "sautent") et la précision peut varier en fonction du nombre de facteurs différents (nombre de signaux wifi, puissance du signal, type de tour cellulaire, etc.)

Passif

  • Autorisations requises:
  • Précision: 10m - 1000m +
  • Exigences d'alimentation: AUCUN
  • Disponibilité: Uniquement lorsqu'une autre application reçoit un emplacement de GPS ou de réseau
  • REMARQUES:
    • Ne comptez pas sur cela pour vous donner des mises à jour continues. Cela permet d'écouter passivement les autres applications qui effectuent des requêtes de localisation et de revenir à ces emplacements.
    • Ne renvoie pas les points générés par FusedLocationProviderApi, mais uniquement les points d'emplacement sous-jacents utilisés pour les générer.

FusedLocationProviderApi

Avantages

  • Offre moins de vidange de la batterie "out of the box"
  • Gère mal le GPS
  • Obtient des mises à jour plus régulièrement

Les inconvénients

  • Moins de contrôle granulaire sur le GPS
  • Peut ne pas être disponible sur tous les appareils ou dans certains pays
  • Nécessite une dépendance de bibliothèque tierce

Caractéristiques

  • Utilisation bien gérée des fournisseurs de localisation pour des économies de pâte optimales
  • Génère généralement des points plus précis que le fournisseur d'emplacement réseau
  • Mises à jour plus fréquentes de la bibliothèque, permettant une plus grande amélioration
  • Pas besoin de spécifier le type de fournisseur à utiliser

Niveaux de priorité d'emplacementRequest

PRIORITY_HIGH_ACCURACY

  • Autorisations requises:
  • Précision: 10m - 100m
  • Exigences de puissance: ÉLEVÉ
  • Disponibilité: partout où les services Google Play sont disponibles.
  • REMARQUES:
    • Si ACCESS_FINE_LOCATION n'est pas utilisé, cela n'utilisera pas le GPS pour générer des mises à jour de localisation, mais trouvera toujours un point assez précis dans les bonnes conditions.
    • Si ACCESS_FINE_LOCATION est utilisé, il peut utiliser ou non le GPS pour générer des points de localisation, en fonction de la précision avec laquelle il peut actuellement suivre le périphérique en fonction des conditions environnementales.
    • Bien que cela puisse rapporter des mises à jour de localisation plus précises que les autres réglages, il reste sujet à l’effet « Urban Canyon ».

PRIORITY_BALANCED_POWER_ACCURACY

  • Autorisations requises:
  • Précision: 100m - 1000m +
  • Exigences d'alimentation: MOYEN
  • Disponibilité: partout où les services Google Play sont disponibles.
  • REMARQUES:
    • Mêmes notes que PRIORITY_HIGH_ACCURACY
    • Bien que cela soit peu probable, ce paramètre peut toujours utiliser le GPS pour générer un emplacement.

PRIORITY_LOW_POWER

  • Autorisations requises:
  • Précision: 100m - 1000m +
  • Exigences de puissance: BAS
  • Disponibilité: partout où les services Google Play sont disponibles.
  • REMARQUES:
    • N'utilise probablement pas le GPS, mais pas encore testé.
    • Les mises à jour ne sont généralement pas très précises
    • Utilisé généralement pour détecter les changements importants de l'emplacement

PRIORITY_NO_POWER

  • Autorisations requises:
  • Précision: 10m - 1000m +
  • Exigences d'alimentation: AUCUN
  • Disponibilité: partout où les services Google Play sont disponibles.
  • REMARQUES:
    • Fonctionne presque identique à LocationManager PASSIVE_PROVIDER
    • PASSIVE_PROVIDER mises à jour des services Google Play lorsqu'elles sont reçues, où PASSIVE_PROVIDER signale les mises à jour d'emplacement sous-jacentes utilisées

Dépannage

OnLocationChanged () jamais appelé

Étant donné que cela semble être un problème courant lors de l’obtention d’emplacement Android, je vais mettre en place une liste de vérification rapide des correctifs courants:


  1. Vérifiez votre manifeste!

    L'un des problèmes les plus courants est que les autorisations appropriées n'ont jamais été données. Si vous utilisez le GPS (avec ou sans réseau), utilisez <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> , sinon utilisez <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> . FusedLocationApi de Google requiert ACCESS_FINE_LOCATION .


  1. (Pour Android 6+) Vérifiez les autorisations d'exécution !

    Recherchez et demandez des autorisations! Si vous ne recevez jamais d'autorisations, vous vous retrouverez avec des accidents, ou pire (si vous attrapez toutes les exceptions), vous vous retrouverez sans aucune indication! Peu importe que l'utilisateur vous accorde l'autorisation au début de l'application, vérifiez toujours si vous disposez des autorisations pour tous les appels. L'utilisateur peut facilement accéder à leurs paramètres et les révoquer.


  1. Vérifiez votre code!

    Êtes-vous sûr de passer le bon auditeur? Avez-vous ajouté ce BroadcastReceiver ou IntentService à votre manifeste? PendingIntent.getService() -vous PendingIntent.getService() dans une classe BroadcastReceiver ou getBroadcast() dans une classe IntentService ? Êtes-vous sûr de ne pas désinscrire votre auditeur ailleurs dans votre code immédiatement après avoir demandé?


  1. Vérifiez les paramètres de l'appareil!

    De toute évidence, assurez-vous que les services de localisation sont activés.

    entrer la description de l'image ici

    Si vous utilisez les services réseau, avez-vous activé "Numérisation toujours disponible"? Votre mode de localisation est-il réglé sur "Meilleur" ("Haute précision") ou "Economie de batterie" ("Réseau uniquement")?

    entrer la description de l'image ici

    Si vous utilisez le GPS, avez-vous activé "Best" ("Haute précision") ou "Device only" en mode de localisation?

    entrer la description de l'image ici


  1. Vérifiez votre code!

    Oui, c'est ici deux fois. Avez-vous essayé d'utiliser un LocationListener au lieu d'un PendingIntent , ou vice-versa, pour vous assurer que vous avez implémenté LocationManager correctement? Êtes-vous sûr que la demande de localisation n'est pas supprimée dans une partie du cycle de vie de l'activité ou du service que vous ne vous attendiez pas?


  1. Vérifiez votre environnement!

    Êtes-vous en train de tester le GPS au premier étage d'un immeuble au milieu de San Francisco? Êtes-vous en train de tester des emplacements de réseau au milieu de nulle part? Travaillez-vous dans un bunker secret souterrain sans tous les signaux radio, en vous demandant pourquoi votre appareil ne trouve pas sa place? Vérifiez toujours votre environnement lorsque vous tentez de résoudre les problèmes de localisation!


Il pourrait y avoir beaucoup d'autres raisons moins évidentes pour lesquelles l'emplacement ne fonctionne pas, mais avant de rechercher ces corrections ésotériques, parcourez simplement cette liste de contrôle rapide.

API de localisation fusionnée

Exemple d'utilisation de l'activité w / LocationRequest

/*
 * This example is useful if you only want to receive updates in this 
 * activity only, and have no use for location anywhere else.
 */
public class LocationActivity extends AppCompatActivity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

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

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mLocationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
                .setInterval(2000) //At least once every 2 seconds
                .setFastestInterval(1000); //At most once a second
    }

    @Override
    protected void onStart(){
        super.onStart();
        mGoogleApiClient.connect();
    }
    
    @Override
    protected void onResume(){
        super.onResume();
        //Permission check for Android 6.0+
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if(mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            }
        }
    }
    
    @Override
    protected void onPause(){
        super.onPause();
        //Permission check for Android 6.0+
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if(mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            }
        }
    }
    
    @Override
    protected void onStop(){
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    }

    @Override
    public void onLocationChanged(Location location) {
        //Handle your location update code here
    }
}

Exemple d'utilisation du service w / PendingIntent et BroadcastReceiver

ExempleActivité

Lecture recommandée: LocalBroadcastManager

/*
 * This example is useful if you have many different classes that should be 
 * receiving location updates, but want more granular control over which ones
 * listen to the updates.
 * 
 * For example, this activity will stop getting updates when it is not visible, but a database
 * class with a registered local receiver will continue to receive updates, until "stopUpdates()" is called here.
 *
 */
public class ExampleActivity extends AppCompatActivity {

    private InternalLocationReceiver mInternalLocationReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        
        //Create internal receiver object in this method only.
        mInternalLocationReceiver = new InternalLocationReceiver(this);
    }

    @Override
    protected void onResume(){
        super.onResume();
        
        //Register to receive updates in activity only when activity is visible
        LocalBroadcastManager.getInstance(this).registerReceiver(mInternalLocationReceiver, new IntentFilter("googleLocation"));
    }

    @Override
    protected void onPause(){
        super.onPause();
        
        //Unregister to stop receiving updates in activity when it is not visible.
        //NOTE: You will still receive updates even if this activity is killed.
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mInternalLocationReceiver);
    }

    //Helper method to get updates
    private void requestUpdates(){
        startService(new Intent(this, LocationService.class).putExtra("request", true));
    }

    //Helper method to stop updates
    private void stopUpdates(){
        startService(new Intent(this, LocationService.class).putExtra("remove", true));
    }

    /*
     * Internal receiver used to get location updates for this activity.
     * 
     * This receiver and any receiver registered with LocalBroadcastManager does
     * not need to be registered in the Manifest.
     *
     */
    private static class InternalLocationReceiver extends BroadcastReceiver{

        private ExampleActivity mActivity;

        InternalLocationReceiver(ExampleActivity activity){
            mActivity = activity;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            final ExampleActivity activity = mActivity;
            if(activity != null) {
                LocationResult result = intent.getParcelableExtra("result");
                //Handle location update here
            }
        }
    }
}

Service de localisation

NOTE: N'oubliez pas d'inscrire ce service dans le manifeste!

public class LocationService extends Service implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    @Override
    public void onCreate(){
        super.onCreate();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mLocationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
                .setInterval(2000) //At least once every 2 seconds
                .setFastestInterval(1000); //At most once a second
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        super.onStartCommand(intent, flags, startId);
        //Permission check for Android 6.0+
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if (intent.getBooleanExtra("request", false)) {
                if (mGoogleApiClient.isConnected()) {
                    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
                } else {
                    mGoogleApiClient.connect();
                }
            }
            else if(intent.getBooleanExtra("remove", false)){
                stopSelf();
            }
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        if(mGoogleApiClient.isConnected()){
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, getPendingIntent());
            mGoogleApiClient.disconnect();
        }
    }
    
    private PendingIntent getPendingIntent(){
        
        //Example for IntentService
        //return PendingIntent.getService(this, 0, new Intent(this, **YOUR_INTENT_SERVICE_CLASS_HERE**), PendingIntent.FLAG_UPDATE_CURRENT);
        
        //Example for BroadcastReceiver
        return PendingIntent.getBroadcast(this, 0, new Intent(this, LocationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        //Permission check for Android 6.0+
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

EmplacementReceiver

REMARQUE: N'oubliez pas d'enregistrer ce récepteur dans le manifeste!

public class LocationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if(LocationResult.hasResult(intent)){
            LocationResult locationResult = LocationResult.extractResult(intent);
            LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("googleLocation").putExtra("result", locationResult));
        }
    }
}

Demande de mises à jour d'emplacement à l'aide de LocationManager

Comme toujours, vous devez vous assurer que vous disposez des autorisations requises.

public class MainActivity extends AppCompatActivity implements LocationListener{

    private LocationManager mLocationManager = null;

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

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    }


    @Override
    protected void onResume() {
        super.onResume();

        try {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        }
        catch(SecurityException e){
            // The app doesn't have the correct permissions
        }
    }


    @Override
    protected void onPause() {
        try{
            mLocationManager.removeUpdates(this);
        }
        catch (SecurityException e){
            // The app doesn't have the correct permissions
        }

        super.onPause();
    }




    @Override
    public void onLocationChanged(Location location) {
        // We received a location update!
        Log.i("onLocationChanged", location.toString());
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

Demande de mises à jour d'emplacement sur un thread distinct à l'aide de LocationManager

Comme toujours, vous devez vous assurer que vous disposez des autorisations requises.

public class MainActivity extends AppCompatActivity implements LocationListener{

    private LocationManager mLocationManager = null;
    HandlerThread mLocationHandlerThread = null;
    Looper mLocationHandlerLooper = null;


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

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mLocationHandlerThread = new HandlerThread("locationHandlerThread");
    }


    @Override
    protected void onResume() {
        super.onResume();

        mLocationHandlerThread.start();
        mLocationHandlerLooper = mLocationHandlerThread.getLooper();

        try {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this, mLocationHandlerLooper);
        }
        catch(SecurityException e){
            // The app doesn't have the correct permissions
        }
    }


    @Override
    protected void onPause() {
        try{
            mLocationManager.removeUpdates(this);
        }
        catch (SecurityException e){
            // The app doesn't have the correct permissions
        }

        mLocationHandlerLooper = null;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
            mLocationHandlerThread.quitSafely();
        else
            mLocationHandlerThread.quit();

        mLocationHandlerThread = null;


        super.onPause();
    }




    @Override
    public void onLocationChanged(Location location) {
        // We received a location update on a separate thread!
        Log.i("onLocationChanged", location.toString());

        // You can verify which thread you're on by something like this:
        // Log.d("Which thread?", Thread.currentThread() == Looper.getMainLooper().getThread() ? "UI Thread" : "New thread");
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

Enregistrez geofence

J'ai créé la classe singleton GeoFenceObserversationService .

GeoFenceObserversationService.java :

public class GeoFenceObserversationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {

    protected static final String TAG = "GeoFenceObserversationService";
    protected GoogleApiClient mGoogleApiClient;
    protected ArrayList<Geofence> mGeofenceList;
    private boolean mGeofencesAdded;
    private SharedPreferences mSharedPreferences;
    private static GeoFenceObserversationService mInstant;
    public static GeoFenceObserversationService getInstant(){
        return mInstant;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstant = this;
        mGeofenceList = new ArrayList<Geofence>();
        mSharedPreferences = getSharedPreferences(AppConstants.SHARED_PREFERENCES_NAME, MODE_PRIVATE);
        mGeofencesAdded = mSharedPreferences.getBoolean(AppConstants.GEOFENCES_ADDED_KEY, false);

        buildGoogleApiClient();
    }


    @Override
    public void onDestroy() {
        mGoogleApiClient.disconnect();
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    protected void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle connectionHint) {
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
    }

    @Override
    public void onConnectionSuspended(int cause) {

    }

    private GeofencingRequest getGeofencingRequest() {

        GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
        builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
        builder.addGeofences(mGeofenceList);
        return builder.build();
    }


    public void addGeofences() {
            if (!mGoogleApiClient.isConnected()) {
                Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
                return;
            }

        populateGeofenceList();
        if(!mGeofenceList.isEmpty()){
            try {
                LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent()).setResultCallback(this);
            } catch (SecurityException securityException) {
                securityException.printStackTrace();
            }
        }

        }

    public void removeGeofences() {
        if (!mGoogleApiClient.isConnected()) {
            Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
            return;
        }
        try {
            LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient,getGeofencePendingIntent()).setResultCallback(this);
        } catch (SecurityException securityException) {
            securityException.printStackTrace();
        }
    }


    public void onResult(Status status) {

        if (status.isSuccess()) {
            mGeofencesAdded = !mGeofencesAdded;
            SharedPreferences.Editor editor = mSharedPreferences.edit();
            editor.putBoolean(AppConstants.GEOFENCES_ADDED_KEY, mGeofencesAdded);
            editor.apply();
        } else {
            String errorMessage = AppConstants.getErrorString(this,status.getStatusCode());
            Log.i("Geofence", errorMessage);
        }
    }

    private PendingIntent getGeofencePendingIntent() {
        Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
        return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private void populateGeofenceList() {
        mGeofenceList.clear();
        List<GeoFencingResponce> geoFenceList = getGeofencesList;
        if(geoFenceList!=null&&!geoFenceList.isEmpty()){
            for (GeoFencingResponce obj : geoFenceList){
                mGeofenceList.add(obj.getGeofence());
                Log.i(TAG,"Registered Geofences : " + obj.Id+"-"+obj.Name+"-"+obj.Lattitude+"-"+obj.Longitude);
            }
        }
    }
}

AppConstant :

   public static final String SHARED_PREFERENCES_NAME = PACKAGE_NAME + ".SHARED_PREFERENCES_NAME";
    public static final String GEOFENCES_ADDED_KEY = PACKAGE_NAME + ".GEOFENCES_ADDED_KEY";
    public static final String DETECTED_GEOFENCES = "detected_geofences";
    public static final String DETECTED_BEACONS = "detected_beacons";

    public static String getErrorString(Context context, int errorCode) {
        Resources mResources = context.getResources();
        switch (errorCode) {
            case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
                return mResources.getString(R.string.geofence_not_available);
            case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
                return mResources.getString(R.string.geofence_too_many_geofences);
            case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
                return mResources.getString(R.string.geofence_too_many_pending_intents);
            default:
                return mResources.getString(R.string.unknown_geofence_error);
        }
    }

Où j'ai commencé le service? De la classe d'application

  • startService(new Intent(getApplicationContext(),GeoFenceObserversationService.class));

Comment j'ai enregistré Geofences?

  • GeoFenceObserversationService.getInstant().addGeofences();

Obtenir l'adresse de l'emplacement à l'aide de Geocoder

Après avoir obtenu l'objet Location de FusedAPI , vous pouvez facilement acquérir des informations d' Address partir de cet objet.

private Address getCountryInfo(Location location) {
    Address address = null;
    Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
    String errorMessage;
    List<Address> addresses = null;
    try {
        addresses = geocoder.getFromLocation(
                location.getLatitude(),
                location.getLongitude(),
                // In this sample, get just a single address.
                1);
    } catch (IOException ioException) {
        // Catch network or other I/O problems.
        errorMessage = "IOException>>" + ioException.getMessage();
    } catch (IllegalArgumentException illegalArgumentException) {
        // Catch invalid latitude or longitude values.
        errorMessage = "IllegalArgumentException>>" + illegalArgumentException.getMessage();
    }
    if (addresses != null && !addresses.isEmpty()) {
        address = addresses.get(0);
    }
    return country;
}

Obtenir des mises à jour de localisation dans un BroadcastReceiver

Commencez par créer une classe BroadcastReceiver pour gérer les mises à jour d’emplacement entrantes:

public class LocationReceiver extends BroadcastReceiver implements Constants {

    @Override
     public void onReceive(Context context, Intent intent) {

        if (LocationResult.hasResult(intent)) {
            LocationResult locationResult = LocationResult.extractResult(intent);
            Location location = locationResult.getLastLocation();
            if (location != null) {
                // Do something with your location
            } else {
                Log.d(LocationReceiver.class.getSimpleName(), "*** location object is null ***");
            }
        }
    }
}

Ensuite, lorsque vous vous connectez à GoogleApiClient dans le rappel onConnected:

@Override
public void onConnected(Bundle connectionHint) {
    Intent backgroundIntent = new Intent(this, LocationReceiver.class);
    mBackgroundPendingIntent = backgroundPendingIntent.getBroadcast(getApplicationContext(), LOCATION_REUEST_CODE, backgroundIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    mFusedLocationProviderApi.requestLocationUpdates(mLocationClient, mLocationRequest, backgroundPendingIntent);
}

N'oubliez pas de supprimer l'intention de mise à jour d'emplacement dans le rappel de cycle de vie approprié:

@Override
public void onDestroy() {
    if (servicesAvailable && mLocationClient != null) {
        if (mLocationClient.isConnected()) {
            fusedLocationProviderApi.removeLocationUpdates(mLocationClient, backgroundPendingIntent);
            // Destroy the current location client
            mLocationClient = null;
        } else {
            mLocationClient.unregisterConnectionCallbacks(this);
            mLocationClient = null;
        }
    }
    super.onDestroy();
}


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow