Ответ 1
Я решил проблему. Причина, по которой мы наблюдали различное поведение при подключении устройства через USB, заключалась в том, что процессор устройства не спал. Я предполагаю, что это либо результат настройки режима отладки, либо просто то, как он ведет себя при подключении к компьютеру, поскольку энергосберегающая функция спящего режима процессора не имеет значения. Очевидно, что когда устройство не подключено, процессор будет счастливо вздремнуть, и, хотя мы наблюдаем, как приложение работает случайно (оно пробуждалось бы в произвольное время), время было бы непоследовательным. Я также предполагаю, что это связано с тем, что несколько циклов процессора, которые произошли, распределены экономно, и нашему приложению будет дано очень мало циклов в "случайные" времена.
Итак, наше решение состояло в том, чтобы захватить частичную блокировку следования, когда устройство переходит в фоновый режим (который выполняется в методе onPause
), и отпустите блокировку в методе onResume
. Кажется, это мешает процессору спать. Мы продолжаем использовать полную блокировку слежения и блокировку клавиатуры, чтобы разбудить устройство, когда нам нужно. Использование частичного блокирования следа, по-видимому, не позволяет процессору спать, и устройство, похоже, нормально проснется, когда ожидается. Вот наш обновленный код, если кто-нибудь столкнется с этой проблемой:
// Called from onCreate
protected void createWakeLocks(){
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
fullWakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Loneworker - FULL WAKE LOCK");
partialWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Loneworker - PARTIAL WAKE LOCK");
}
// Called implicitly when device is about to sleep or application is backgrounded
protected void onPause(){
super.onPause();
partialWakeLock.acquire();
}
// Called implicitly when device is about to wake up or foregrounded
protected void onResume(){
super.onResume();
if(fullWakeLock.isHeld()){
fullWakeLock.release();
}
if(partialWakeLock.isHeld()){
partialWakeLock.release();
}
}
// Called whenever we need to wake up the device
public void wakeDevice() {
fullWakeLock.acquire();
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG");
keyguardLock.disableKeyguard();
}