安卓:LocationManager 动态调整 minTime/minDistance 阈值

9

这是我监听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覆盖范围),则两者都增加
  • 如果电池电量过低,则两者都增加
  • ...(任何其他启发式算法)

我想知道:

  1. 这样做真的是为了节省电池寿命吗?
  2. 我该如何进行这种调整?如果没有其他替代方案,我可以同时调用LocationManager#removeUpdatesLocationManager#requestLocationUpdates
  3. 您知道如何实现此类自适应算法的任何想法或示例代码吗?

编辑:该应用程序是一个跟踪系统,用于确定人们的位置,以便将任务分配给最靠近特定点的人。实际上,电池几乎只能持续8小时,因此我想将其增加。


虽然我不能提供太多帮助,但这是一个有趣的问题。我认为节省电池电量是个好主意。我倾向于说你提出的解决方案是唯一可行的,但对于位置API我不是专家,所以我会让其他人来发言。 - Sephy
我在我的应用程序中使用了相同的代码,但它没有返回任何值,想知道是否有人能帮助我... - user1242295
移除和添加,就像这样:https://stackoverflow.com/questions/5385094/change-mintime-for-gps-locationlistener-dynamically - jp1017
3个回答

4
据我所知,您需要再次调用removeUpdatesrequestLocationUpdates。此外,您可以尝试其他方法来查看手机是否在移动,例如使用加速度计。在这里阅读相关信息,并查看此问题的其他答案。但是,为了给您更多想法,您需要介绍问题本身。不要过早优化,直到您遇到问题。如果您有问题,需要发布详细信息。

谢谢。这是一个内部应用程序,用户技术能力有限,因此他们不知道什么是GPS,并且强制更改设置或开关GPA无线电存在可用性问题。目前电池续航时间为8-10小时,我们需要将其延长至至少12小时。 - Guido

1
我做过类似这样的事情:
我有一个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);

这让我能够做到以下几点:

  1. 如果系统在alarmManager触发ForceLocationService之前获得任何位置更新,它会自动获取更新并重置闹钟。

  2. 如果在闹钟触发之前没有收到更新,则强制触发闹钟,从而确保我们在需要时获得更新。

我唯一的问题是,如果位置没有变化,则无法工作,因为闹钟的重置是在onLocationChanged()中完成的。


1
这真的是一个节省电池寿命的好主意吗?
可能不是。据我所知,GPS无线电将一直处于打开状态,并且在您描述的情况下这是最大的电池耗尽。要节省电池,请删除更新,以便GPS无线电关闭。但是,下次请求位置更新时,GPS需要一些时间来获取其初始固定。
如果用户在室内(没有GPS覆盖),增加两者
如果无法获得GPS定位,关闭无线电,并在一些分钟后再尝试(或基于UI事件或其他内容)。如果GPS对您没有任何帮助,则没有意义让GPS保持开启。
如果电池电量过低,则增加两者
如果电池电量过低,请关闭GPS。要么切换到低功率提供程序(使用“Criteria”找到一个),要么不使用位置数据。让用户通过首选项决定什么是“太低”。

谢谢。你认为保持GPS电台开启的时间更好(比关闭并再次打开更好)。是几秒钟还是几分钟?我的意思是,如果我需要每30秒修正一次,那么保持它开启可能更好,但如果您需要每5分钟修正一次,则不是这样。 - Guido
1
你不能通过编程打开GPS,你的用户需要为你打开它。你只能向他们展示设置屏幕。 - Pentium10
为了回答你需要多频繁地轮询数据的问题,请给我们更多细节。比如,你是用位置数据做什么? - Pentium10
1
为了减少混淆,并与Android文档相匹配,我使用“启用”和“禁用”来表示用户通过设置控制的内容,“开”和“关”则指GPS无线电是否正在消耗电力并获取修复。 - CommonsWare
@Guido:正如Pentium10所指出的,抽象地回答这个问题是很困难的。请记住,在GPS刚被打开后需要一段时间才能获取位置信息。因此,如果您需要每隔5分钟获取位置信息,并且需要立即获得这些信息,那么您可能无法关闭GPS。就我个人而言,我会尽可能让用户通过偏好设置来做出尽可能多的决定。 - CommonsWare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接