上下文
最近,我一直在寻找可靠的方法来控制安全的 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
处理两件事的 a ,持有一个静态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
并调用完成()后,我的应用程序退出并显示主屏幕或屏幕关闭前的最后一个活动。但是,每当我按下 Home 键时,Keyguard 都会闪烁到屏幕中,并立即快速自行关闭,并且不处理正常的 Home 键功能/事件(闪烁后不会返回主屏幕)。当我反复快速点击 Home 键时会观察到这种情况。
- 在我禁用
我什至查看了 Android 源代码以找出 Home Key 处理,但它永远不会发送到第三方应用程序,除非窗口类型是WindowManager.LayoutParams.TYPE_KEYGUARD
or WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
,这将在 4.0+ 上抛出 SecurityException ,即使它在早期平台上工作。对于Keyguard
,我已经声明DISABLE_KEYGUARD
允许使用这不应该是问题。我的猜测是该标志FLAG_SHOW_WHEN_LOCKED
会告诉系统以Keyguard
某些与其他禁用调用冲突的方式进行处理。由于此标志主要用于警报/短信类型的应用程序,即向用户显示有限的信息,然后关闭自己并调出Keyguard
. 但在我的情况下,让用户解锁我的锁屏然后解锁系统锁屏只会破坏我的应用程序的目的。
所以问题是为什么Keyguard
在我禁用它后每当我按 Home 时都会闪烁?此问题是否有任何解决方法/解决方案?
PS 感谢您阅读这么长的问题。这是我第一次在这里提问,如果我做错了什么,请告诉我(即格式,语法,代码约定,标签等)。我也没有任何编程知识的经验,在我知道 Java 是什么之前,我就开始使用 Android。所以我还没有参加任何适当的课程/培训,这个社区很棒并且经常帮助像我这样的人,即使他们是简单的问题,当然观看谷歌 I/O 视频、阅读博客、阅读其他人的代码对我有很大帮助. 所以请容忍任何愚蠢的错误/明显的错误/愚蠢的问题。我才16岁。^_^"