我正在编写一个Android应用程序,其主要功能是跟踪用户的位置,并在用户接近某个点时发出警报。因此,我需要定期更新用户的位置,并且当用户接近目标时,这些间隔应该变小。因此,当用户位于目标1公里范围内时,我希望每20秒更新一次该位置,依此类推,直到用户到达。
当我对其进行测试时(provider = LocationManager.NETWORK_PROVIDER
),使用任何requestLocationUpdates(provider, minTime, minDistance, locationListener)
调用minTime < 45000
与minTime = 45000
具有相同的效果,即我获得的间隔为< em>完全 45秒
我知道最小时间参数只是一个“提示”,但它不是我的应用程序提示。我得到指定间隔的更新,直到该间隔超过45秒。似乎位置更新之间的最短时间为45秒,硬编码到Android中,但这有点奇怪。另外我以前从未听说过这个问题,而且我无法在Stackoverflow上找到它。
由于我无法获得频繁的更新,我的解决方法(目前)是在需要新位置时手动调用requestLocationUpdates
,然后只使用第一个可用位置。为了在较短的时间间隔执行此操作,我使用handler.postDelayed(myRunnable, updateInterval)
来延迟来电,然后myRunnable
负责调用requestLocationUpdates
。但是,这种方法只占50%(显然是随机的)时间。
有没有人知道这个问题,有没有办法解决它?或者我是唯一可以选择设置minTime = 0
并希望最好的选择?
以下是myRunnable的源代码,我使用run()
定期手动调用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.
}
这是我的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;
}
}
};
整个位置更新服务在服务中运行。
我已多次阅读该文档,谷歌解决了这个问题,并尝试了其他各种解决方法。什么都没有。
我已经记录了这个该死的东西,唯一令人兴奋的事情是我的频繁位置请求的一个大胖子“忽略”。所有正确的方法都被称为。
任何帮助非常赞赏!
答案 0 :(得分:18)
你是完全正确的,在Android中对最小时间45秒进行了编码。
这似乎是一个NetworkLocationProvider类源代码,当它仍在Android核心中时:
查看变量:
private static final long MIN_TIME_BETWEEN_WIFI_REPORTS = 45 * 1000; // 45 seconds
方法:
@Override
public void setMinTime(long minTime) {
if (minTime < MIN_TIME_BETWEEN_WIFI_REPORTS) {
mWifiScanFrequency = MIN_TIME_BETWEEN_WIFI_REPORTS;
} else {
mWifiScanFrequency = minTime;
}
super.setMinTime(minTime);
}
现在NetworkLocationProvider不在Android核心中,您可以在/ system / app中的NetworkLocation.apk中找到它
你可以在这里找到解释为什么不在核心的解释:
https://groups.google.com/forum/?fromgroups=#!topic/android-platform/10Yr0r2myGA
但是45秒的时间似乎仍然存在。 看看这个NetworkProvider反编译:
.line 149
const-wide/32 v4, 0xafc8
iput-wide v4, p0, Lcom/google/android/location/NetworkLocationProvider;->mWifiScanFrequency:J
正如您可能猜到的,如果将0xafc8转换为十进制,则会得到45000毫秒
我还没有找到为什么45秒的解释。我想有一些理由可以避免服务超载或者他们不想要的其他用途。
事实上,Geolocation API有100个请求礼貌限制:
https://developers.google.com/maps/documentation/business/geolocation/#usage_limits
但他们似乎并不尊重Google地图应用中的此规则。如果您打开它并且只有活动的网络位置,您可以注意到您的位置更新频率超过45秒。
当谷歌地图开放时,我注意到这条线在logcat中经常出现频繁(每秒33次):
02-20 17:12:08.204:V / LocationManagerService(1733):getAllProviders
我猜Google地图也会再次调用removeUpdates()和requestLocationUpdates()来获取新职位。
所以我认为没有解决办法,如果你想在45秒内获得一个网络位置,这是你能做的最好的。
答案 1 :(得分:7)
您可以将minTime设置为任何值。但是,只有在新位置可用时,您才会获得更新。网络只在我拥有的每部手机上每隔45秒左右更新一次。这似乎是网络提供商的限制。如果您想要更频繁的更新,请使用GPS提供商。根据GPS硬件的不同,您应该获得大约4Hz的最大更新速率。
答案 2 :(得分:0)
我遇到了类似的问题。我在locationManager.requestSingleUpdate()
结束时拨打了onLocationChanged()
,并强制退回更新。您可以设置延迟命令然后执行requestSingleUpdate
,确保注册包含locationListener
。
我正在尝试创建GPS时钟,但更新不一致,更新时间从1-5秒左右。但它可能适用于其他应用程序。