Android Galaxy S4 — Activity that is visible over lock screen

前端 未结 5 996
一整个雨季
一整个雨季 2020-12-09 05:08

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 A

相关标签:
5条回答
  • 2020-12-09 05:43

    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!

    0 讨论(0)
  • 2020-12-09 05:48

    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!

    0 讨论(0)
  • 2020-12-09 05:48

    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.

    0 讨论(0)
  • 2020-12-09 05:53

    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

    0 讨论(0)
  • 2020-12-09 06:00

    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.

    0 讨论(0)
提交回复
热议问题