Android 12: How to prevent activity restart on changing phone wallpaper?
Asked Answered
N

1

22

On Android 12,

  1. If we open an activity

  2. Go to the home screen of the phone to change the wallpaper

  3. Switch back to our activity, the activity restarts.

It seems it is related to the Material You theming.

I would like to disable the restarting of activity when my app comes to the foreground. Is there a way?

Nephogram answered 27/10, 2021 at 15:54 Comment(12)
Most likely this is a configuration change, no different than screen rotation, dark mode toggle, locale change, or any of the other configuration change sources. How are you handling configuration changes overall?Oratorical
@Oratorical I thought the same, and have all config values under activity tag in manifest file, but the activity is still restarting. android:configChanges="orientation|uiMode|mcc|mnc|locale|keyboard|keyboardHidden|navigation|screenLayout|fontScale|screenSize|smallestScreenSize"Nephogram
You are missing layoutDirection, touchscreen, and density in that list. While none of those would really fit, you could try adding those and see if it changes your behavior. I forget what Logcat logs around configuration changes, but you might find something there too. BTW, what device are you testing on?Oratorical
@Oratorical I added the missing config values, and nothing changed. I didn't see any special log entry when the activity restarted on orientation change. I am testing it on Pixel device, official build. All other apps are restarting too.Nephogram
If you are overriding onConfigurationChanged() in this activity, use debugging or logging to see if it is being called. If it is, then there is some new config change type that is not documented, and we'd need to figure out what that is. If it is not being called... that's bad.Oratorical
@Oratorical onConfigurationChanged() is called only when we have the right configchanges flag set in the manifest. So no callback happens. The restart also happens on the emulator(API Sv2), so it is definitely Android 12 specific issue.Nephogram
"onConfigurationChanged() is called only when we have the right configchanges flag set in the manifest" -- oh, right, sorry. I will try to look at this problem on the weekend.Oratorical
I see the same effect, and I cannot explain it. I filed a comment on a seemingly-related existing issue, wrote a blog post about it, plus added the bounty here. With luck, we will get some answers out of all of that.Oratorical
We are talking about this issue at r/android_devs. I reproduce something I found interesting: what happens when the user uses an app that changes the wallpaper automatically? In this case, could the activity close automatically even when the user is using it?Morningglory
It seems to be a configuration changes. I can catch the changes by overriding the onConfigurationChanges from the Application (which will be called for all such changes, regardless of the Manifest). The flag "assetsSeq" is updated. A demo here: lensdump.com/i/gmpwWA . I used the built-in Wallpaper App, and Pixel 4 running Android 12.Drank
@NguyễnHoàiNam: Ooooo... I had forgotten about Application and onConfigurationChanged()! I included your tip in my answer and in an update to my blog post on this. Thanks for pointing that out!Oratorical
@anemomylos: You're correct, it appears it affects all wallpaper changing apps from Android 12+ too. In fact, I originally posted this question before I was directed here.Phosgene
O
10

It is a non-traditional configuration change. By "non-traditional", I mean that it cannot be blocked by android:configChanges — your activity will be destroyed and recreated whether you like it or not.

If you have Configuration objects from before and after the change, you can determine that this scenario occurred by calling diff() on the newer Configuration to compare it to the older one:

val diff = resources.configuration.diff(vm.originalConfiguration)

Log.d("WallpaperCCTest", "matches CONFIG_ASSETS_PATHS? ${(diff.toLong() and 0x80000000) != 0L}")

Here, vm.originalConfiguration points to the older Configuration, and we get the current Configuration from the Resources object. (diff.toLong() and 0x80000000) != 0L will evaluate to true if a wallpaper change or something similar triggered the configuration change. There are other edge cases for this — this whole "unblockable configuration change" thing came about when Sony got Google to add support for runtime resource overlays (RROs) back in 2017. So, some of those "change the system theme" apps might trigger this same unblockable configuration change.

As Nguyễn Hoài Nam notes, you can detect this from onConfigurationChanged() of a custom Application. Or, have your viewmodel hold onto the previous Configuration and compare it with the current one in onCreate() of your activity.

I have more on this issue in this blog post. AFAIK, there is no way to opt out of this configuration change, so if your app was designed to avoid configuration changes, you may be out of luck.

Oratorical answered 31/10, 2021 at 18:39 Comment(1)
Could you please take a look at this #69985752 Thanks.Nephogram

© 2022 - 2024 — McMap. All rights reserved.