背景 最近,我一直在寻找可靠的方法来控制安全的Android Keyguard,主要是为了显示自定义锁屏。我知道Google已经声明自定义锁屏不受平台官方支

背景

最近,我一直在寻找可靠的方法来控制安全的Android Keyguard,主要是为了显示自定义锁屏。我知道Google已经声明自定义锁屏不受平台官方支持,并且应该预料到可能会有问题,但是通过现有的API,我相信必须有方法可以实现这一点。我进行了大量的研究约一周时间,但仍然偶尔遇到问题。截至目前,我的实现方式是假定启用了安全的Keyguard:

WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 允许一个Activity(窗口)显示在屏幕上,将Keyguard放在其后,所有不安全的操作都被防止了。通知面板被禁用,结束该Activity会带回Keyguard。这是我在我的锁屏Activity中实现的方式:

@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并调用了finish()方法之后,我的应用程序退出并显示到主屏幕或屏幕关闭之前的最后一个活动。但是,每当我按Home键时,Keyguard会刷入屏幕,立即快速消失,并且正常的Home键功能/事件不被处理(闪烁后不会返回到主屏幕)。这种情况是在我快速重复点击Home键时观察到的。

我甚至看了Android源代码以找出Home键的处理方式,但除非窗口类型为WindowManager.LayoutParams.TYPE_KEYGUARD或WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,否则不会将其发送给第三方应用程序,在4.0+上甚至会抛出SecurityException异常,尽管它在早期平台上运行正常。对于Keyguard,我已声明了DISABLE_KEYGUARD权限,因此这不应该是问题。我猜测标志FLAG_SHOW_WHEN_LOCKED会告诉系统以某种方式处理Keyguard,可能与其他禁用调用冲突。由于此标志通常用于Alarm/SMS类型的应用程序,即向用户显示有限信息,然后将其关闭并显示Keyguard。但在我的情况下,让用户解锁我的锁屏然后解锁系统锁屏就完全失去了我应用的意义。

所以问题是,为什么我禁用Keyguard后按Home键时Keyguard会闪现?是否有任何解决此问题的变通方法/解决方案?

P.S. 谢谢您阅读这么长的问题。这是我第一次在这里提问,如果我做错了什么,请告诉我(例如格式、语法、代码约定、标签等)。而且我没有任何编程知识的经验,在了解Java之前就开始接触Android。所以我还没有接受任何适当的课程/培训,这个社区非常棒,经常帮助像我这样的人解决简单的问题,当然还有观看Google I/O视频、阅读博客、阅读其他人的代码。这些都帮助了我很多。所以请容忍任何愚蠢的错误/显而易见的错误/愚蠢的问题。我只有16岁。^_^"