web-dev-qa-db-fra.com

API de localisation la plus précise d'Android

Pour fonctionner, mon application nécessite une API de localisation. J'ai l'intention d'utiliser la plateforme Mapbox pour personnaliser son design (puisque Google Maps ne fournit pas ce niveau de personnalisation, en ce qui me concerne).

La documentation indique que nous devons utiliser l'API Google Play lors de la création d'applications de localisation:

Les API de localisation des services Google Play sont préférées aux API de localisation du framework Android (Android.location)) pour ajouter la connaissance de la localisation à votre application. Si vous utilisez actuellement la Android, vous êtes fortement encouragé à passer aux API de localisation des services Google Play dès que possible.

Ma question est: l'API Google Play est-elle l'API la plus efficace en termes de précision GPS? Ou dois-je utiliser la méthode LocationManager et LocationListener pour le faire?

J'ai besoin de précision. Lequel devrais-je utiliser? Merci.

13
AndroidDev

Dans Android il existe également trois types de localisation:

  1. GPS_PROVIDER
  2. FOURNISSEUR DE RÉSEAU
  3. PASSIVE_PROVIDER

Donc, selon mon expérience de codage, j'ai appris que si vous utilisez:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, new MyLocationListener());

vous obtiendrez une précision jusqu'à 14+ décimales.

Mais si vous utilisez leur fusion comme ceci:

LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, my_google_listener);

vous obtiendrez une précision jusqu'à 6 à 7 décimales. essayez-le !!! référence

Mais notez quelques choses ici, le fournisseur de GPS prend du temps pour récupérer la position tandis que Google Location est beaucoup plus rapide car il obtient les données de l'appel d'API vers sa base de données de serveur Google.

Le GPS fonctionne hors ligne tandis que le fournisseur Google obtient l'emplacement via des données mobiles ou wifi.

11
Dharvik shah

FusedLocationProviderApi est déconseillé. Vous devez utiliser FusedLocationProviderClient et vous devez ajouter ACCESS_FINE_LOCATION autorisation, pas ACCESS_COARSE_LOCATION pour obtenir l'emplacement le plus précis.

Et lisez l'article this pour comprendre pourquoi FusedLocationProviderClient est la meilleure solution.

1
Levon Petrosyan

Vous devez utiliser LocationManager pour plus de précision. Vous pouvez également utiliser cette classe.

//GPSTracker.Java
import Android.app.AlertDialog;
import Android.app.Service;
import Android.content.Context;
import Android.content.DialogInterface;
import Android.content.Intent;
import Android.location.Location;
import Android.location.LocationListener;
import Android.location.LocationManager;
import Android.os.Bundle;
import Android.os.IBinder;
import Android.provider.Settings;
import Android.util.Log;

public class GPSTracker extends Service implements LocationListener {

private final Context mContext;

// flag for GPS status
boolean isGPSEnabled = false;

// flag for network status
boolean isNetworkEnabled = false;

// flag for GPS status
boolean canGetLocation = false;

Location location; // location
double latitude; // latitude
double longitude; // longitude
float bearing; // bearing

// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

// Declaring a Location Manager
protected LocationManager locationManager;

public GPSTracker(Context context) {
    this.mContext = context;
    getLocation();
}

public Location getLocation() {
    try {
        locationManager = (LocationManager) mContext
                .getSystemService(LOCATION_SERVICE);

        // getting GPS status
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        // getting network status
        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnabled && !isNetworkEnabled) {
            // no network provider is enabled
        } else {
            this.canGetLocation = true;
            if (isNetworkEnabled) {
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                Log.d("Network", "Network");
                if (locationManager != null) {
                    location = locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                        bearing = location.getBearing();
                    }
                }
            }
            // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) {
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                            bearing = location.getBearing();
                        }
                    }
                }
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

    return location;
}

/**
 * Stop using GPS listener
 * Calling this function will stop using GPS in your app
 * */
public void stopUsingGPS(){
    if(locationManager != null){
        locationManager.removeUpdates(GPSTracker.this);
    }
}

/**
 * Function to get latitude
 * */
public double getLatitude(){
    if(location != null){
        latitude = location.getLatitude();
    }

    // return latitude
    return latitude;
}

/**
 * Function to get longitude
 * */
public double getLongitude(){
    if(location != null){
        longitude = location.getLongitude();
    }

    // return longitude
    return longitude;
}

public float getBearing() {
    if (location != null) {
        bearing = location.getBearing();
    }
    return bearing;
}

/**
 * Function to check GPS/wifi enabled
 * @return boolean
 * */
public boolean canGetLocation() {
    return this.canGetLocation;
}

/**
 * Function to show settings alert dialog
 * On pressing Settings button will lauch Settings Options
 * */
public void showSettingsAlert(){
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

    // Setting Dialog Title
    alertDialog.setTitle("GPS is settings");

    // Setting Dialog Message
    alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

    // On pressing Settings button
    alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog,int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
        }
    });

    // on pressing cancel button
    alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
        }
    });

    // Showing Alert Message
    alertDialog.show();
}

@Override
public void onLocationChanged(Location location) {
}

@Override
public void onProviderDisabled(String provider) {
}

@Override
public void onProviderEnabled(String provider) {
}

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

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

}

//MainActivity.Java
GPSTracker gps = new GPSTracker(MainActivity.this);
1
Sergey

D'après mon expérience, l'API de localisation des services Google est préférable à utiliser dans les aspects suivants:

  • ils traitent des paramètres utilisateur, en choisissant le meilleur fournisseur de localisation disponible. Si vous choisissez de travailler directement avec LocationManager, votre code devra gérer cela.
  • vous pouvez vous attendre à obtenir un meilleur emplacement avec moins d'énergie, car Google met régulièrement à jour ses algorithmes pour déterminer l'emplacement à l'aide du WiFi, de tours de téléphonie mobile, etc.

D'après mon expérience, en utilisant les services Google, l'emplacement avec une précision suffisante pour une application de cartographie (c'est-à-dire quelques dizaines de mètres) dans de nombreux cas ne nécessite pas de données GPS. Cela pourrait également être le cas avec FusedLocationProvider, peut-être avec une exception pour les numéros d'utilisation de la batterie.

Pour conclure, si vous n'avez pas d'arguments pour NE PAS utiliser les services Google (tels que - vous ciblez un pays où ils ne sont pas disponibles, ou souhaitez distribuer via des marchés alternatifs), vous devez utiliser leur API de localisation.

0
sichevoid