Android : LocationManager 动态调整 minTime/minDistance 阈值

Posted

技术标签:

【中文标题】Android : LocationManager 动态调整 minTime/minDistance 阈值【英文标题】:Android : LocationManager dynamically adjust minTime/minDistance thresholds 【发布时间】:2011-04-02 06:24:26 【问题描述】:

这是我收听 GPS 位置更新的方式(使用 LocationManagerLocationListener):

locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
listener = new MyLocationistener(); // LocationListener
locationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER, 
        30000, // milliseconds (minTime)
        20, // meters (minDistance)
        listener );

但我想动态调整LocationManager#requestLocationUpdates 使用的minTimeminDistance 参数。我的目标是根据几项使用政策来节省电池,即:

如果用户没有移动,则增加 minTime 以获取位置更新 如果用户移动速度非常快,请增加 minDistance 如果用户在室内(没有 GPS 覆盖范围),请同时增加两者 如果电池电量过低,请同时增加两者 ...(任何其他启发式)

我想知道:

    这真的是节省电池寿命的好主意吗? 如何进行这种调整?如果有唯一的选择,我可以再次致电LocationManager#removeUpdatesLocationManager#requestLocationUpdates。 您知道实现这种自适应算法的任何想法或示例代码吗?

编辑:该应用程序是一个跟踪系统,用于了解人们的位置,以便将任务分配给离给定位置最近的人。实际上电池几乎不能持续 8 小时,所以我想增加它。

【问题讨论】:

有趣的问题虽然我帮不上什么忙。我认为节省电池是个好主意。我倾向于说你建议的解决方案是唯一的,但我不是位置 API 方面的专家,所以我会让其他人说话。 [我在我的应用程序中使用了相同的代码,但它没有返回任何值,想知道是否有任何人可以帮助我...][1] [1]:@ 987654321@ 删除和添加,就像这样:***.com/questions/5385094/… 【参考方案1】:

AFAIK 您需要再次致电 removeUpdatesrequestLocationUpdates

此外,您还可以研究其他方法来查看手机是否在移动,例如加速度计。阅读 here 和 see this other question's answers

但是为了给你更多的想法,你需要提出问题本身。不要尝试过早优化,直到没有问题为止。如果有,您需要发布有关它的详细信息。

【讨论】:

谢谢。这是一个内部应用程序,用户几乎没有技术技能,所以他们不知道什么是 GPS,强迫他们更改设置或打开和关闭 GPA 无线电存在可用性问题。电池现在可以使用 8-10 小时,我们需要将其延长到至少 12 小时。【参考方案2】:

这真的是节省电池寿命的好主意吗?

可能不会。 AFAIK,GPS 收音机将一直打开,这是您所描述的最大的电池消耗。节省电池的方法是删除更新,因此 GPS 无线电会关闭。但是,下次您请求位置更新时,GPS 需要一些时间才能获得其初始定位。

如果用户在室内(没有 GPS 覆盖),则同时增加两者

如果您无法获得 GPS 定位,请关闭无线电,并在几分钟后重试(或根据 UI 事件或其他原因)。如果 GPS 对您没有任何好处,那么让 GPS 处于开启状态是没有意义的。

如果电池电量过低,请同时增加

如果电池电量过低,请关闭 GPS。要么切换到低功耗供应商(使用Criteria 查找),要么不使用位置数据。让用户通过偏好来决定什么是“太低”。

【讨论】:

谢谢。您认为什么时候最好保持 GPS 收音机打开(比关闭再打开要好)。秒,分钟?我的意思是,如果我需要每 30 秒修复一次,最好保持它打开,但如果您需要每 5 分钟修复一次,那就不是真的了。 您不能以编程方式打开 GPS,您的用户需要为您打开它。您可以向他们展示设置屏幕。 为了回答您需要多久轮询一次数据,请提供更多详细信息。比如你使用位置数据是为了什么? @Pentium10:为了减少混淆并匹配 android 文档,我使用“启用”和“禁用”来表示用户通过设置控制的内容,并使用“开启”和“关闭”来指代GPS 无线电是否正在消耗电力并获得修复。 @Guido:正如 Pentium10 所指出的,很难在摘要中回答你。请记住,刚刚打开 GPS 需要一段时间才能获得修复。因此,如果您需要每 5 分钟进行一次修复,但您必须立即进行这些修复,您可能无法关闭 GPS。就个人而言,我会让用户在这里通过偏好做出尽可能多的决定。【参考方案3】:

我做过这样的事情:

我有一个 LocationService(扩展 Service 并实现 LocationListener)。我添加了

locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 1, 1, this);

在 onLocationChangedListener 中:

    public void onLocationChanged(Location location) 
        AlarmManager aleManager = (AlarmManager) LocationService.context.getSystemService(ALARM_SERVICE);
//Change the values of MINIMIUM_TRIGGER_TIME and INTERVAL_TIME
        Intent forceLoc = new Intent(LocationService.context,
                ForceLocationService.class);
        PendingIntent pendingForceLoc = PendingIntent.getService(
                LocationService.context, 0, forceLoc,
                PendingIntent.FLAG_ONE_SHOT);
        // CANCEL PREVIOUS alarm and set new one
        aleManager.cancel(pendingForceLoc);
        aleManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                MINIMIUM_TRIGGER_TIME, INTERVAL_TIME, pendingForceLoc);
    

并在 ForceLocationService(扩展 IntentService)中触发常规位置侦听器,如下所示:

locMan=(LocationManager)getSystemService(LOCATION_SERVICE);
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 1, locationService);

这让我可以做到以下几点:

    如果系统在alarmManager触发ForceLocationService之前获取到任何位置更新,它会自动获取更新并重置警报。

    如果直到警报触发才获得更新,则它会强制触发警报,从而确保我们在需要时获得更新。

我唯一的问题是,如果位置没有变化导致警报重置是在 onLocationChanged() 中完成的,则它不起作用。

【讨论】:

以上是关于Android : LocationManager 动态调整 minTime/minDistance 阈值的主要内容,如果未能解决你的问题,请参考以下文章

Android之LocationManager

Android - 使用 LocationManager 不会提供地理修复

Android:LocationManager 构造函数的循环器

当我得到 LocationManager 时发生异常。(Android)

Android开发之LocationManager和定位

[Android-Location]无法从LocationManager获取经纬度