Использование FLAG_SHOW_WHEN_LOCKED с отключеннымKeyguard() в защищенном экране блокировки Android
Контекст
Недавно я искал надежные способы управления защищенной Android Keyguard. В основном для отображения пользовательского экрана блокировки. Я знаю, что Google заявила, что пользовательские блокировки блокировки официально не поддерживаются платформой и должны ожидать, что что-то сломается, но с существующими API-интерфейсами, я считаю, что должны быть способы сделать это. Я провел много исследований около недели, но все еще имею проблемы здесь и там. Что я реализовал, если включен защищенный Keyguard, до сих пор,
-
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED позволяет отображать активность (окно) на экране, помещать Keyguard позади и предотвращать все небезопасные действия. Панель уведомлений отключена, при завершении операции появится Keyguard. Я выполнил следующие действия в активности блокировки экрана.
@Override
public void onAttachedToWindow() {
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
-
KeyguardManager
, KeyguardManager.KeyguardLock
- устаревшие классы, но они все еще работают до Jelly Bean. Для этого у меня есть Service
, который обрабатывает две вещи, сохраняя статический KeyguardManager
и связанные объекты, и держите BroadcastReceiver
для приема Intent.ACTION_SCREEN_ON
и Intent.ACTION_SCREEN_OFF
. (все объекты инициализируются должным образом)
Для ScreenReceiver
public static synchronized void disableKeyguard() {
if ( isLocked ) {
if ( keyguardLock == null ) {
keyguardLock = keyguardManager.newKeyguardLock(LOG_TAG);
}
keyguardLock.disableKeyguard();
isLocked = false;
}
}
public static synchronized void reenableKeyguard() {
if ( !isLocked ) {
if ( keyguardLock == null ) {
keyguardLock = keyguardManager.newKeyguardLock(LOG_TAG);
}
keyguardLock.reenableKeyguard();
keyguardLock = null;
isLocked = true;
}
}
Для BroadcastReceiver
@Override
public void onReceive( Context context, Intent intent ) {
if ( intent.getAction().equals(Intent.ACTION_SCREEN_ON) ) {
Intent start = new Intent(context, LockScreen.class);
start.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(start);
} else if ( intent.getAction().equals(Intent.ACTION_SCREEN_OFF) ) {
ScreenReceiverService.reenableKeyguard();
}
}
Для LockScreenActivity
, когда пользователь вводил правильный пароль,
window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
ScreenReceiverService.disableKeyguard();
finish();
Проблема
Я даже изучил исходный код Android, чтобы узнать, как обрабатывать Home Key, но он никогда не отправляется сторонним приложениям, если только тип окна не является WindowManager.LayoutParams.TYPE_KEYGUARD
или WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
, что вызовет SecurityException на 4.0+ даже он работал на более ранних платформах. А для Keyguard
я объявил использование разрешения DISABLE_KEYGUARD
, это не должно быть проблемой. Я предполагаю, что флаг FLAG_SHOW_WHEN_LOCKED
будет сообщать системе обрабатывать Keyguard
в некотором роде, что противоречило бы с другими запрещающими вызовами. Поскольку этот флаг используется главным образом для приложения типа "будильник/SMS", который должен показывать пользователю ограниченную информацию, затем отпустите себя и поднимите Keyguard
. Но в моем случае, когда пользователь разблокирует мой экран блокировки, тогда разблокировать системный lockscreen просто поражает цель моего приложения.
Итак, вопрос в том, почему мигает Keyguard
, когда я нажимаю "Дом" после того, как я отключил его? Есть ли способ обхода/решения для этой проблемы?
P.S. Спасибо, что прочитали такой длинный вопрос. Это мой первый вопрос, задающий здесь вопрос, если есть что-то, что я сделал неправильно, скажите мне (например, формат, грамматика, условное обозначение кода, теги и т.д.). Также у меня не было опыта программирования каких-либо знаний, я начал с Android, прежде чем я знаю, что такое Java. Таким образом, я еще не прошел надлежащий курс/обучение, это сообщество удивительно и часто помогает людям, как я, даже если они простые вопросы, и, конечно, просмотр видео входов/выходов Google, чтение блогов, чтение кода других, мне очень помогает, Поэтому, пожалуйста, терпите любые глупые ошибки/очевидные ошибки/глупые вопросы. Я всего лишь 16. ^ _ ^ "
Ответы
Ответ 1
Я использовал это с некоторым успехом как в Gingerbread, так и в ICS, чтобы открыть свою активность (через фоновый сервис, который его запускает). В запуске:
@Override
public void onAttachedToWindow() {
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
Ответ 2
У меня была такая же проблема при нажатии кнопки HOME при разблокировке устройства. Это можно решить, переведя пароль в пустой (т.е. ""):
DevicePolicyManager devicePolicyManager;
ComponentName demoDeviceAdmin;
devicePolicyManager.setPasswordQuality(demoDeviceAdmin,DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
devicePolicyManager.setPasswordMinimumLength(demoDeviceAdmin, 0);
devicePolicyManager.resetPassword("",DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
а затем отключить keygaurd:
this.keyGuardLock = ((KeyguardManager)getSystemService("keyguard")).newKeyguardLock("keyguard");
keyGuardLock.disableKeyguard();
Надеюсь, это решило вашу проблему.\m/сохранить кодировку!
Ответ 3
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED разрешает действие (a окно), которое будет отображаться на экране, помещая Keyguard в положение
Я попытался получить это, но моей активности всегда предшествовал экран блокировки системы. isOrderdBroadcast() говорит, что ACTION_SCREEN_NO является упорядоченной трансляцией.
Я добавил флаг в действие:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
в onAttachedView(). Но все же системный замок получает предпочтение по сравнению с моей пользовательской активностью блокировки экрана.
Как вы получили свою активность до экрана блокировки системы?
ИЗМЕНИТЬ
Оглядываясь назад, я думаю, что мое понимание концепции экрана блокировки было неправильным. Мой вещательный приемник сначала получил трансляцию. Но перед этим показывался экран блокировки системы, который был запущен при приеме SCREEN_OFF. Исправлена проблема на данный момент.
Но в тупик от двусмысленности поведения кнопки на дом. Это не будет проблемой для почтовых устройств ICS, так как все жесткие кнопки не рекомендуется.
Ответ 4
В вашей LockScreenActivity, заканчивая код проверки finish();
, убивает LockscreenActivity и, следовательно, все приложение. Вместо этого вы можете просто запустить свою основную деятельность (или любую другую) следующим образом:
startActivity(new Intent(LockScreenActivity.this, MainActivity.class));
Ответ 5
Если AOSP находится под вашим контролем, вам нужно установить простой флаг, а keyguard() ушел навсегда.
Вот подробности для этого, войдите в файл
"Наложение/рамки/база/пакеты/SystemUI/RES/значения/config.xml"
и найдите "config_enableKeyguardService", затем установите флаг в false.
НЕТ БОЛЬШЕ keyGuard, pheww