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.
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.
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);
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.
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!
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.
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.
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).
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.
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.
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);
}
}
Si vous essayez avec NETWORK_PROVIDER, il est vraiment difficile de tester:
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.
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
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).