androidandroid-activityandroid-alarmslockscreenandroid-notification-bar

Android Galaxy S4 -- Activity that is visible over lock screen


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?


Solution

  • 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!