14

几年前,我编写了一个可在 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:以编程方式删除或禁用三星 Galaxy S2 设备上的锁定屏幕

如何显示全屏 TYPE_SYSTEM_ALERT 窗口?

如何创建在锁定屏幕顶部可见的 Activity

如何启动无需解锁屏幕即可点击的对话框(如闹钟关闭/贪睡)

默认锁定屏幕上的 Android 活动

android 设备已锁定,但希望警报响起并出现对话框

锁定屏幕上的 Android 对话框

在 Android 2.3 的锁屏上显示带有触摸事件的对话框

是否有人对可能导致此问题的 Android 4 中的更改有任何想法?

编辑:这是我见过的警报对话框中最简单的示例之一,它没有出现“最小化”。如所写,它不会出现在锁定屏幕上,但您可以使用以下方法修复它WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED

http://wptrafficanalyzer.in/blog/setting-up-alarm-using-alarmmanager-and-waking-up-screen-and-unlocking-keypad-on-alarm-goes-off-in-android/

它是用 FragmentActivity 和 DialogFragment 编写的,但它仍然可以作为 Activity 工作。它使用 AlertDialog.Builder 来制作对话框,如果您尝试使用 XML 布局进行操作,它将无法正常工作。为什么?

4

5 回答 5

18

我想通了,答案与我的预期大相径庭。

这段代码包含在 Android 2 的闹钟示例的 AlarmAlert.java 活动中:

@Override
protected void onStop() {
    super.onStop();
    // Don't hang around.
    finish();
}

作为参考,您可以在此处查看Git 过去的示例代码中的文件,其中包含上述onStop函数。它从未在 Android 2 中引起问题。

但在 Android 4 中,如果手机处于关机状态,它onStop会在手机唤醒之前立即触发,从而有效地“最小化”Activity。一旦我删除了此功能,它立即再次起作用。

但我想知道,这是像 @radley 和 @Guardanis 这样的其他人遇到的问题吗?这似乎不太可能,但如果这也解决了您的问题,请告诉我。

如果您将来访问此答案,并且遇到此问题,我会尝试的是:

  1. 取出任何onStop功能。

  2. 将此代码添加到活动中:

    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);
    
  3. 确保您使用的是全屏主题,而不是对话框主题。

  4. 这对我来说没有什么不同,但您可以尝试在清单中明确设置 showOnLockScreen:<activity android:name="com.example.MyActivity" android:showOnLockScreen="true"/>

  5. 第二件事对我没有影响,但您可以尝试添加标志WindowManager.LayoutParams.FLAG_FULLSCREEN

我希望这对其他人有帮助!

于 2014-01-15T11:01:21.900 回答
4

在科特林,

对于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 测试了这段代码,并且像魅力一样工作!

于 2019-08-07T14:08:27.440 回答
3

不确定这是否是所有情况下的问题,但 ShowWhenLocked 上的文档说它仅适用于最顶部的全屏窗口。我有一个以对话框为主题的窗口,它不起作用,但是一旦我将其更改为常规的全屏窗口,它就可以正常工作。

于 2013-12-12T19:53:46.767 回答
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"
    >

默认锁定屏幕上的 Android 活动

于 2014-01-05T15:10:44.167 回答
1

对 - 所以我最近一直在努力解决这个问题,但使用的是 5.0.2 Galaxy Tab A。不出所料,适用于其他所有设备的功能不适用于三星(自第一款三星 Galaxy 设备以来就是这种情况,他们打破了一些新的东西每次发布!)

在大多数设备的锁定屏幕上显示 Activity 的一般解决方案是

//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存在,三星似乎不会打扰。我的应用程序需要设置锁定屏幕,因此删除关闭键盘保护标志实际上允许我在锁定屏幕上显示全屏活动。对我来说是,对三星来说不是。

于 2016-02-29T09:44:16.287 回答