LocationListener du fournisseur de réseau est activé mais, onLocationChanged n'est jamais appelé

je développe une application qui obtient la position du téléphone cellulaire toute la journée en 6 et 6 minutes dans un service, il fonctionne très bien, mais parfois la méthode OnLocationChanged du fournisseur de Réseau auditeur arrêter d'être appelé, et je ne sais pas pourquoi.

pour une raison de cesser d'être appelé, mais le Fournisseur est de permettre et de les Lister est au travail, quand je Activer ou désactiver le Fournisseur manuellement, onProviderEnabled et onProviderDisabled est appelée.

Il arrive juste avec NETWORK_PROVIDER, le GPS_PROVIDER fonctionne bien.

port d'écoute:

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 à un Samsung Galaxy S3: enter image description here

on obtient toujours "sem sinal" pendant 4 jours d'affilée.

ce problème est déjà arrivé avec Galaxy Y et LG Optimus l5

j'ai fait un autre test pour voir si d'autres applications ont obtenu les positions nettes, et j'ai découvert qu'ils passent pour le même problème, ils ne peuvent pas obtenir la position nette 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é sur Cerberus).

Je n'ai pas pu trouver d'explication pour expliquer pourquoi NETWORKSLOCATIONS listener 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 est en train de se produire avec mon application, et j'ai découvert qu'ils passent pour le même problème, comme dans Cerberus par exemple:

j'ai désactiver le GPS Fournisseur dans un téléphone portable (Galaxy S3) avec la "Sem sinal" problème, prendre un coup d'oeil:

Mon rapport: enter image description here

Et Cerberus(impression pris en 14/05/2013) rapport: enter image description here

mais quand J'ai ouvert le Google Maps il semble fonctionner OK, j'ai essayé de passer à un endroit de distance pour voir si elle va montrer le GetLastknowLocation , mais non, google maps m'a mis au bon endroit dans le moment, donc j'ai réalisé que Google Maps utilisait motionevent pour me déplacer dans la carte;

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

cas Normal:

enter image description here

Sem sinal cas:

enter image description here

42
demandé sur Guilherme Gregores 2013-04-01 20:45:52

7 réponses

j'ai rencontré des problèmes similaires avec fournisseur de Réseau et la seule solution était redémarrage du dispositif de force. Bien que google map montre toujours emplacement correct, parce qu'il utilise d'autres informations de capteurs également en dehors de fournisseur de localisation du réseau.

Mais voici bonne nouvelle, pas il y a longtemps Google a introduit les api de fournisseurs de localisation fusionnés via son Google Play Service Framework ce qui est très facile à utilisation que les fournisseurs de localisation GPS / Réseau.

Compatible JUSQU'au niveau 8 de L'API, maintenant quand je reçois ce problème bizarre de fournisseur de réseau, la même heure emplacement fusionné me donne l'emplacement exact (sans redémarrage du périphérique).

j'en ai engagé un qui fonctionne FusedLocation Projet de Test ici, vous pouvez cloner et de tester vous-même..

voici un extrait du 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;
    }
}
28
répondu Akhil 2013-10-09 21:20:40

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 à part Google maps.

Google maps app trouve un endroit!..



PS. utilisant un LocationListener en service, donc ce n'est certainement pas un problème de mauvaise référence, objet mort et ainsi de suite.

4
répondu m190 2013-06-27 15:38:50

j'ai toujours ce problème. Mais je suis toujours à la recherche d'une réponse, j'ai essayé de l'implémenter dans L'écouteur 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 cela ne devrait pas changer dans un avenir proche; TEMPORARILY_UNAVIABLE si le fournisseur est temporairement indisponible, mais devrait être disponible sous peu; et disponible si le fournisseur est actuellement disponible. onStatusChanged

et j'ai pensé que L'OUT_OF_SERVICE était mon problème, et il n'y a pas de solution pour l'instant, juste redémarrer l'appareil, puis j'ai essayé de faire quelques rapports quand cela arrive et quand cet ocurre je demande à l'utilisateur de reebot l'appareil, mais peu d'appareils recive ce statut.

4
répondu Guilherme Gregores 2013-10-04 12:41:33

semble être un bug ouvert, problème de fournisseur de réseau rapporté à Android Open Source Project, Issue Tracker: https://code.google.com/p/android/issues/detail?id=57707