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

时间:2012-08-06 06:11:21

标签: android android-intent

上下文

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

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

    @Override
    public void onAttachedToWindow() {
        window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    }
    
  • KeyguardManagerKeyguardManager.KeyguardLock是不推荐使用的类,但它们仍然可以一直运行到Jelly Bean。要做到这一点,我有一个Service来处理两件事,包含静态KeyguardManager和相关对象,并让BroadcastReceiver接收Intent.ACTION_SCREEN_ON和{{} 1}}。 (所有对象都已正确初始化)


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可靠地收到。
    • LockScreenActivity显示在键盘锁之前(尚未处理电话状态)
    • 无法撤消通知,以任何方式退出活动都会显示锁屏。
  • 不起作用的事情

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

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

所以问题是,为什么在我禁用它后按{Home}时Keyguard会闪烁?针对此问题是否有解决方法/解决方案?

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

5 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:1)

解锁设备时,单击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 /继续编码!

答案 2 :(得分:0)

  

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

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

我在活动中添加了标记:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
在onAttachedView()中

。但是系统锁定仍然取决于我的自定义屏幕锁定活动。

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

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

但是由于主页按钮行为的模糊性而难倒。这在后ICS设备中不会成为问题,因为不鼓励使用所有硬按钮。

答案 3 :(得分:0)

在您的LockScreenActivity中,finish();结束验证代码会导致LockscreenActivity,从而导致整个应用程序崩溃。而不是那样,你可以像这样启动你的主要活动(或任何其他):

startActivity(new Intent(LockScreenActivity.this, MainActivity.class));

答案 4 :(得分:0)

如果AOSP在您的控制之下,那么您需要设置简单标志并且keyguard()已经消失了。 这是详细信息,进入文件 "覆盖/框架/碱/包/ SystemUI / RES /值/ config.xml的" 并搜索" config_enableKeyguardService"然后将标志设置为false。

没有更多的keyGuard,pheww