【发布时间】: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
-
首先尝试stackoverflow.com/questions/4459058/alarm-manager-example - 如果可行,请以它为基础。请注意,它只会在 onReceive 返回之前保持唤醒锁,如果您需要运行更长时间 - 获取自己的
标签: android geolocation