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

Использование 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();

Проблема

  • Вещи, которые работают

    • ACTION_ON и ACTION_OFF принимаются надежно.
    • LockScreenActivity отображается перед Keyguard (без обработки состояния телефона еще)
    • Уведомление не может быть снято, выход из операции каким-либо образом отобразит блокировку экрана.
  • Вещи, которые не работают

    • После отключения Keyguard и завершения вызова(), мое приложение выходит и работает на рабочем столе или последнее действие перед отключением экрана. Тем не менее, всякий раз, когда я нажимаю клавишу "Домой", Keyguard будет мигать на экране, быстро отбрасывая себя немедленно, и нормальная функция/событие Home Key не обрабатывается (после мигания не вернется к главному экрану). Это наблюдается, когда я быстро постучал по главному ключу.

Я даже изучил исходный код 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. ^ _ ^ "

4b9b3361

Ответ 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