Разбудить Android-устройство

Эй, мне нужно разбудить мое спящее устройство Android в определенное время. Какие-либо предложения?

P.S. Просыпайтесь: включите дисплей и, возможно, разблокируйте телефон


person Coxer    schedule 01.09.2010    source источник


Ответы (8)


Лучше всего использовать подходящую комбинацию этих флагов окна:

http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_DISMISS_KEYGUARD
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SHOW_WHEN_LOCKED
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_TURN_SCREEN_ON

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

ОДНО ВАЖНОЕ ПРИМЕЧАНИЕ. Ваша активность должна быть полноэкранной, чтобы указанная выше комбинация флажков работала. В своем приложении я пытался использовать эти флаги с активностью, которая не является полноэкранной (тема диалога), и это не сработало. Изучив документацию, я обнаружил, что эти флаги требуют, чтобы окно было полноэкранным.

person hackbod    schedule 02.09.2010
comment
Есть ли у вас какие-либо мысли об альтернативном пути? - person Coxer; 02.09.2010
comment
API-интерфейсы KeyguardManager и PowerManager для прямого управления ими. Но использовать их очень сложно... на самом деле, я бы сказал, что идеально использовать их для такого рода вещей невозможно. Это одна из причин, по которой были введены флаги. - person hackbod; 03.09.2010
comment
Это не работает для меня. Я добавил эти флаги в onCreate моей активности, вызываемой моим BroadcastReceiver, в свою очередь вызываемой AlarmService. Код вызывается, но экран остается черным. - person Yar; 16.04.2012
comment
@hackbod, один важный комментарий спас мне день. Бесконечно благодарен! - person Thomas; 28.03.2013
comment
У @Yar и у меня такая же проблема. У меня полноэкранное окно, но экран остается выключенным и заблокированным. Требует ли этот подход каких-либо разрешений. Я чувствую, что что-то упускаю, но нашел здесь следующее примечание (developer.android.com/reference/android/view/). Системные окна (от FIRST_SYSTEM_WINDOW до LAST_SYSTEM_WINDOW) — это особые типы окон, используемые системой для определенных целей. Обычно они не должны использоваться приложениями, и для их использования требуется специальное разрешение. - person Forrest Bice; 21.05.2014
comment
это решение не работает со мной, устройство все еще находится в спящем режиме - person Muhammed Refaat; 10.04.2016

Чтобы включить экран:

PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
wakeLock.acquire();

Чтобы снять блокировку экрана:

KeyguardManager keyguardManager = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE); 
KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG");
keyguardLock.disableKeyguard();

И манифест должен содержать:

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />

Дополнительные сведения о PowerManager см. в документации по API: http://developer.android.com/reference/android/os/PowerManager.html

EDIT: этот ответ считается устаревшим.

person Yar    schedule 16.04.2012
comment
Верхние 2 блока кода относятся к onCreate() Activity. Нижний блок кода, очевидно, относится к манифесту Android. - person Yar; 06.12.2012
comment
Спасибо Яр. Кстати, в Индии друга зовут Яр. Так что спасибо мой друг. Это очень помогло. - person Chintan Raghwani; 19.04.2013
comment
SCREEN_BRIGHT_WAKE_LOCK и FULL_WAKE_LOCK теперь устарели. Предлагается FLAG_KEEP_SCREEN_ON (см. выбранный ответ). - person loeschg; 27.11.2013
comment
Спасибо за это. KeyguardLock и WakeLock устарели в более новых версиях Android, и вместо этого рекомендуется использовать флаги окна, но мне нужно было разбудить и разблокировать экран из служебного приложения, в котором нет активности или окна, поэтому ваше решение было то, что мне нужно. - person Josh Davis; 13.02.2016
comment
Также этот код проходит два уровня блокировки пробуждения, что запрещено документами. Вы должны выбрать один или другой. Уровни блокировки пробуждения: PARTIAL_WAKE_LOCK, FULL_WAKE_LOCK, SCREEN_DIM_WAKE_LOCK и SCREEN_BRIGHT_WAKE_LOCK. Ровно один уровень блокировки пробуждения должен быть указан как часть параметра levelAndFlags. - person Daniel Lubarov; 15.11.2016
comment
Этот ответ устарел - person Neon Warge; 23.10.2017
comment
Возможно. Google должен что-то менять каждые 5 минут. - person Yar; 23.10.2017
comment
Это все еще работает для меня на API 24 (Android 7.0 Nougat) - person daka; 24.10.2018

Я нашел способ, и он не такой сложный... работает с любой версией API.

Вам нужно использовать метод PowerManager.userActivity(l, false) и зарегистрировать свою активность как трансляцию, полученную для намерения SCREEN_OFF:

В вашей деятельности OnCreate поместите что-то вроде:

mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.v(TAG, "Screen OFF onReceive()");
        screenOFFHandler.sendEmptyMessageDelayed(0, 2000L);
    }
};

Он запустит обработчик через 2 секунды после события Screen Off.

Зарегистрируйте получателя в методе onResume():

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
Log.i(TAG, "broadcast receiver registered!");

Создайте обработчик, как показано ниже:

private Handler screenOFFHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {

        super.handleMessage(msg);
        // do something
        // wake up phone
        Log.i(TAG, "ake up the phone and disable keyguard");
        PowerManager powerManager = (PowerManager) YourActivityName.this
                .getSystemService(Context.POWER_SERVICE);
        long l = SystemClock.uptimeMillis();
        powerManager.userActivity(l, false);//false will bring the screen back as bright as it was, true - will dim it
    }
};

Запросить разрешение в файле манифеста:

<uses-permission android:name="android.permission.WAKE_LOCK" />

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

unregisterReceiver(mReceiver);
Log.i(TAG, "broadcast UNregistred!");
person mishkin    schedule 27.12.2010
comment
По какой-то причине я могу заставить код работать. Я пытаюсь заставить службу разблокировать экран, но по какой-то причине он не разблокируется. Должен ли код разбудить и разблокировать телефон через 2 секунды? Используя код выше, телефон просто блокируется после того, как я его заблокирую. - person Nick; 10.10.2011
comment
Проблема возникает после блокировки телефона. Экран ВЫКЛЮЧЕН. Отображается тег Log.V, а затем сообщается об отключении экрана -> Разбудите телефон и отключите клавиатуру. Затем он сидит около 30 секунд, а затем говорит, что Close() никогда не вызывался явно в базе данных - person Nick; 10.10.2011

Если вы показываете окно при пробуждении, вы можете легко заставить его работать, добавив несколько флагов в свою активность, не используя блокировку пробуждения.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_activity);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
person Lahiru Chandima    schedule 21.01.2017

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

class AlarmActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_alarm)

        // Keep screen always on, unless the user interacts (wakes the mess up...)
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

        setTurnScreenOn(true)
        setShowWhenLocked(true)

        (getSystemService(KeyguardManager::class.java) as KeyguardManager).requestDismissKeyguard(this,
            object: KeyguardManager.KeyguardDismissCallback(){
                override fun onDismissCancelled() {
                    Log.d("Keyguard", "Cancelled")
                }

                override fun onDismissError() {
                    Log.d("Keyguard", "Error")
                }

                override fun onDismissSucceeded() {
                    Log.d("Keyguard", "Success")
                }
            }
        )
    }
}

KeyguardManager.requestDismissKeyguard пробуждает устройство только в том случае, если перед этим был вызван сеттер setTurnScreenOn(true).

Я проверил это на своем устройстве Android Pie.

person Palm    schedule 21.03.2019

Установка будильника программно разбудит телефон (воспроизведет звук), и я думаю, что включение дисплея будет там вариантом.

Я не думаю, что будет открытый API, который автоматически разблокирует телефон.

person schar    schedule 01.09.2010
comment
если что-то из вашей активности появится на экране блокировки, и как только вы выйдете из него, экран блокировки будет там. Например, когда вы разговариваете по телефону. - person Nathan Schwermann; 02.09.2010

getWindow().addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);

отключит общую защиту клавиатуры и заставит устройство разблокироваться.

person Prativa    schedule 12.01.2014

Попробуйте использовать приведенный ниже код после setContentView(R.layout.YOUR_LAYOUT); в методе активности onCreate()

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        Log.d(TAG, "onCreate: set window flags for API level > 27");
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
                        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        KeyguardManager keyguardManager = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
        keyguardManager.requestDismissKeyguard(this, null);
        setShowWhenLocked(true);
        setTurnScreenOn(true);
    } else {
        Log.d(TAG, "onCreate: onCreate:set window flags for API level < 27");
        getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN
                        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    }
person Rajesh.k    schedule 11.08.2020