36 votes

L'API de localisation du service Google Play renvoie parfois un mauvais emplacement

Nous avons une application qui capture l'emplacement de l'utilisateur à l'aide de Google Play Service de l'Emplacement de l'API pour chacune des transactions, comme Geotag terre, lors de la passation de commande, etc.

Après la capture de ces emplacements de mobile nous allons synchroniser le serveur et l'afficher dans un tableau de bord web.

Nous avons remarqué que dans de rares cas de transaction capturé à l'intérieur de quelques secondes ont lieu à des résultats variés à distance.


Exemple:
L'emplacement de l'utilisateur sera dans l'

Mandsaur, Madhya Pradesh, En Inde, En Asie
(Latitude - 24.057291, Longitude 75.0970672, Capturé date - 2017-01-04 09:19:48).

Mais la suite des opérations ont lieu de

Paris qui est 6772 km
(Latitude - 48.8581074, Longitude 2.3525187, Capturé date - 2017-01-04 09:20:01)


parfois, son extraction de mal a déclaré de l'inde comme l'utilisateur est de gujrat puis l'emplacement d'extraction du Bihar, Maharastra, le Koweït(de l'inde), c'est vraiment casse-tête pour les indiens développeur


Comme cela se passe sans intervention de l'utilisateur et pas de se moquer de l'emplacement des applications installé dans le périphérique de l'utilisateur.

Quelqu'un peut-il expliquer pourquoi cela se produit et comment pourrions-nous éviter ces scénarios?


NOTE:
Ces sites de transactions sont généralement capturés dans les champs ouverts avec GPS activé et configuré en mode de Haute Précision

11voto

Froyo Points 2928

L'Endroit que vous obtenez à partir de l'API aura de précision en mètres. Vous devriez également vérifier l'âge de l'emplacement.

https://developer.android.com/reference/android/location/Location.html#getAccuracy()

https://developer.android.com/reference/android/location/Location.html#getTime()

En général, les gens jeter l'emplacement si la précision est supérieure à 50 ou 100m.


Pourquoi cela se produit?

Il faut un certain temps pour que le GPS de l'appareil pour trouver les satellites et obtenir le signal. Aussi, l'API va essayer de déterminer votre position en fonction de votre réseau. C'types de saut entre le réseau et le GPS, jusqu'à ce que le GPS fournit quelques données précises.


Comment faire pour éviter cela?

Dans votre situation, à l'écoute, vérifier l'exactitude et attendre d'avoir une meilleure précision.

4voto

v1bri Points 1167

Le fonctionnaire Android développeur de site a une page dédiée aux Stratégies de Localisation pour le succès des applications Android. Vous pouvez en lire plus là, donc, sans entrer dans trop de détails, la documentation officielle est la suivante...

Vous pourriez vous attendre que la dernière position gps est la plus précise. Toutefois, en raison de la précision d'une position gps varie, le correctif plus récent n'est pas toujours la meilleure. Vous devez inclure une logique pour le choix de l'emplacement des correctifs en fonction de plusieurs critères. Les critères varie également selon le cas d'utilisation de l'application et les tests sur le terrain.

Voici quelques mesures que vous pouvez prendre afin de valider l'exactitude d'un emplacement corrigé:

  • Vérifier si l'emplacement recherché est beaucoup plus récente que la précédente estimation.
  • Vérifier si le degré de précision indiqué par l'emplacement est mieux ou pire que la précédente estimation.
  • Vérifiez le fournisseur dont le nouvel emplacement, et de déterminer si vous avez confiance en plus.

Vous pouvez aussi regarder dans la mise en œuvre d'une base de Filtre de Kalman dans votre application afin de maintenir et de mettre à jour une estimation de la localisation de l'utilisateur. Bonne chance.

3voto

Darshan Mistry Points 2277

Vous pouvez utiliser le code ci-dessous pour une api fusionnée avec Google

 package com.hydrometcloud.location;

import android.app.Activity;
import android.content.Context;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStatusCodes;


public class GoogleLocation implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener,
        ResultCallback<LocationSettingsResult> {

    private LocationSettingsRequest mLocationSettingsRequest;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    private String TAG = "GoogleLocation";

    private Context context;
    private long UPDATE_INTERVAL = 10 * 1000;  /* 10 secs */
    private long FASTEST_INTERVAL = 2000; /* 2 sec */
    private GoogleLocationCallback googleLocationCallback;

    private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
    public static final int REQUEST_CHECK_SETTINGS = 0x1;

    public GoogleLocation(Context context) {
        this.context = context;
        setUpLocation();
    }

    public void setGoogleLocationCallback(GoogleLocationCallback googleLocationCallback) {
        this.googleLocationCallback = googleLocationCallback;
    }

    private void setUpLocation() {

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

        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(UPDATE_INTERVAL)        // 10 seconds, in milliseconds
                .setFastestInterval(FASTEST_INTERVAL); // 1 second, in milliseconds

        locationEnable();
    }

    public void googleClientConnect() {
        mGoogleApiClient.connect();
    }

    public void googleClientDisConnect() {
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.unregisterConnectionCallbacks(this);
            mGoogleApiClient.unregisterConnectionFailedListener(this);
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            mGoogleApiClient.disconnect();
            mGoogleApiClient = null;
        }
    }

    private void locationEnable() {
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        mLocationSettingsRequest = builder.build();
        checkLocationSettings();
    }

    private void checkLocationSettings() {
        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(
                        mGoogleApiClient,
                        mLocationSettingsRequest
                );
        result.setResultCallback(this);
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (location == null) {
            updateLocation();
        } else {
            handleNewLocation(location);
        }
    }

    private void handleNewLocation(Location location) {

        double currentLatitude = location.getLatitude();
        double currentLongitude = location.getLongitude();

        Log.e(TAG, "---currentLatitude--" + currentLatitude);
        Log.e(TAG, "---currentLongitude--" + currentLongitude);

        if (googleLocationCallback != null) {
            googleLocationCallback.updateLocationListner(currentLatitude, currentLongitude);
        }

    }

    public void updateLocation() {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                     /*
         * Google Play services can resolve some errors it detects.
         * If the error has a resolution, try sending an Intent to
         * start a Google Play services activity that can resolve
         * error.
         */
        if (connectionResult.hasResolution()) {
            try {
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult((Activity) context, CONNECTION_FAILURE_RESOLUTION_REQUEST);
                /*
                 * Thrown if Google Play services canceled the original
                 * PendingIntent
                 */
            } catch (IntentSender.SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        } else {
            /*
             * If no resolution is available, display a dialog to the
             * user with the error.
             */
            Log.e(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
        }
    }

    @Override
    public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
        final Status status = locationSettingsResult.getStatus();
        switch (status.getStatusCode()) {
            case LocationSettingsStatusCodes.SUCCESS:
                Log.e(TAG, "All location settings are satisfied.");
                break;
            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                Log.e(TAG, "Location settings are not satisfied. Show the user a dialog to" +
                        "upgrade location settings ");

                try {
                    // Show the dialog by calling startResolutionForResult(), and check the result
                    // in onActivityResult().
                    status.startResolutionForResult((Activity) context, REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG, "PendingIntent unable to execute request.");
                }
                break;
            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                Log.e(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " +
                        "not created.");
                break;
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        handleNewLocation(location);
    }

    public interface GoogleLocationCallback {
        void updateLocationListner(double latitude, double longitude);
    }
}
 

Maintenant, vous implémentez callback GoogleLocation.GoogleLocationCallback sur quelle activité ou fragment vous récupérez l'emplacement, puis écrivez ci-dessous le code correspondant à l'activité ou au fragment sur lequel vous obtenez l'emplacement.

 googleLocation = new GoogleLocation(this);
googleLocation.setGoogleLocationCallback(this);
 

2voto

Thracian Points 1602

La meilleure façon de résoudre ce problème, le filtrage des résultats. La probabilité d'un emplacement correct retourné à partir d'un Fusible de service est de 67%, ce qui signifie que vous pouvez obtenir un emplacement incorrect dans 1/3.

Vous devriez comparer emplacement précédent( ou plus d'un à être sûr de vous, gardez-les dans une liste) avec l'actuel avant d'obtenir l'emplacement. Si il y a un noticible différence n'utilisez pas la dernière.

Remarque: ne pas enregistrer les positions de l'utilisateur à un fichier ou un dossier, c'est contre la politique de confidentialité, il suffit de comparer avec lastKnownLocation ou de lieux reçu dans la session en cours.

Une autre idée est que si vous utilisez GoogleApiClient, je suis actuellement à l'aide, il est une nouvelle classe pour les fusibles emplacement FusedLocationProvider, vous pouvez vérifier cela.

Aussi loin que j'ai compris, ils ont mis 4 emplacement de récupération de la limite par heure pour les appareils avec Android 8.0 API (niveau 26) et plus tard. Vous pouvez consulter ce document pour de nouveaux comportements.

1voto

Anu Martin Points 409

J'ai eu le même problème sur Pune, en Inde. Le dispositif utilisé pour les essais, Balayez vers la tablette,

Solution : je garde la dernière de la latitude et de la longitude et l'heure de mise à jour, lors de la prochaine latitude et la longitude de mise à jour, calculer la distance entre les deux endroits, si la distance est supérieure à 100 KM, alors il ne comptera pas .

La méthode que j'ai utilisé pour calculer la distance

public static double calculateDistance(double lat1,double lon1,double lat2,double lon2) {

    double theta = lon1 - lon2;
    double dist = Math.sin(deg2rad(lat1))
            * Math.sin(deg2rad(lat2))
            + Math.cos(deg2rad(lat1))
            * Math.cos(deg2rad(lat2))
            * Math.cos(deg2rad(theta));
    dist = Math.acos(dist);
    dist = rad2deg(dist);
    dist = dist * 60 * 1.1515;
    return (dist);
}    

Pourquoi ça arrive

Sur un appareil android il y a 2 options pour obtenir la localisation

  • GPS
  • Internet

GPS (LocationManager.GPS_PROVIDER): est lent comparer à internet, mais il précise que l'internet, dans des régions éloignées GPS connexion plus lente et parfois difficile à connecter.

Internet (LocationManager.NETWORK_PROVIDER) : c'est beaucoup plus rapide que le GPS, mais il est moins précis que GPS

Si le GPS est indisponible et vous avez besoin d'emplacement actuel, puis LocationManager vous donnera des données disponibles, ce qui est récupérée à partir de l'internet. (dans ce cas, vous pouvez également consulter le fournisseur d'emplacement.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X