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

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

>使我的服务成为前台服务
>使服务保持部分唤醒锁定
>我已经给了我的应用程序WAKE_LOCK权限
>使服务在一个单独的进程中运行(针对某些android bug的变通方法)
>我已停用我的应用程序的电池优化

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

最佳答案 最后,我通过阅读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");
    [...]
}
点赞