在安全的Android锁定屏幕中使用FLAG_SHOW_WHEN_LOCKED和disableKeyguard()

Edm*_*d C 25 android android-intent

上下文

最近,我一直在寻找可靠的方法来控制安全的Android Keyguard.主要是显示自定义锁屏.我知道谷歌已经声明平台没有正式支持自定义锁定屏幕,并且应该预期事情会破裂,但是,对于现有的API,我相信必须有办法实现这一点.我做了大约一周的研究,但仍然存在问题.假设已启用安全的Keyguard,到目前为止,我已实现了

  • WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED允许在屏幕上显示活动(窗口),将Keyguard放在后面,并防止所有不安全的操作.通知面板被禁用,完成活动将调出键盘.我在锁屏活动中实现了如下.

    @Override
    public void onAttachedToWindow() {
        window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • KeyguardManager,KeyguardManager.KeyguardLock已弃用的类,但它们仍然一直工作到Jelly Bean.要做到这一点,我有一个Service处理两件事,拿着一个静态KeyguardManager和相关的对象,让它持有一个BroadcastReceiver接收Intent.ACTION_SCREEN_ONIntent.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;
        }
}
Run Code Online (Sandbox Code Playgroud)

对于 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

因为LockScreenActivity,当用户输入正确的密码时,

window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
ScreenReceiverService.disableKeyguard();
finish();
Run Code Online (Sandbox Code Playgroud)

问题

  • 有用的东西

    • ACTION_ON并且ACTION_OFF可靠地收到.
    • LockScreenActivity显示在Keyguard之前(尚未处理电话状态)
    • 通知无法下拉,以任何方式退出活动都会显示锁屏.
  • 事情不起作用

    • 禁用Keyguard并调用finish()后,我的应用程序退出并显示主屏幕或屏幕关闭前的最后一个活动.但是,每当我按下Home键时,键盘将闪烁进入屏幕,立即快速解除,并且不处理正常的Home键功能/事件(闪烁后不会返回主屏幕).当我反复快速敲击Home键时观察到这种情况.

我甚至查看了Android源代码以找出Home Key处理,但它永远不会发送到第三方应用程序,除非窗口类型是WindowManager.LayoutParams.TYPE_KEYGUARD或者WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,即使它在早期平台上运行,它也会在4.0+上引发SecurityException.而对于Keyguard,我已经宣布DISABLE_KEYGUARD许可使用这应该不是问题.我的猜测是标志FLAG_SHOW_WHEN_LOCKED会告诉系统以Keyguard某种方式处理与其他禁用调用冲突的方式.由于此标志主要用于警报/短信类型应用程序,即向用户显示有限的信息,然后解雇自己并调出Keyguard.但在我的情况下,让用户解锁我的锁定屏幕,然后解锁系统锁定屏幕只是打败了我的应用程序的目的.

所以问题是为什么Keyguard每当我禁用它后按Home 就会闪烁?针对此问题是否有解决方法/解决方案?

PS感谢您阅读这么长的问题.这是我第一次在这里提问,如果有什么我做错了,请告诉我(即格式,语法,代码约定,标签等).此外,我没有任何编程知识的经验,我开始使用Android之前我知道Java是什么.所以我还没有采取任何正确的课程/培训,这个社区很棒,经常帮助像我这样的人,即使他们是简单的问题,当然看Google I/O视频,阅读博客,阅读别人的代码对我很有帮助.所以请容忍任何愚蠢的错误/明显的错误/愚蠢的问题.我只有16岁.^ _ ^"

dro*_*kar 15

我已经在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);
}
Run Code Online (Sandbox Code Playgroud)


Sup*_*hks 0

WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 允许在屏幕上显示活动(窗口),将 Keyguard 放在后面

我试图得到这个,但我的活动总是先于系统锁定屏幕。isOrderdBroadcast() 表示 ACTION_SCREEN_NO 是有序广播。

我向活动添加了标志:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
Run Code Online (Sandbox Code Playgroud)

在 onAttachedView() 中。但系统锁定仍然优先于我的自定义屏幕锁定活动。

您是如何获取系统锁定屏幕之前的活动的?

编辑 事后看来,我认为我对锁屏概念的理解是错误的。我的广播接收器首先收到广播。但之前显示的是收到 SCREEN_OFF 消息时启动的系统锁定屏幕。目前已修复该问题。

但被主页按钮行为的模糊性所困扰。这在后 ICS 设备中不会成为问题,因为不鼓励使用所有硬按钮。