Android - Как я могу разбудить телефон от тяжелого сна, чтобы сделать снимок? - PullRequest
9 голосов
/ 07 марта 2011

Я хочу делать снимки с камеры устройства Android периодически в течение нескольких часов, чтобы создать эффект замедленного видео.

Я установил Диспетчер тревог с флагом AlarmManager.RTC_WAKEUP, чтобы запускать службу каждые несколько минут.

Служба удерживает частичную блокировку, выполняет некоторую работу, а затем вызывает приемник вещания через диспетчер аварийных сигналов, который запускает действие.

Действие создается (или возобновляется), включает собственный пробуждение и устанавливает поверхность предварительного просмотра камеры. Как только поверхность настроена, вызывается метод SurfaceChanged () слушателя SurfaceHolder, который в итоге делает снимок.

Если устройство работает, все работает отлично, как и ожидалось. Но если устройство находится в спящем режиме, после того, как метод onResume () класса Activity завершен, действие немедленно приостанавливается. Поверхность предварительного просмотра камеры никогда не завершает инициализацию, и изображение никогда не будет снято.

Итак, у меня есть следующие вопросы:

  1. Есть ли способ программно разбудить телефон? Я даже пытаюсь использовать:

    PowerManager powerManager =
                (PowerManager)this.getSystemService(Context.POWER_SERVICE);
    powerManager.userActivity(SystemClock.currentThreadTimeMillis(),false);
    

Но это не разбудит телефон, если он спит.

  1. Можно ли сделать снимок без предварительного просмотра поверхности?

  2. Есть ли способ сделать снимок, который не зависит от асинхронных обратных вызовов? Могу ли я поместить весь код в метод Activity onResume () для создания снимка?

  3. Есть ли способ сохранить метод onResume () в Activity достаточно долго, чтобы у предварительного просмотра камеры было достаточно времени для инициализации и вызова всех слушателей?

Я правильно использую wakelocks, и у меня все права доступа правильно установлены в файле манифеста. Моя активность не дремлет достаточно долго, чтобы асинхронные слушатели могли нормально работать.

И, чтобы усугубить проблему, я пытаюсь сделать все, что совместимо с Android 1.6, потому что это единственное тестовое устройство, к которому у меня есть доступ.

Это неприятно!

Ответы [ 3 ]

8 голосов
/ 07 марта 2011

Я наконец-то добрался где-то сейчас.

Я должен создать wakelock, используя эти два флага

PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ACQUIRE_CAUSES_WAKEUP

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ACQUIRE_CAUSES_WAKEUP, "bbbb");
wl.acquire();

Затем устройство просыпается и запускается на экране клавиатуры.

Но единственный способ пройти через экран клавиатуры и сделать снимок - это использовать эти флаги в окне действия:

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

Но это доступно только в Android 2.0 и не работает в 1.6.

2 голосов
/ 29 марта 2011

Вы также можете отключить экран Keyguard с помощью

KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
km.newKeyguardLock(TAG).disableKeyguard();

, если у вас есть разрешение DISABLE_KEYGUARD.

Доступно с API уровня 1.

0 голосов
/ 07 марта 2011

Вы делаете что-то подобное в вашем методе onResume

.... onResume() {
    ....
    WakeLock myWakeLock = .....;
    ...
}

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

...