Эй, мне нужно разбудить мое спящее устройство Android в определенное время. Какие-либо предложения?
P.S. Просыпайтесь: включите дисплей и, возможно, разблокируйте телефон
Эй, мне нужно разбудить мое спящее устройство Android в определенное время. Какие-либо предложения?
P.S. Просыпайтесь: включите дисплей и, возможно, разблокируйте телефон
Лучше всего использовать подходящую комбинацию этих флагов окна:
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
Если вы хотите работать на более старых версиях платформы, которые не поддерживают нужные флаги, вы можете напрямую использовать блокировки пробуждения и блокировки клавиатуры... но этот путь чреват опасностью.
ОДНО ВАЖНОЕ ПРИМЕЧАНИЕ. Ваша активность должна быть полноэкранной, чтобы указанная выше комбинация флажков работала. В своем приложении я пытался использовать эти флаги с активностью, которая не является полноэкранной (тема диалога), и это не сработало. Изучив документацию, я обнаружил, что эти флаги требуют, чтобы окно было полноэкранным.
Чтобы включить экран:
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: этот ответ считается устаревшим.
SCREEN_BRIGHT_WAKE_LOCK
и FULL_WAKE_LOCK
теперь устарели. Предлагается FLAG_KEEP_SCREEN_ON
(см. выбранный ответ).
- person loeschg; 27.11.2013
Я нашел способ, и он не такой сложный... работает с любой версией 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!");
Если вы показываете окно при пробуждении, вы можете легко заставить его работать, добавив несколько флагов в свою активность, не используя блокировку пробуждения.
@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);
}
На более новых устройствах вы должны использовать что-то подобное, поскольку упомянутые флаги устарели.
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.
Установка будильника программно разбудит телефон (воспроизведет звук), и я думаю, что включение дисплея будет там вариантом.
Я не думаю, что будет открытый API, который автоматически разблокирует телефон.
getWindow().addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
отключит общую защиту клавиатуры и заставит устройство разблокироваться.
Попробуйте использовать приведенный ниже код после 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);
}