如何持续追踪安卓手机的位置?
Posted
技术标签:
【中文标题】如何持续追踪安卓手机的位置?【英文标题】:How to continuously track the location of an Android mobile phone? 【发布时间】:2013-08-18 02:31:56 【问题描述】:我需要编写一个应用程序,它每 5 分钟确定一次手机的当前位置(使用所有免费、可用的位置提供程序)并将其发送到服务器。
如果某些位置提供程序在应用程序启动时不起作用,但稍后可用,则应用程序也应处理其位置数据。
为了做到这一点,我实现了以下课程。在我的一项活动中,我创建了它的一个实例并调用它的startTrackingUpdates
方法。 locationChangeHandler
处理位置数据。
public class LocationTracker implements ILocationTracker, LocationListener
public static final long MIN_TIME_BETWEEN_UPDATES = 1000 * 60 * 5; // 5 minutes
public static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
private ILocationManager locationManager;
private ILocationChangeHandler locationChangeHandler;
public LocationTracker(final ILocationManager aLocationManager,
final ILocationChangeHandler aLocationChangeHandler)
this.locationManager = aLocationManager;
this.locationChangeHandler = aLocationChangeHandler;
public void startTrackingUpdates()
final List<String> providers = locationManager.getAllProviders();
for (final String curProviderName : providers)
final ILocationProvider provider = locationManager.getLocationProvider(curProviderName);
if (!provider.hasMonetaryCost())
subscribeToLocationChanges(provider);
private void subscribeToLocationChanges(final ILocationProvider aProvider)
locationManager.requestLocationUpdates(aProvider.getName(), MIN_TIME_BETWEEN_UPDATES,
(float)MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
public void onLocationChanged(final Location aLocation)
locationChangeHandler.processLocationChange(new LocationWrapper(aLocation));
public void onProviderDisabled(final String aProvider)
public void onProviderEnabled(final String aProvider)
public void onStatusChanged(final String aProvider, final int aStatus,
final Bundle aExtras)
我构建了应用程序并将其安装在我的手机上。然后,早上我拿起手机,去上班,然后回家。在家查看应用程序一天工作的结果,发现数据库中只有一条记录。
如果系统的其余部分(将位置数据传输到服务器,保存在数据库中)工作正常,我的位置跟踪代码肯定有问题(onLocationChanged
没有被调用,即使我更改了我的多次定位)。
我的代码有什么问题(我应该如何更改它,以便在电话位置变化超过 MIN_DISTANCE_CHANGE_FOR_UPDATES
米时根据定位提供商之一调用 onLocationChanged
)?
更新 1(18.08.2013 13:59 MSK):
我根据msh 的建议更改了我的代码。我使用以下代码启动计时器:
public void startSavingGeoData()
final IAlarmManager alarmManager = activity.getAlarmManager();
final IPendingIntent pendingIntent = activity.createPendingResult(
ALARM_ID, intentFactory.createEmptyIntent(), 0);
alarmManager.setRepeating(INTERVAL, pendingIntent);
在activity
中我放置了以下计时器事件处理程序:
@Override
protected void onActivityResult(final int aRequestCode, final int aResultCode,
final Intent aData)
geoDataSender.processOnActivityResult(aRequestCode, aResultCode,
new IntentWrapper(aData));
当手机打开时,一切都按预期工作 - onActivityResult
在 INTERVAL
毫秒内执行一次。
但是当我按下电源按钮(屏幕被禁用)时,onActivityResult
根本没有被调用。当我再次按下电源按钮时,onActivityResult
会执行多次,因为INTERVAL
自我关闭手机以来已经过去了。如果我关闭手机1 * INTERVAL
毫秒,它会触发一次。如果我将手机关机2 * INTERVAL
毫秒,它会触发两次等。
注意:“关闭”是指短按电源按钮(例如,手机仍然“活着”并对传入的 SMS 做出反应)。
我应该如何修改startSavingGeoData
的代码,以使onActivityResult
方法每INTERVAL
毫秒执行一次,即使手机处于休眠状态?
更新 2(18.08.2013 19:29 MSK):alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 0, INTERVAL, pendingIntent)
和 alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, INTERVAL, INTERVAL, pendingIntent)
都没有解决问题。
【问题讨论】:
报警类型必须是_WAKEUP常量之一,例如RTC_WAKEUP 首先尝试***.com/questions/4459058/alarm-manager-example - 如果可行,请以它为基础。请注意,它只会在 onReceive 返回之前保持唤醒锁,如果您需要运行更长时间 - 获取自己的 【参考方案1】:您的代码可能是正确的,但是当您的手机处于睡眠状态时,位置提供程序没有运行。您可能需要获取唤醒锁(如果您不关心功耗),或者使用 AlarmManager 并安排您的应用程序定期唤醒并检查位置(在等待更新时您仍然需要激活唤醒锁,或者由 AlamManager 或您自己获得)。
【讨论】:
我更改了代码(请参阅“更新 1”),但它仍然无法按预期工作。有什么想法吗? 您可以将警报代码基于此示例***.com/questions/4459058/alarm-manager-example 是的,这个例子有效,至少在手机休眠时,获取位置的方法也会被执行。 每当警报响起时(例如每 5 分钟)我必须执行subscribeToLocationChanges
是真的吗?
如果位置提供程序停止后订阅丢失,我不会感到惊讶。您确定您等待的时间足够长以接收更新并在等待期间保持部分唤醒锁吗?以上是关于如何持续追踪安卓手机的位置?的主要内容,如果未能解决你的问题,请参考以下文章