14

A few years ago, I wrote an alarm app that worked on Android 2, and I'm now trying to upgrade it to work on Android 4. Specifically, on the Samsung Galaxy S4.

On Android 2, if the phone was sleeping, it would wake the phone up and display a "Snooze or Dismiss" screen over the lock screen.

On Android 4, it wakes the phone up, but you have to unlock it, then open the notifications area, then click the alarm's notification, before you can hit "Dismiss."

I have always been using this code to do the waking:

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);

I have read 8 different stackoverflow questions on this matter. Most of them give the code above, which worked for me years ago in Android 2 but doesn't work in Android 4. But none of them have helped me solve this problem. Here are the questions that I read and tried:

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

Does anyone have any ideas about what's changed in Android 4 that may have caused this?

EDIT: Here is one of the simplest examples I've seen of an alarm dialog that doesn't come up "minimized." It does not, as written, appear over the lockscreen, but you can fix that with 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/

It's written with a FragmentActivity and a DialogFragment, but it still works as an Activity. It uses an AlertDialog.Builder to make the dialog, and if you try to do it with an XML layout, it won't work. Why?

Community
  • 1
  • 1
howrad
  • 1,006
  • 2
  • 12
  • 30
  • you have set this permission in manifest?? --> – bofredo Sep 25 '13 at 11:48
  • Yep, that permission has always been set, and used to work on Android 2. – howrad Sep 25 '13 at 21:48
  • I tried something new. I set Screen Lock to None, but I'm still seeing the problem. To give a desktop computer analogy, it's like the dialog is starting up "minimized" -- you have to tap the alarm's notification before the dialog appears. When the phone is on, the dialog pops up as it should, but when the phone is off, the dialog starts minimized. And this wasn't a problem in Android 2.3 – howrad Sep 27 '13 at 08:52
  • It's not Android 4. It's a problem unique to the S4. I'm trying to track it down myself. We had it working at one point, but recently it stopped. – radley Oct 03 '13 at 03:08
  • radley, I'm not sure that it's unique to the S4, because when I try it on the Android 4 emulator, I see the same problem. – howrad Oct 04 '13 at 08:19
  • Does this article help anyone? It's one of the simplest examples I've seen of an alarm dialog that doesn't come up "minimized." It does not, as written, appear over the lockscreen, but you can fix that with `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/ It works by using a FragmentActivity and a DialogFragment. But why? Why won't this work with a full Activity? – howrad Oct 04 '13 at 11:45
  • Have you found any solution to this? I'm running into the exact same problem with my Lucid Dreamer app, but only with the Galaxy S4 and so far no other device... – Cruceo Oct 31 '13 at 15:58
  • @Cruceo, the only hackish solution I've found is to use AlertDialog.Builder to make the popup. No one has found a "real" solution yet. – howrad Oct 31 '13 at 16:34
  • @howrad Thanks, if only that were viable for me... I need to bring the full activity back up, not just an alert (although I may have to make due with that) – Cruceo Nov 03 '13 at 21:34
  • Please see my answer below for a solution to this stupid issue – Dori Feb 29 '16 at 09:44

5 Answers5

17

I figured it out, and the answer was very different from what I expected.

This piece of code was included in the alarm clock sample from Android 2, in the AlarmAlert.java Activity:

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

For reference, you can see the file from the example code in Git's past right here, containing the above onStop function. It never caused a problem in Android 2.

But in Android 4, if the phone was off, this onStop would fire right before the phone woke up, effectively "minimizing" the Activity. Once I removed this function, it immediately worked again.

But I wonder, is this the problem that other people like @radley and @Guardanis are getting? It seems unlikely, but please let me know if this fixes your problems too.

If you're visiting this answer in the future, and you're getting this problem, what I would try is:

  1. Take out any onStop functions.

  2. Add this code to the Activity:

    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. Make sure you're using a full screen theme, and not a dialog theme.

  4. This didn't make a difference for me, but you could try setting showOnLockScreen explicitly in the manifest: <activity android:name="com.example.MyActivity" android:showOnLockScreen="true"/>

  5. A second thing that didn't make a difference for me but you might try is adding the flag WindowManager.LayoutParams.FLAG_FULLSCREEN

I hope this helps other people!

howrad
  • 1,006
  • 2
  • 12
  • 30
  • 4
    Especially not using a dialog theme makes a difference! – bk138 May 06 '14 at 12:00
  • Does anyone know why onStop() is supposedly called on activities when the phone comes out of sleep? I'm observing this as well and it's causing issues when I want to place an activity in front of the lock screen. Any updates would be appreciated! – Forrest Bice May 21 '14 at 22:45
  • is there any alternative to the dialog theme? I want to show a message-box-like popup window over a locked screen, and I cant use the dialog theme, only fullscreen.. – Ofek Agmon May 23 '16 at 13:59
  • @OfekAgmon, I wrote in point #3: "Make sure you're using a full screen theme, and not a dialog theme." However, that was in 2014, and I'm not sure what the status of this is in current versions of Android. – howrad May 25 '16 at 14:23
  • @howrad I saw what you wrote, and its still an issue now (dialog themed activity can't be shown over locked screen). I was wondering if anybody has a good alternative for the Dialog theme, because I want the popup to not be a fullscreen, I want it to look like a incoming sms or whatsapp message, and the only way I found how to do it is using a dialog theme. any ideas? – Ofek Agmon May 25 '16 at 16:33
  • Thank you so much, any idea why onStop has been called ? – XcodeNOOB Dec 22 '16 at 12:36
  • 1
    @XcodeNOOB I don't know why it calls onStop() in this case, it doesn't make too much sense. But I think the superclass method Activity.onStop() doesn't cause a problem; I believe it's the finish() that causes the problem. Unless you're seeing something different? – howrad Dec 23 '16 at 04:39
3

Not sure if this is the problem in all cases, but the documentation on ShowWhenLocked says it applies only to the top-most full-screen window. I had a window themed as a dialog which was not working, but it worked fine once I changed it to a regular full-screen window.

  • In styles.xml, I set a parent of `android:Theme.DeviceDefault.Light.NoActionBar.Fullscreen`, and I added the flag `WindowManager.LayoutParams.FLAG_FULLSCREEN`, but it's still not working. Is there anything else I need to do to make it full-screen and working? – howrad Jan 11 '14 at 10:26
2

One of the questions you linked to has an answer that appeared to solve this issue for me.

This is the code I am using which appears to be working:

@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();
    }

I'm also explicitly declaring this in the activity definition in the manifest:

<activity 
    android:name="com.example.MyActivity"
    android:label="@string/app_name"
    android:showOnLockScreen="true"
    >

Android activity over default lock screen

Community
  • 1
  • 1
Ben Pearson
  • 6,882
  • 4
  • 28
  • 49
  • When dealing with a list of flags, using a + or a | _should_ produce the same result. Since all the flags are powers of two, bitwise OR and addition are equivalent, but using bitwise OR will be slightly faster. I also tested this specific example, and they both produce the integer value of 6815872. And neither of them fixes this issue on the Galaxy S4, sorry. – howrad Jan 11 '14 at 09:06
  • I tried your updated answer, but if the screen is off, the Activity still starts up essentially "minimized." You have to open the notification bar and click the notification to see it. Any other ideas about what I might be missing? – howrad Jan 15 '14 at 09:11
  • Are you using the fullscreen flag? – Ben Pearson Jan 15 '14 at 18:02
2

In Kotlin,

For Api level 28 or less, you can simply add below method in your activity that needs to be opened:

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
        )
    }
}

And to make it work on Android Pie and above, in additional to above step, we need to set in AndroidManifest as well:

<activity
    android:name=".view.activity.LockScreenActivity"
    android:showOnLockScreen="true"
    android:showWhenLocked="true"
    android:turnScreenOn="true" />

I have tested this code from Api level 21 to 29, and works like charm!

Chintan Soni
  • 22,543
  • 24
  • 96
  • 158
1

Right - So I have been struggling with this one recently but with a 5.0.2 Galaxy Tab A. Unsurprisingly what works on every other device does not work on Samsung (this has been the case since the first Samsung Galaxy device, they break something new each release!)

The general solution for showing an Activity over the lock screen for most devices is

//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);

However this does not work for samsung devices. Removing FLAG_DISMISS_KEYGUARD however does this trick.

Looking at the docs for this flag we have

Window flag: when set the window will cause the keyguard to be dismissed, only if it is not a secure lock keyguard. Because such a keyguard is not needed for security, it will never re-appear if the user navigates to another window (in contrast to FLAG_SHOW_WHEN_LOCKED, which will only temporarily hide both secure and non-secure keyguards but ensure they reappear when the user moves to another UI that doesn't hide them). If the keyguard is currently active and is secure (requires an unlock pattern) than the user will still need to confirm it before seeing this window, unless FLAG_SHOW_WHEN_LOCKED has also been set.

and for FLAG_SHOW_WHEN_LOCKED we have

Window flag: special flag to let windows be shown when the screen is locked. This will let application windows take precedence over key guard or any other lock screens. Can be used with FLAG_KEEP_SCREEN_ON to turn screen on and display windows directly before showing the key guard window. Can be used with FLAG_DISMISS_KEYGUARD to automatically fully dismisss non-secure keyguards. This flag only applies to the top-most full-screen window.

You can see they can be used together but it seems samsung will not bother with FLAG_SHOW_WHEN_LOCKED if the device is locked and FLAG_DISMISS_KEYGUARD is present. My app requires a lock screen to be setup so removing the dismiss keyguard flag actually allows me to show full screen Activities over the lock screen. Yay for me, nay for samsung.

Dori
  • 17,514
  • 16
  • 69
  • 112
  • 1
    Hello, I tried your solution, still it doesn't work. if I go and unlock my screen I see my home page of the app is launched, instead of the activity that supposed to show up as notification – Sweety Bertilla Jul 25 '16 at 21:05
  • if you are not seeing the new activity at all, on top or below the lock screen, then that suggests your not starting the activity in the first place. – Dori Jul 26 '16 at 09:07
  • Mine is a full screen take over – Sweety Bertilla Jul 26 '16 at 14:48
  • Thats not really a relevant response! Have you checked the Activity is actually being started in the first place? – Dori Jul 26 '16 at 18:25
  • yes.. it looks like it.. becoz when I unlock the device(without any notification) it shows up my home activity. I have submitted my ques as well http://stackoverflow.com/questions/38596347/fullscreen-notification-when-locked-and-screen-is-offnot-working – Sweety Bertilla Jul 26 '16 at 18:48