Блокировка по вторжению отключена на переднем плане с использованием режима Doze - новая оптимизация батарей в Android M

Это, по-видимому, полудокументированное поведение, если комментарии Dianne Hackborn на пост G + "документированы": https://plus.google.com/+AndroidDevelopers/posts/94jCkmG4jff, но передними службами связанное с значком уведомления, должно быть разрешено сохранять блокировку во время доза.

Кажется, что это недействительно, когда у вас есть активность в дополнение к службе переднего плана.

Я создал минимальную реализацию, которая демонстрирует это: https://github.com/petrnalevka/dozetest/blob/master/src/com/urbandroid/doze/DozeService.java

Проблема может быть воспроизведена на
Android M, MRA58K Nexus 5 и MRA58N Nexus 6

У моего сервиса переднего плана есть связанное уведомление, и я выполняю частичную блокировку слежения. К сожалению, режим "Доза" берет верх, и мой замок блокировки нарушен. Я смог предотвратить это, отказавшись от оптимизации батареи или оставив верхнюю активность.

Я считаю, что это ошибка в Android, так как нет причин, по которым услуги переднего плана должны содержать блокировку слежения, но не если они работают сверху.

Я помещаю эту проблему в SO, даже если я уже сообщал об этом на треке Androdi issue здесь https://code.google.com/p/android/issues/detail?id=193802, чтобы найти обходные пути как это критическая функция, чтобы не требовать REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, которая, по-видимому, в настоящий момент означает только REQUEST_REMOVAL_FROM_PLAYSTORE_BY_GOOGLE.

Вот как я смог воспроизвести проблему с помощью adb благодаря подсказкам + Dianne Hackborn:

Кажется, что когда я сохраняю Activity на переднем плане, имея также службу переднего плана, запускающую мое приложение, диспетчер Power Manager распознает как:

PARTIAL_WAKE_LOCK              'Doze lock' DISABLED (uid=10112, pid=24649, ws=null)  
Proc # 0: fore  F/A/TS trm: 0 24649:com.urbandroid.doze/u0a112 (top-activity)  

Если я нажму на дом и оставлю действие, я попаду в состояние:

PARTIAL_WAKE_LOCK              'Doze lock' (uid=10112, pid=24649, ws=null)  
Proc # 4: prcp  F/S/SF trm: 0 24649:com.urbandroid.doze/u0a112 (fg-service)  

Ответ 1

Это ответ Dianne Hackborn, представленный под https://plus.google.com/+AndroidDevelopers/posts/94jCkmG4jff. Тем не менее мы можем провести мозговой штурм более обходных путей здесь, поскольку разделение процессов может быть не всегда простым.

Диана Хакборн: + Петр Налевка Извините, что это похоже на ошибку в платформе. Я посмотрю, как это исправится, когда это возможно.

Ваша работа вокруг в правильном направлении, но, пожалуйста, не делайте этого, перемещая свое состояние на экране вкл./выкл. Хорошо, что можно переместиться на спину и сделать это, когда экран выключится... однако очень сложно заставить себя на фронт, когда экран включается, потому что он может включаться по другим причинам (до запуск камеры, голосовое взаимодействие и т.д.). На самом деле это, вероятно, то, что платформа должна лучше защищать себя.

То, что я предлагаю, - это прослушивание режима доз, чтобы начать, и просто поместив вашу деятельность на задний план. Вы можете это сделать, прослушивая широковещательную передачу http://developer.android.com/reference/android/os/PowerManager.html#ACTION_DEVICE_IDLE_MODE_CHANGED и отправляя себя обратно, когда вы видите, что простоя устройства верны. Я бы предложил просто не беспокоиться о том, чтобы попытаться вернуться на передний план - в случае, когда пользователь на самом деле не использовал свое устройство в течение длительного времени, и это происходит, возвращаясь к нему и находясь дома не должно быть неожиданностью.

EDIT (Dianne Hackborn): На самом деле, другое решение - ваша служба переднего плана запускается в другом процессе, чем действие. Из того, что я вижу, все будет хорошо. Мне было бы интересно узнать, есть ли у вас желаемое поведение.

И это на самом деле наша рекомендуемая практика для этой ситуации - если у вас долговременная служба переднего плана, она должна быть в отдельном процессе от действия, поэтому она не заставляет всю память, связанную с активностью чтобы их держали. (Вот почему эта ошибка прошла, все наши приложения используют этот шаблон.)