Android: requestLocationUpdates emplacement de mises à jour à la plupart des toutes les 45 secondes
Fond
Je suis en train d'écrire une application Android dont la fonction principale est le suivi de l'emplacement de l'utilisateur et en faisant une alerte lorsque l'utilisateur s'approche d'un certain point. Donc j'ai besoin de mettre à jour l'emplacement de l'utilisateur, à intervalles réguliers, et ces intervalles plus petits que l'utilisateur se rapproche de la cible. Ainsi, lorsque l'utilisateur est à l'intérieur, à 1 km de la cible, je veux l'emplacement pour être à jour toutes les 20 secondes et ainsi de suite, jusqu'à ce que l'utilisateur arrive.
Problème
Quand je l'ai tester (provider = LocationManager.NETWORK_PROVIDER
), un appel à requestLocationUpdates(provider, minTime, minDistance, locationListener)
avec tout minTime < 45000
a le même effet que minTime = 45000
, c'est à dire-je obtenir les mises à jour, avec un intervalle de exactement 45 secondes.
Je sais que le temps minimum paramètre n'est qu'une "astuce", mais elle n'est pas prise comme un indice par mon application. Je reçois des mises à jour avec l'intervalle de temps spécifié jusqu'à ce que l'intervalle de passe en-dessous de 45 secondes. Il semble qu'un minimum de temps de 45 secondes entre l'emplacement des mises à jour est codé en dur dans Android, mais ce serait bizarre. En Plus je n'ai jamais entendu parler de ce problème avant, et je n'ai pas été capable de le trouver abordé ici sur Stackoverflow.
Parce que je ne suis pas en mesure d'obtenir des mises à jour fréquentes, ma solution (pour l'instant) est manuellement appel requestLocationUpdates
chaque fois qu'un nouvel emplacement qui est nécessaire, puis il suffit d'utiliser la première position disponible. Pour ce faire, à de petits intervalles-je utiliser handler.postDelayed(myRunnable, updateInterval)
pour retarder les appels, et myRunnable
s'occupe ensuite de l'appeler requestLocationUpdates
. Cependant, cette méthode ne fonctionne que sur 50 (apparemment aléatoire) pour cent du temps.
Quelqu'un connais le problème, et est-il un moyen de le réparer? Ou est ma seule option pour définir minTime = 0
et espérer pour le mieux?
Code Source
Voici le code source pour myRunnable, dont run()
méthode que j'ai manuellement appel régulièrement avec handler.postDelayed(myRunnable, updateInterval)
:
public class MyRunnable implements Runnable {
private LocationManager manager;
private LocationListener listener;
@Override
public void run() {
//This is called everytime a new update is requested
//so that only one request is running at a time.
removeUpdates();
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new LocationListener() {
@Override
public void onLocationChanged(Location loc) {
location = loc;
latitude = loc.getLatitude();
longitude = loc.getLongitude();
accuracy = Math.round(loc.getAccuracy());
handler.sendMessage(Message.obtain(handler, KEY_MESSAGE_LOCATION_CHANGED));
checkForArrival();
}
//Other overrides are empty.
};
if(!arrived)
manager.requestLocationUpdates(provider, updateInterval, 0, listener);
}
/**
* Removes location updates from the LocationListener.
*/
public void removeUpdates() {
if(!(manager == null || listener == null))
manager.removeUpdates(listener);
}
//Another method for "cleaning up" when the user has arrived.
}
Et voici mon handler
:
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case KEY_MESSAGE_LOCATION_CHANGED:
if(myRunnable != null) {
myRunnable.removeUpdates();
handler.postDelayed(myRunnable, updateInterval);
}
break;
}
}
};
Informations supplémentaires
L'ensemble de l'emplacement de la mise à jour de chose s'exécute dans un service.
J'ai lu la doc plusieurs fois, Google avait le problème, et j'ai essayé diverses autres solutions de contournement. Rien de fait.
J'ai connecté la merde hors de cette chose, et la seule chose la plus intéressante à voir est un gros "ignorer" pour mes fréquentes demandes de localisation. Toutes les méthodes sont appelées.
Toute aide sera très apprécié!
- Ce type de fournisseur que vous utilisez? Je ne le vois pas dans le code. Je reçois des mises à jour environ toutes les 45 secondes pour que le fournisseur de réseau.
- Je suis en utilisant le fournisseur de réseau parce que mon téléphone (sur lequel je suis en train de tester l'application) a toujours un moment difficile l'obtention d'un gps.
- Pour être clair le code source est inclus dans cette question est que mon code source de courant, qui, je l'espère, une solution de contournement temporaire. Le problème réside dans le fait que l'appelant simplement
requestLocationUpdates(provider, minTime, minDistance, locationListener)
ne fonctionne pas lorsque minTime < 45000.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez définir la minTime à une valeur quelconque. Cependant, vous ne recevrez qu'une mise à jour dès qu'un nouvel emplacement est disponible. Le réseau uniquement des mises à jour toutes les 45 sec ou alors sur chaque téléphone que je possède. Cela semble être une limitation du Fournisseur de Réseau. Si vous voulez plus de mises à jour fréquentes d'utiliser le GPS fournisseur. Selon le GPS de matériel que vous devriez obtenir un maximum de mise à jour des taux autour de 4 hz.
Vous êtes complètement à droite, le temps minimum de 45 secondes est harcoded dans Android.
Ce qui semble être un NetworkLocationProvider code source de la classe, quand il était encore dans l'Android de base:
http://www.netmite.com/android/mydroid/frameworks/base/location/java/com/android/internal/location/NetworkLocationProvider.java
Regarder la variable:
Et la méthode:
Maintenant NetworkLocationProvider est de l'Android de base, vous pouvez le trouver dans NetworkLocation.apk dans /system/app
Vous pouvez trouver une explication du pourquoi de la base ici:
https://groups.google.com/forum/?fromgroups=#!topic/android plate-forme/10Yr0r2myGA
Mais 45 secondes min, le temps semble s'être encore là.
Regardez cette NetworkProvider décompilation:
http://android.fjfalcon.com/xt720/miui-trans/apk-decompiled/NetworkLocation/smali/com/google/android/location/NetworkLocationProvider.smali
Comme vous pouvez le deviner si vous convertissez 0xafc8 à virgule vous obtenez 45000 millisecondes
Je n'ai pas trouvé une explication sur les raisons de 45 secondes. Je suppose qu'il y aura des raisons comme éviter de surcharger ou d'autres utilisations qu'ils ne veulent pas.
En fait, il y a 100 demande de courtoisie limite à l'API de Géolocalisation:
https://developers.google.com/maps/documentation/business/geolocation/#usage_limits
Mais ils ne semblent pas respecter cette règle en application Google Maps. Si vous l'ouvrez et vous n'active emplacement réseau, vous pouvez remarquer que votre emplacement est mis à jour beaucoup plus souvent que les 45 secondes.
J'ai remarqué cette ligne étrangement fréquentes (33 fois par seconde) dans le logcat quand Google Maps est ouvert:
02-20 17:12:08.204: V/LocationManagerService(1733): getAllProviders
Je suppose que Google Maps est également un appel removeUpdates() et requestLocationUpdates() à nouveau pour obtenir une nouvelle position.
Donc je pense qu'il n'y a pas de solution et c'est le meilleur que vous pouvez faire si vous voulez obtenir les emplacements d'un réseau de plus de un en 45 secondes.
removeUpdates(..)
et puisrequestLocationUpdates(..)
.NETWORK_PROVIDER
utilise des cellules de la tour de la triangulation et wi-fi. 45 deuxième limitation sur le WiFi ne serait pas nécessairement se traduire par un 45-deuxième limitation surNETWORK_PROVIDER
globale.J'ai eu un problème similaire. J'ai mis un appel à
locationManager.requestSingleUpdate()
à la fin deonLocationChanged()
et forcée dos à dos les mises à jour. Vous pouvez définir un retard de commande, puis d'exécuterrequestSingleUpdate
, en s'assurant d'inscrire le contenantlocationListener
.J'ai essayé de créer une horloge GPS, mais les mises à jour étaient incompatibles mise à jour de n'importe où de 1 à 5 secondes. mais il peut travailler pour une autre application.