我正在编写一个Android应用程序,其主要功能是跟踪用户的位置,并在用户接近某个点时发出警报.因此,我需要定期更新用户的位置,并且当用户接近目标时,这些间隔应该变小.因此,当用户位于目标1公里范围内时,我希望每20秒更新一次该位置,依此类推,直到用户到达为止.
当我测试它(provider = LocationManager.NETWORK_PROVIDER),以调用requestLocationUpdates(provider, minTime, minDistance, locationListener)任何minTime < 45000具有相同的效果minTime = 45000,也就是我获得更新与间隔正好 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.
}
Run Code Online (Sandbox Code Playgroud)
这是我的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;
}
}
};
Run Code Online (Sandbox Code Playgroud)
整个位置更新事物在服务中运行.
我已多次阅读该文档,谷歌解决了这个问题,并尝试了其他各种解决方法.什么都没有.
我已经把这个该死的东西记录下来了,唯一令人兴奋的事情是我的频繁位置请求"忽略"了.调用所有正确的方法.
任何帮助将非常感谢!
djp*_*ado 18
你完全正确,Android的最小时间是45秒.
这似乎是一个NetworkLocationProvider类源代码,当它仍然在Android核心时:
看看变量:
private static final long MIN_TIME_BETWEEN_WIFI_REPORTS = 45 * 1000; // 45 seconds
Run Code Online (Sandbox Code Playgroud)
方法:
@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);
}
Run Code Online (Sandbox Code Playgroud)
现在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
Run Code Online (Sandbox Code Playgroud)
正如您可能猜到的,如果将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 Maps也会再次调用removeUpdates()和requestLocationUpdates()来获取新位置.
所以我认为没有解决办法,如果你想在45秒内获得一个网络位置,这是你能做的最好的事情.
您可以将minTime设置为任何值.但是,只有在新位置可用时,您才会获得更新.网络只在我拥有的每部手机上每隔45秒左右更新一次.这似乎是网络提供商的限制.如果您想要更频繁的更新,请使用GPS提供商.根据GPS硬件的不同,您应该获得大约4Hz的最大更新速率.
| 归档时间: |
|
| 查看次数: |
24616 次 |
| 最近记录: |