几年前,我写了一个适用于Android 2的闹钟应用程序,我现在正尝试升级它以在Android 4上运行。具体来说,在三星Galaxy S4上。
在Android 2上,如果手机正在睡眠,它会唤醒手机并在锁定屏幕上显示“暂停或关闭”屏幕。
在Android 4上,它会唤醒手机,但您必须将其解锁,然后打开通知区域,然后点击闹钟的通知,然后才能点击“关闭”。
我一直在使用此代码进行清醒:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
我已经阅读了8个关于此问题的不同stackoverflow问题。他们中的大多数都给出了上面的代码,这在几年前在Android 2中起作用,但在Android 4中不起作用。但是他们都没有帮助我解决这个问题。以下是我阅读和尝试过的问题:
Android: remove or disable programmatically the Lock Screen on Samsung Galaxy S2 device
How to display a fullscreen TYPE_SYSTEM_ALERT window?
How do I create an Activity that is visible on top of the lock screen
How to start a dialog (like alarm dimiss /snooze) that can be clicked without unlocking the screen
Android activity over default lock screen
android device locked, yet want alarm to sound and dialog to appear
Android dialog over lock screen
Show dialog with touch events over lockscreen in Android 2.3
有没有人对Android 4中可能导致此更改的内容有任何想法?
编辑:这是我见过的一个最简单的例子,它没有出现“最小化”的警报对话框。它没有像写的那样出现在锁屏上,但您可以使用WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
它是用FragmentActivity和DialogFragment编写的,但它仍然可以作为Activity使用。它使用AlertDialog.Builder来创建对话框,如果您尝试使用XML布局,它将无法工作。为什么呢?
答案 0 :(得分:17)
我明白了,答案与我的预期完全不同。
这段代码包含在Android 2的闹钟示例中,在AlarmAlert.java活动中:
@Override
protected void onStop() {
super.onStop();
// Don't hang around.
finish();
}
作为参考,您可以在Git过去的right here中看到示例代码中的文件,其中包含上述onStop
函数。它从未在Android 2中引起过问题。
但是在Android 4中,如果手机关闭,这个onStop
会在手机醒来之前启动,有效地“最小化”活动。一旦我删除了这个功能,它立即再次工作。
但我想知道,这是其他人喜欢@radley和@Guardanis的问题吗?这似乎不太可能,但如果这也解决了你的问题,请告诉我。
如果您将来访问此答案,并且您遇到此问题,我会尝试的是:
取出所有onStop
个功能。
将此代码添加到活动:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
确保您使用的是全屏主题,而不是对话框主题。
这对我没什么影响,但您可以尝试在清单中明确设置showOnLockScreen:<activity android:name="com.example.MyActivity" android:showOnLockScreen="true"/>
第二件事对我没什么影响但是你可能会尝试添加标志WindowManager.LayoutParams.FLAG_FULLSCREEN
我希望这有助于其他人!
答案 1 :(得分:3)
不确定这是否是所有情况下的问题,但ShowWhenLocked上的文档说它仅适用于最顶层的全屏窗口。我有一个主题为对话框的窗口无效,但是一旦我将其更改为常规全屏窗口,它就能正常工作。
答案 2 :(得分:2)
您链接的其中一个问题有一个似乎可以解决此问题的答案。
这是我正在使用的代码似乎正在运行:
@Override
public void onAttachedToWindow() {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onAttachedToWindow();
}
我还在清单中的活动定义中明确声明了这一点:
<activity
android:name="com.example.MyActivity"
android:label="@string/app_name"
android:showOnLockScreen="true"
>
答案 3 :(得分:1)
正确 - 所以我最近一直在努力解决这个问题,但是使用5.0.2 Galaxy Tab A.不出所料,在其他所有设备上运行的功能都不适用于三星(自第一款三星Galaxy设备以来就是这种情况,他们打破每个版本的新东西!)
大多数设备在锁定屏幕上显示活动的一般解决方案是
//wake up device and show even when on lock screen
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_FULLSCREEN);
然而,这对于三星设备不起作用。然而,删除FLAG_DISMISS_KEYGUARD
就是这个伎俩。
查看此标志的文档,我们有
窗口标记:设置窗口时,只有当它不是安全锁定键盘锁时才会解除锁定。由于安全性不需要这样的键盘锁,因此如果用户导航到另一个窗口,它将永远不会重新出现(与FLAG_SHOW_WHEN_LOCKED相反,后者只会暂时隐藏安全和非安全的键盘保护,但确保在用户移动到的时候再次出现另一个不隐藏它们的UI)。如果键盘锁当前处于活动状态且安全(需要解锁图案),则用户在看到此窗口之前仍需要确认它,除非还设置了FLAG_SHOW_WHEN_LOCKED。
和FLAG_SHOW_WHEN_LOCKED
我们有
窗口标志:在屏幕显示时显示窗口的特殊标志 锁定。这将使应用程序窗口优先于密钥 警卫或任何其他锁屏。可以与FLAG_KEEP_SCREEN_ON一起使用 在显示按键之前打开屏幕并直接显示窗口 守卫窗口。 可以自动与FLAG_DISMISS_KEYGUARD一起使用 完全取消非安全密钥保护。此标志仅适用于 最顶层的全屏窗口。
你可以看到它们可以一起使用但是如果设备被锁定并且FLAG_SHOW_WHEN_LOCKED
存在,那么三星似乎不会打扰FLAG_DISMISS_KEYGUARD
。我的应用程序需要设置锁定屏幕,因此删除dismiss keyguard标志实际上允许我通过锁定屏幕显示全屏活动。对我来说,不管是三星。
答案 4 :(得分:0)
在科特林,
对于 Api级别28 或更低,您只需在需要打开的活动中添加以下方法即可:
override fun onAttachedToWindow() {
super.onAttachedToWindow()
toBeShownOnLockScreen()
}
private fun toBeShownOnLockScreen() {
window.addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setTurnScreenOn(true)
setShowWhenLocked(true)
} else {
window.addFlags(
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
)
}
}
要使其在 Android Pie及更高版本上运行,除了上述步骤外,我们还需要在AndroidManifest中进行设置:
<activity
android:name=".view.activity.LockScreenActivity"
android:showOnLockScreen="true"
android:showWhenLocked="true"
android:turnScreenOn="true" />
我已经测试了从Api 21到29级的这段代码,并且像魅力一样工作!