web-dev-qa-db-fra.com

Le rappel OnLocationChanged n'est jamais appelé

J'essaie d'obtenir l'emplacement actuel des utilisateurs à l'aide de LocationManager. J'ai fait beaucoup de recherches et n'arrive pas à trouver quelqu'un qui a le même problème. Le callback OnLocationChanged ne semble jamais être appelé. Ci-dessous sont mes différents codes et le logcat.

protected LocationListener locationListener;
protected LocationManager locationManager;
protected Context context;

Ma méthode OnCreate()

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v(TAG, "IN ON CREATE");

    this.context = getActivity();

    registerLocationUpdates();
}

Ma méthode registerLocationUpdates

void registerLocationUpdates() {
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_LOW);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);

    locationManager = (LocationManager)getActivity().getSystemService(LOCATION_SERVICE);

    provider = locationManager.getBestProvider(criteria, true);

    // Cant get a hold of provider
    if (provider == null) {
        Log.v(TAG, "Provider is null");
        showNoProvider();
        return;
    } else {
        Log.v(TAG, "Provider: " + provider);
    }

    locationListener = new MyLocationListener();

    locationManager.requestLocationUpdates(provider, 1L, 1f, locationListener);

    // connect to the GPS location service
    Location oldLocation = locationManager.getLastKnownLocation(provider);

    if (oldLocation != null)  {
        Log.v(TAG, "Got Old location");
        latitude = Double.toString(oldLocation.getLatitude());
        longitude = Double.toString(oldLocation.getLongitude());
        waitingForLocationUpdate = false;
        getNearbyStores();
    } else {
        Log.v(TAG, "NO Last Location found");
    }
}

Mon LocationListener

private class MyLocationListener implements LocationListener {

    public void onLocationChanged(Location location) {
        latitude = Double.toString(location.getLatitude());
        longitude = Double.toString(location.getLongitude());

        Log.v(TAG, "IN ON LOCATION CHANGE");

        if (waitingForLocationUpdate) {
            getNearbyStores();
            waitingForLocationUpdate = false;
        }

        locationManager.removeUpdates(this);
    }

    public void onStatusChanged(String s, int i, Bundle bundle) {
        Log.v(TAG, "Status changed: " + s);
    }

    public void onProviderEnabled(String s) {
        Log.e(TAG, "PROVIDER DISABLED: " + s);
    }

    public void onProviderDisabled(String s) {
        Log.e(TAG, "PROVIDER DISABLED: " + s);
    }
}

Mes autorisations dans le Manifeste Android

<uses-permission Android:name="Android.permission.INTERNET" />
<uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE" />
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />

Et enfin le logcat après avoir lancé mon application

01-25 09:43:10.963: VERBOSE/NearbyListFragment(3060): IN ON CREATE
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.973: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): Provider: gps
01-25 09:43:10.983: DEBUG/LocationManager(3060): requestLocationUpdates: provider = gps, listener = co.fusionweb.dealsplus.app.NearbyItems$NearbyListFragment$MyLocationListener@46ef4680
01-25 09:43:10.983: DEBUG/GpsLocationProvider(1329): setMinTime 1
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): NO Last Location found
01-25 09:43:10.983: VERBOSE/LocationManagerService(1329): _requestLocationUpdates: listener = Receiver{47421e68 Listener Android.os.BinderProxy@47421a68}
01-25 09:43:11.003: VERBOSE/countingFragment(3060): IN ON CREATE VIEW
01-25 09:43:11.003: WARN/GpsLocationProvider(1329): Duplicate add listener for co.fusionweb.dealsplus
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): In Constructor
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): Scrolling
01-25 09:43:11.033: DEBUG/GpsLocationProvider(1329): startNavigating
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_time_out(standalone = 60, agps = 89)
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_accuracy(accuracy = 50)
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): persist.radio.agps.mode: []
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_position mode, client = 1, interval = 1, mode = 1
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl called: client = 1, ioctl_type = 2
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_ioctl
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [96]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_api_sync_ioctl: select_id = 0, loc_ioctl returned 0
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): Callback received: 80 (cb_id=0x5310000 handle=1)
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl result: client = 1, ioctl_type = 2, SUCCESS
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_start
01-25 09:43:11.043: DEBUG/locapi_rpc_glue(1329): loc_start_fix
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [44]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.053: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.113: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.113: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_SESSION_BEGIN
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.113: VERBOSE/GpsLocationProvider(1329): reportStatus status: 1
01-25 09:43:11.113: DEBUG/GpsLocationProvider(1329): Acquiring wakelock
01-25 09:43:11.123: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.183: DEBUG/PowerManagerService(1329): New lightsensor value:40, lcdValue:77
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.273: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.273: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_ENGINE_ON
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.273: VERBOSE/GpsLocationProvider(1329): reportStatus status: 3

Et les Android parties de l’emplacement SDK du logcat se répètent. J'ai tout essayé et tout ce que je peux imaginer et ce que j’ai vu sur google et stackoverflow. Comme une note de côté, j’ai pu pour le faire fonctionner sur un appareil 2.3 utilisant le requestSingleUpdate disponible dans l'API 9 et en suivant le guide Plongée profonde dans l'emplacement mais il me faut travailler sur les versions 2.1 ou 2.2 et plus haut en utilisant l'ancien SDK. SO si vous avez des indices ou souhaitez en savoir plus, faites-le moi savoir. Merci d'avance.

61
smitt04

Il semble que votre configuration devrait fonctionner, car dans le cas contraire, je simplifierais au maximum votre exemple afin de vous aider à résoudre les problèmes. Je voudrais faire ressembler votre demande

requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

De cette façon, vous obtenez TOUTES les mises à jour possibles. Et commentez la partie sur l'obtention du dernier emplacement connu. Ce n'est pas encore nécessaire.

Puis dans onLocationChanged(), juste avoir

Log.v(TAG, "IN ON LOCATION CHANGE, lat=" + latitude + ", lon=" + longitude);

Commentez le reste afin de garder votre auditeur actif. Cela devrait vous donner un flux de mises à jour sur un appareil réel. Sur l'émulateur, vous devrez utiliser DDMS et vous obtiendrez une mise à jour GPS à chaque fois que vous appuierez sur Envoyer.

59
Steve Blackwell

Remplacement

LocationManager.GPS_PROVIDER

avec

LocationManager.NETWORK_PROVIDER

résolu mon problème.

Voici l'extrait de code de mon responsable emplacement

 LocationManager locationManager = (LocationManager) getActivity().getSystemService(LOCATION_SERVICE);

// Vérifier les autorisations d'emplacement, guimauve et au-dessus

        if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.

            Toast.makeText(getActivity(), "Not Enough Permission", Toast.LENGTH_SHORT).show();
            return;
        }

// Obtenir l'emplacement actuel pour commencer

        Location myLocation = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);

        currentLatitude = myLocation.getLatitude();
        currentLongitude = myLocation.getLongitude();

// Demander la mise à jour d'emplacement à l'aide de LocationManager.NETWORK_PROVIDER

        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                MIN_TIME_BW_UPDATES,
                MIN_DISTANCE_CHANGE_FOR_UPDATES, MapFragment.this);
12
Hitesh Sahu

Le fournisseur GPS se désactive lorsque l'appareil est à faible consommation d'énergie ou utilise le mode d'économie d'énergie. Dans ce cas, nous ne pouvons pas recevoir onLocationChanged

GPS Provider ne retourne presque jamais l'emplacement si vous restez à l'intérieur d'une maison ou d'un bâtiment (ne fonctionne bien qu'en extérieur)

Par conséquent, dans mon application, j'utiliserai à la fois GPS_PROVIDER Et NETWORK_PROVIDER Pour recevoir onLocationChanged() mieux

https://developer.Android.com/guide/topics/location/strategies.html#Updates

Pour demander des mises à jour de localisation au fournisseur GPS, utilisez GPS_PROVIDER au lieu de NETWORK_PROVIDER. Vous pouvez également demander des mises à jour d'emplacement auprès du GPS et du fournisseur d'emplacement réseau en appelant requestLocationUpdates () deux fois, une fois pour NETWORK_PROVIDER et une fois pour GPS_PROVIDER.

8
Phan Van Linh

Comme l'a écrit Steve Blackwell, votre configuration est bonne. Ce que vous pouvez essayez de comprendre si vous avez 100% un signal fixe GPS! J'ai installé un Nice application GPS Tester (du Play Store) et il vous indiquera si vous avez un correctif ou non, et à quels satellites vous êtes connecté et quelle est la force de la connexion. C'est la raison pour laquelle mon OnLocationChanged () n'a jamais appelé. J'ai essayé de l'exécuter depuis un bâtiment: \

bonne chance!

4
Li3ro

J'ai eu la même situation, je pensais avoir fait une erreur dans mon code afin que la méthode onlocationchanged ne soit pas appelée, enfin j'ai résolu comme ça.

Step 1 :
Close your application and Open Google Map Application.

Step 2 :
Touch the location Finder button or icon over the Google Map app then It will show, currently where you are located.

Step 3 :
Now Run your app and check onlocationchage will call. 
1
VyTcdc

Désolé de heurter un fil aussi ancien, mais cela pourrait être utile à d’autres, car cette question occupe un rang relativement élevé dans la recherche Google.

J'ai eu un problème similaire, le changement de lieu ne s'est pas fait virer, mais je n'ai rien trouvé de mal avec mon code. Après avoir essayé toutes sortes de combinaisons, je me suis rendu compte que la cause fondamentale du problème était le fait que j'enregistrais l'auditeur dans un service.

Le service était un service de premier plan, donc basé sur Google documentation qui devrait fonctionner, il DID PAS!

Emballer l'initialisation dans une méthode et appeler la méthode à partir de l'activité qui a créé ou lié au service a résolu mon problème.

Voici ma méthode à mon service:

void start_gps_track(int i) {
        if (myCarLocationListener!=null) {
            if (i==1) //if start night
                myCarLocationListener.setNightstart(true);
            else if (i==2) //if start GPS
                myCarLocationListener.setLocationStart(true);
            return;
        }
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if ( locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
            myCarLocationListener=new CarLocationListener(this,adjust_audio);
            if (i==1) //if start night
                myCarLocationListener.setNightstart(true);
            else if (i==2) //if start GPS
                myCarLocationListener.setLocationStart(true);
            try {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, myCarLocationListener);
                Log.d("HU","Registered location listener");
                Location lastlocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (lastlocation == null)
                    lastlocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (lastlocation != null)
                    myCarLocationListener.onLocationChanged(lastlocation);
            }
            catch (SecurityException e){
                Log.e("HU-GPS","No permission to access Location");
            }
        }
        else
        {
            Log.e("HU-GPS","No GPS provider or no permission");
        }
    }

Si j'appelle cela depuis le service lui-même, je ne recevrai aucune mise à jour d'emplacement (à nouveau, le service note est un service FOREGROUND qui est lié à une activité en cours d'exécution).

Cependant, si j'appelle cette méthode depuis l'activité qui a créé/lié au service, comme ci-dessous, cela fonctionne bien:

@Override
public void onServiceConnected(ComponentName className,
                               IBinder service) {
    // We've bound to LocalService, cast the IBinder and get LocalService instance
    TransporterService.LocalBinder binder = (TransporterService.LocalBinder) service;
    mService = binder.getService();
    mService.updatePlayer(player.this);
    try {
        mService.start_gps_track(0);
    }
    catch (Exception e) {            //This should only happen if there is no GPS provider available, but it might happen quickly after boot when the device is not yet ready.
        mService.recheck_gps(0);
    }

    mBound = true;
  }

@Override
public void onServiceDisconnected(ComponentName arg0) {
    mBound = false;

}
};

J'espère que cela aide d'autres personnes qui rencontrent ce problème.

1
Emil Borconi

J'ai connu un problème similaire. J'avais les autorisations, j'ai demandé le service correctement, mais aucune mise à jour n'est arrivée. Il s'est avéré que tout ce que je devais faire était simplement attendre. Alors que je cherchais le problème sur Internet, je faisais tourner l'application et, après quelques minutes, elle commençait tout juste à recevoir des mises à jour. Ensuite, même lorsque j'ai tué l'application et que je l'ai exécutée à nouveau, les mises à jour sont arrivées instantanément - je suppose que c'est un problème système, une optimisation, peut-être parce que l'appareil ne bouge pas du tout (d'ailleurs, ce n'est pas un appareil de merde , c’est Pixel).

1
arenaq

Comme Phan Van Linh _ répondit, c'est probablement parce que vous êtes à l'intérieur d'un bâtiment. Il y a une explication ici sur la façon de se moquer du GPS pour l'émulateur. En outre, il y a this application qui se moque des données GPS.

0
dafnahaktana

J'ai eu le même problème (onLocationChanged () jamais appelé avec NETWORK_PROVIDER) sur mon périphérique réel (M, targetSDK 23 de l'application) jusqu'à ce que je le redémarre.

0
Andrew Glukhoff

J'ai fait face au même problème. J'obtenais getLastKnownLocation comme null. Le problème est résolu lorsque j'ai redémarré à la fois le périphérique et le service Location dans le périphérique.

0
Niranjan
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (manager != null) {
        List<String> providers = manager.getAllProviders();
        for (String provider : providers) {
           manager.requestLocationUpdates(provider, TIME_BW_UP, DISTANCE_BW_UP, locationListener);
        }
}
0
Reza

Si vous essayez avec NETWORK_PROVIDER, il est vraiment difficile de tester:

  • sur Emulator: ne fonctionne jamais
  • sur un périphérique réel: seul getLastKnownLocation () fonctionne; pour recevoir onLocationChanged (), vous devez utiliser les données mobiles et sortir avec le risque de perdre votre téléphone de la part d'un voleur: P

Je suppose que la raison en est qu’il s’agit uniquement de l’emplacement du fournisseur de réseau, mais pas de votre appareil lui-même, et que le fournisseur de réseau ne se déplace jamais, ainsi onLocationChanged () n’appelle jamais. Cela peut se produire uniquement lors du basculement entre données mobiles et wifi et inversement. S'il vous plait corrigez moi si je me trompe.

Je suggère donc d’utiliser GPS_PROVIDER pour expérimenter avant d’envisager les performances et l’utilisation de la batterie. Cela fonctionne bien sur les émulateurs et les appareils réels. Pour la meilleure pratique: https://developer.Android.com/guide/topics/location/strategies.html

Il m'a fallu plusieurs heures pour tester avec NETWORK_PROVIDER sans aucun résultat. J'espère donc que ma suggestion m'a été utile.

0
thanhbinh84

Cela devrait être dû aux paramètres de votre téléphone. Dans les paramètres de localisation des téléphones, si le mode Service de localisation est défini sur GPS uniquement, les appels en rappel OnLocationChanged s’il existe un repère GPS. En sélectionnant Utiliser les options GPS, WI-FI et réseaux mobiles, la localisation sera déterminée à l'aide de ces trois fournisseurs. Cela prendra moins de temps pour localiser l'emplacement de votre appareil. *** Le chemin d'accès aux services de localisation peut être changer d'appareil en appareil. Merci

0
Osura Weerasinghe

J'ai 2 appareils: Samsung Galaxy S4 (Android 5.0.1) et Vertex Win (Android 8.1).

Sur Samsung, tout fonctionne correctement et rapidement, les coordonnées GPS sont trouvées et onLocationChanged est appelé.

Sur Vertex in prioity PRIORITY_BALANCED_POWER_ACCURACY il interagit probablement avec le fournisseur de réseau en premier, il trouve donc les coordonnées via Wi-Fi. Mais il ne peut pas détecter correctement si le service de localisation est activé (après un certain temps, le périphérique pense qu'il est activé, alors qu'il est éteint, et appelle la méthode addOnSuccessListener de LocationServices.getSettingsClient. Alors je suis passé à PRIORITY_HIGH_ACCURACY et j'ai une autre surprise. Le fournisseur de réseau a été désactivé, mais onLocationChanged n'a pas été appelé. Je n'ai donc pas pu obtenir les coordonnées. J'ai téléchargé GPS tester (@ Li3ro a conseillé) de Play Market et a constaté que les satellites sont visibles, mais sans signal fixe. Je ne pouvais pas recevoir de signal à l'intérieur d'un bâtiment.

Même les cartes autonomes ne pouvaient pas recevoir de coordonnées, mais celles d'extérieur le pouvaient. Ainsi, une fois que je suis parti, je pouvais trouver mes coordonnées dans une application.

Voir aussi https://stackoverflow.com/a/27828929/291414 , où il est parlé des priorités et de la reconnaissance des erreurs (désactivation du GPS après un certain temps si aucune coordonnée n'est trouvée).

0
CoolMind