42 votes

Le LocationListener de NETWORK_PROVIDER est activé, mais onLocationChanged n'est jamais appelé.

Je développe une application qui obtient la position du téléphone portable toute la journée en 6 et 6 minutes dans un service, cela fonctionne bien mais parfois la méthode OnLocationChanged de l'auditeur du fournisseur de réseau arrête d'être appelé, et je ne sais pas pourquoi.

Pour une raison quelconque, il n'est plus appelé, mais le fournisseur est activé et la liste fonctionne, lorsque j'active ou désactive le fournisseur manuellement, onProviderEnabled et onProviderDisabled s'appelle.

Cela arrive juste avec NETWORK_PROVIDER le GPS_PROVIDER fonctionne bien.

Auditeur :

LocationListener locationListenerGPS = new LocationListener() {
        // @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO locationListenerGPS onStatusChanged
            Log.d(TAG, "Provedor trocado");
        }

        // @Override
        public void onProviderEnabled(String provider) {
            Log.w(TAG, "PROVEDOR " + provider + " HABILITADO!");
        }

        // @Override
        public void onProviderDisabled(String provider) {
            Log.w(TAG, "PROVEDOR " + provider + " DESABILITADO!");
        }

        // @Override
        public void onLocationChanged(Location location) {

            longitudeGPS = location.getLongitude();
            latitudeGPS = location.getLatitude();
            Log.d(TAG,"LocationChangedGPS LAT: "+latitudeGPS+" longi: "+longitudeGPS);
            gpsComSinal = true;
        }
    };

    LocationListener locationListenerNET = new LocationListener() {

        // @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO locationListenerNET onStatusChanged
            Log.d("Contele", "Provedor foi mudado");
        }

        // @Override
        public void onProviderEnabled(String provider) {
            Log.i(TAG, "PROVEDOR " + provider + " HABILITADO!");
        }

        // @Override
        public void onProviderDisabled(String provider) {
            Log.i(TAG, "PROVEDOR " + provider + " DESABILITADO!");
        }

        @Override
        public void onLocationChanged(Location location) {
            longitudeNET = location.getLongitude();
            latitudeNET = location.getLatitude();
            Log.d(TAG,"LocationChangedNET LAT: "+latitudeNET+" longi: "+longitudeNET);
            netComSinal = true;
        }
    };

Code :

public void initProviders() {

        localizacao = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);

        localizacao.removeUpdates(locationListenerNET);
        localizacao.removeUpdates(locationListenerGPS);

        localizacao.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
                locationListenerGPS);

        localizacao.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0,
                0, locationListenerNET);

        Log.d(TAG,"EsperaGPS");
        Handler esperaGPS = new Handler() {
            public void handleMessage(Message msg) {

                requestGPS();
            }
        };

        Message msgEsperaGPS = Message.obtain();
        msgEsperaGPS.what = 0;
        esperaGPS.sendMessageDelayed(msgEsperaGPS, 35000);
    }

    public void requestGPS() {
            if (gpsComSinal) {
                Log.d(TAG,"PEGO SINAL DE GPS");
                rastreio = "GPS";
                longitude = longitudeGPS;
                latitude = latitudeGPS;
                Log.d(TAG, "Utilizando provedor GPS.");
                localizacao.removeUpdates(locationListenerGPS);
                localizacao.removeUpdates(locationListenerNET);

            } else {
                Log.d(TAG,"Sem GPS... pegar NEt");
                // Setando os valores para usar network
                localizacao.removeUpdates(locationListenerGPS);
                localizacao.removeUpdates(locationListenerNET);
                localizacao
                        .requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                                0, 0, locationListenerNET);
                Log.d(TAG,"EsperaNET");

                        requestNET();
            }
        }

    public void requestNET() {
            if (netComSinal) {
                Log.d(TAG,"PEGO SINAL DE NET");
                rastreio = "NET";
                longitude = longitudeNET;
                latitude = latitudeNET;
                Log.d(TAG, "Utilizando provedor NET.");
                localizacao.removeUpdates(locationListenerNET);

            } else {
                localizacao.removeUpdates(locationListenerGPS);
                localizacao.removeUpdates(locationListenerNET);
                Log.d(TAG,"Sem sinal");
            }
        }

Rapport dans un Samsung Galaxy S3 : enter image description here

Je reçois toujours "Sem sinal" pendant 4 jours d'affilée.

Ce problème s'est déjà produit avec le Galaxy Y et le LG Optimus l5.

J'ai fait un autre test pour voir si d'autres applications ont obtenu les positions NET, et j'ai découvert qu'ils passent pour le même problème, ils ne peuvent pas obtenir la position NET juste le GetLastknowLocation ; pour tester que j'ai utilisé un Galaxy S3 avec ce problème, et j'ai désactivé le fournisseur GPS. (Testé dans Cerberus).

Je n'ai pas trouvé d'explication à la raison pour laquelle l'auditeur de NETWORKSLOCATIONS cesse de donner des positions, mais c'est peut-être parce qu'il ne devrait pas fonctionner pendant 2 ou 3 jours sans arrêt.

J'ai fait quelques tests avec d'autres applications pour voir si ce problème ne concerne que mon application, et j'ai découvert qu'ils ont le même problème, comme dans Cerberus par exemple :

J'ai désactivé le fournisseur GPS dans un téléphone portable (Galaxy S3) avec le problème "Sem sinal", jetez un oeil :

Mon rapport : enter image description here

Et le rapport de Cerberus (empreinte prise le 14/05/2013) : enter image description here

Mais lorsque j'ai ouvert Google Maps, il semble fonctionner correctement. J'ai essayé de me déplacer à une certaine distance pour voir s'il allait afficher l'image. GetLastknowLocation Mais non, Google Maps m'a placé au bon endroit à ce moment-là. J'ai donc réalisé que Google Maps utilisait motionevent pour me déplacer sur la carte ;

Et aussi imprimer le journal de Google Maps pour obtenir NetWorkProvider :

Cas normal :

enter image description here

Cas semi-final :

enter image description here

0 votes

C'est parce que le fournisseur de réseau ne fournit pas votre position mais la position de la tour/cellule BT à la place. Je peux me tromper mais je pense que si vous vous déplacez suffisamment, vous allez probablement attraper une autre tour/cellule BT et vous obtiendrez une nouvelle localisation dans cet auditeur de réseau.

0 votes

J'ai déjà pensé à cela, et j'ai essayé de le déplacer de 2000 mètres + mais sans succès, si je redémarre le téléphone cellulaire l'application fonctionne normalement pendant 4 ou 3 jours, dans certains appareils ce problème n'est jamais arrivé. J'ai eu un Galaxy S3 avec ce problème pendant 2 jours d'affilée, et il n'a pas obtenu une seule position nette, juste le GPS.

0 votes

Il semble que le fournisseur NetworkLocation de l'appareil soit cassé J'ai également rencontré le même genre de problème sur certains appareils HTC, puis j'ai cherché sur le net le problème du GPS HTC et j'ai trouvé beaucoup d'utilisateurs se plaignant que le GPS ne fonctionne pas correctement .

28voto

Akhil Points 2109

J'ai rencontré des problèmes similaires avec Fournisseur de réseau et la seule solution était forcer le redémarrage du dispositif . Bien que la carte de google montrait toujours l'emplacement correct, parce qu'elle utilise d'autres informations de capteurs également en dehors du fournisseur d'emplacement de réseau.

Mais voici bonne nouvelle Il n'y a pas longtemps, Google a introduit des API de fournisseur de localisation fusionnées via son Cadre du service Google Play qui est plus facile à utiliser que les fournisseurs de localisation GPS / réseau.

Compatible jusqu'au niveau 8 de l'API, maintenant quand j'ai ce problème bizarre de fournisseur de réseau, en même temps Fused Location me donne une localisation précise (sans redémarrage de l'appareil).

J'ai commis un travail Projet de test de FusedLocation ici vous pouvez cloner et tester vous-même

Voici un extrait de code :-

package com.example.fusedLoctionTest.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationRequest;

public class FusedLocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener{
    private static final LocationRequest REQUEST = LocationRequest.create()
            .setInterval(0)
            .setFastestInterval(0)
            .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    public static final String LOCATION_RECEIVED = "fused.location.received";
    private Long now;

    private LocationClient mLocationClient;
    private final Object locking = new Object();
    private Runnable onFusedLocationProviderTimeout;
    private Handler handler = new Handler();

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        now = Long.valueOf(System.currentTimeMillis());
        mLocationClient = new LocationClient(this, this, this);
        mLocationClient.connect();
        return START_STICKY;
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.d("FusedLocationService", "Fused Location Provider got connected successfully");
        mLocationClient.requestLocationUpdates(REQUEST,this);
        onFusedLocationProviderTimeout = new Runnable() {
            public void run() {
                Log.d("FusedLocationService", "location Timeout");

                Location lastbestStaleLocation=getLastBestStaleLocation();
                sendLocationUsingBroadCast(lastbestStaleLocation);

                if(lastbestStaleLocation!=null)
                    Log.d("FusedLocationService", "Last best location returned ["+lastbestStaleLocation.getLatitude()+","+lastbestStaleLocation.getLongitude()+"] in "+(Long.valueOf(System.currentTimeMillis())-now)+" ms");

                if(mLocationClient.isConnected())
                    mLocationClient.disconnect();
            }
        };
        handler.postDelayed(onFusedLocationProviderTimeout, 20000);//20 sec
    }

    private void sendLocationUsingBroadCast(Location location) {
        Intent locationBroadcast = new Intent(FusedLocationService.LOCATION_RECEIVED);
        locationBroadcast.putExtra("LOCATION", location);
        locationBroadcast.putExtra("TIME", Long.valueOf(System.currentTimeMillis()-now) +" ms");
        LocalBroadcastManager.getInstance(this).sendBroadcast(locationBroadcast);
        stopSelf();
    }

    @Override
    public void onDisconnected() {
        Log.d("FusedLocationService","Fused Location Provider got disconnected successfully");
        stopSelf();
    }

    @Override
    public void onLocationChanged(Location location) {
        synchronized (locking){
            Log.d("FusedLocationService", "Location received successfully ["+location.getLatitude()+","+location.getLongitude()+"] in "+(Long.valueOf(System.currentTimeMillis()-now))+" ms");

            handler.removeCallbacks(onFusedLocationProviderTimeout);
            if(mLocationClient.isConnected())
                mLocationClient.removeLocationUpdates(this);

            sendLocationUsingBroadCast(location);

            if(mLocationClient.isConnected())
                mLocationClient.disconnect();
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.d("FusedLocationService", "Error connecting to Fused Location Provider");
    }

    public Location getLastBestStaleLocation() {
        Location bestResult = null;
        LocationManager locMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Location lastFusedLocation=mLocationClient.getLastLocation();
        Location gpsLocation = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        Location networkLocation = locMgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        if (gpsLocation != null && networkLocation != null) {
            if (gpsLocation.getTime() > networkLocation.getTime())
                bestResult = gpsLocation;
        } else if (gpsLocation != null) {
            bestResult = gpsLocation;
        } else if (networkLocation != null) {
            bestResult = networkLocation;
        }

        //take Fused Location in to consideration while checking for last stale location
        if (bestResult != null && lastFusedLocation != null) {
            if (bestResult.getTime() < lastFusedLocation.getTime())
                bestResult = lastFusedLocation;
        }

        return bestResult;
    }

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

0 votes

J'ai mis en place quelque chose de similaire et je peux recevoir des mises à jour de localisation lorsque mon application passe en arrière-plan. Toutefois, lorsque je détruis mon application (le service est toujours en cours d'exécution), je ne reçois plus de mises à jour de l'emplacement. La même chose se produit avec votre application. Avez-vous une idée de la raison ?

2 votes

R... redémarrer ? Quel terrible échec, Google.

0 votes

La bibliothèque des services de google play a atteint le maximum de mon numéro de méthode dex.

4voto

m190 Points 11

J'ai exactement le même problème et la seule solution pour moi est de redémarrer l'appareil. Ce qui est intéressant, c'est qu'aucune des applications n'a d'informations de localisation à l'exception de Google Maps.
L'application Google Maps trouve en quelque sorte un emplacement

P.S. J'utilise un LocationListener en service, donc ce n'est certainement pas un problème de mauvaise référence, d'objet mort, etc.

0 votes

Oui, c'est un peu un mystère mais je pense que Google Maps utilise l'accéléromètre pour gérer ce problème.

1 votes

Dans mon cas, mon application ne recevait pas de rappels onLocationChanged sur un téléphone particulier, alors que d'autres les recevaient. J'ai remarqué la même chose que m190 : d'une certaine manière, Google Maps obtenait la position actuelle, et mon application était bloquée avec seulement la possibilité d'obtenir les dernières positions connues, qui étaient assez anciennes. Le redémarrage de l'appareil a finalement réglé le problème. J'aimerais bien savoir ce que Google Maps faisait différemment...

4voto

J'ai toujours ce problème. J'ai essayé de l'implémenter dans le listener du NETWORK_PROVIDER :

public void onStatusChanged(final String provider, final int status, final Bundle extras) {
    switch( status ) {
    case LocationProvider.AVAILABLE:
                // ...
        break;
    case LocationProvider.OUT_OF_SERVICE:
                // ...
        break;
    case LocationProvider.TEMPORARILY_UNAVAILABLE:
                // ...
        break;
    }
}

Parce que : OUT_OF_SERVICE si le fournisseur est hors service et que cela ne devrait pas changer dans un avenir proche ; TEMPORARILY_UNAVAILABLE si le fournisseur est temporairement indisponible mais devrait être disponible sous peu ; et AVAILABLE si le fournisseur est actuellement disponible. onStatusChanged

Et je pensais que le OUT_OF_SERVICE était mon problème, et il n'y a pas de solution jusqu'à présent, juste un redémarrage de l'appareil, puis j'ai essayé de faire des rapports quand cela se produit et quand cela se produit je demande à l'utilisateur de redémarrer l'appareil, mais peu d'appareils reçoivent ce statut.

2voto

nurisezgin Points 560

J'ai compris quelque chose dans notre question ; vous appelez la méthode requestGPS et ensuite vous découvrez sa position. Si le GPS est activé, vous l'obtenez via le GPS. Ou bien via NET. Lorsque l'on appelle la méthode requestGPS et que l'on contrôle le fournisseur, on obtient la lat-lang mais on supprime les mises à jour (ne pas appeler parce que l'on a supprimé le déclencheur de mises à jour) ;

if (gpsComSinal) {
    Log.d(TAG,"PEGO SINAL DE GPS");
    rastreio = "GPS";
    longitude = longitudeGPS;
    latitude = latitudeGPS;

    Log.d(TAG, "Utilizando provedor GPS.");
    // if you remove update don't call onLocationChanged
    localizacao.removeUpdates(locationListenerGPS); 
    localizacao.removeUpdates(locationListenerNET);
} else {
    Log.d(TAG,"Sem GPS... pegar NEt");
    // Setando os valores para usar network
    localizacao.removeUpdates(locationListenerGPS);
    localizacao.removeUpdates(locationListenerNET);
    localizacao.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                                       0, 0, locationListenerNET);
    Log.d(TAG,"EsperaNET");
    requestNET();
}

0 votes

Je suis d'accord avec vous qu'il y a des removeUpdates inutiles, mais à ce stade, si(gpsComSinal) j'ai déjà attendu 35 secondes pour écouter NetProvicer et GPSProvider et sauvegarder leurs positions, parce que je veux des positions en 6 et 6 minutes et je veux économiser la batterie. Donc ce removeUpdates n'est pas le problème car après 6 minutes je demande à nouveau leurs positions.

1voto

Toverbal Points 128

Je pense que c'est parce que ton application est "tuée" en arrière-plan. J'ai déjà été confronté à ce problème et je l'ai résolu en déplaçant la création du LocationListener dans un service. Assurez-vous de garder une référence à l'écouteur aussi. Cela pourrait résoudre le problème.

0 votes

J'ai un service qui tourne en 6 et 6 minutes dans ce service, j'ai créé le LocationListener pour GPS et NET, et il n'y a pas d'erreurs, l'application ne se fait pas tuer aussi, parce qu'elle obtient toujours la position GPS, si je sors le OnlocationChanged du fournisseur GPS me retourne un LAT et LONGITUDE, mais le NET reste "mort" même si j'ai une connexion WIFI ou 3G.

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