Подтвердить что ты не робот

Android - Wake Up and Unlock Device

Описание приложения: Приложение предназначено как программа обеспечения безопасности для конкретного клиента (не публиковаться публично). Если приложение не обнаружило движение в течение определенного периода времени, приложение должно подать сигнал тревоги и выйти на передний план, если оно находится в фоновом режиме или устройство спит.

Проблема: Если устройство спит и заблокировано, нам необходимо просыпаться и разблокировать устройство. Используя различные методы, найденные здесь в SO и других местах, мы смогли (частично) разбудить и разблокировать устройство, однако это ТОЛЬКО ведет себя правильно, когда устройство физически подключено к компьютеру. Если устройство сидит самостоятельно, отключается, и мы проверяем разблокировку после пробуждения, ничего не происходит; устройство, похоже, продолжает спать, и приложение, похоже, ничего не делает (без тревоги).

Я использовал этот пост об использовании PowerManager и KeyguardManager и этот пост, используя флаги окна.

Вот код, используемый для пробуждения устройства:

public void wakeDevice() {
    PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
    wakeLock.acquire();

    KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
    KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG");
    keyguardLock.disableKeyguard();
    runOnUiThread(new Runnable(){
        public void run(){
            getWindow().addFlags(
                      WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);                
        }
    });
}

Из комментариев и сообщений о некоторых других вопросах SO, которые я видел/использовал, кажется, что код PowerManager/KeyguardManager должен был сделать трюк. Опять же, как я уже говорил, он технически работает, когда устройство подключается через USB к машине dev, но ничего не делает, пока устройство разделено.

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

Короче говоря, учитывая приведенный выше код, почему устройство ведет себя так по-разному, основываясь на том, подключено ли оно, и что мы должны изменить, чтобы разбудить и разблокировать устройство, как описано? Заранее благодарю вас за помощь!

4b9b3361

Ответ 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();
}