在打盹模式下获取位置更新

时间:2017-09-16 13:36:09

标签: android locationmanager android-gps android-doze

我在打盹模式下尝试在我的Android应用程序中获取位置更新,这用于Android 5.x。随着android 6和打瞌睡的出现,无论我做什么,更新都会在某个时刻停止。在阅读了关于该主题的一些文章和stackoverflow答案之后,我做了以下更改:

  • 使我的服务成为前台服务
  • 使服务保持部分唤醒锁
  • 我已经为我的应用程序提供了WAKE_LOCK权限
  • 使服务在一个单独的进程中运行(对于一些android错误的解决方法)
  • 我已停用我的应用的电池优化

但是,我仍然没有在打瞌睡时获得位置更新。我已经确认我的服务线程在打瞌睡时保持运行(通过定期记录消息),但不知何故位置管理器停止发送更新。关于doze和LocationManager的文档在这方面相当不足,所以我想知道是否有人知道如何让位置管理器在打瞌睡中保持活力?在LocationManager上是否有一些方法,如果定期调用将使LocationManager保持活动状态? 请注意,我只对GPS更新感兴趣,更新频率很高,每秒一次。

3 个答案:

答案 0 :(得分:2)

最后我找到了解决这个问题的方法,在阅读了com.android.internal.location.GpsLocationProvider的源代码后,我注意到发送了一个com.android.internal.location.ALARM_WAKEUP意图阻止了位置提供者打瞌睡。因此,为了防止GPS打瞌睡,我每隔10秒广播一次意图,我在服务类中添加了以下内容:

[...]
private Handler handler;
private PowerManager powerManager;

private PendingIntent wakeupIntent;
private final Runnable heartbeat = new Runnable() {
    public void run() {
        try {
            if (isRecording && powerManager != null && powerManager.isDeviceIdleMode()) {
                LOG.trace("Poking location service");
                try {
                    wakeupIntent.send();
                } catch (SecurityException | PendingIntent.CanceledException e) {
                    LOG.info("Heartbeat location manager keep-alive failed", e);
                }
            }
        } finally {
            if (handler != null) {
                handler.postDelayed(this, 10000);
            }
        }
    }
};

@Override
public void onCreate() {
    handler = new Handler();
    wakeupIntent = PendingIntent.getBroadcast(getBaseContext(), 0,
        new Intent("com.android.internal.location.ALARM_WAKEUP"), 0);
    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    powerManager = (PowerManager) getSystemService(POWER_SERVICE);
    wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TrackService");
    [...]
}

答案 1 :(得分:0)

您的应用程序的行为正是doze旨在停止的行为。 Android 6中引入的Doze通过将活动推迟到维护窗口来降低设备的功耗。 GPS是一种巨大的功耗,不允许在打盹模式下持续运行。如果允许这样做,电池可能会以与屏幕相似的速率耗尽;网络流量的优化不会延长电池寿命。如果您希望每1秒更新一次GPS位置,则必须停止设备进入打盹模式。

Android 5中没有打盹模式。

答案 2 :(得分:0)

如果您使用“ adb shell dumpsys deviceidle force-idle”等命令在模拟器上测试位置和打ze模式。您可能会注意到位置在打ze模式下停止。

但是...因为“文档”代表:

用户只要通过移动设备,打开屏幕或连接充电器来唤醒设备系统就会退出Doze ,并且所有应用都将恢复正常活动”

来源:https://developer.android.com/training/monitoring-device-state/doze-standby

因此...使用GPS游戏杆应用程序或类似设备移动模拟器,您会注意到位置从打Do模式中醒来。