Android 12 splash screen before api 21
Asked Answered
A

5

16

I'm trying to upgrade my application to target android 31 which introduces splash screen API so I followed the migration process mentioned here, but after migration the application doesn't run because splash screen API only supports android version 21 and above so what is the process to support older versions than 21?

enter image description here

Archoplasm answered 1/9, 2021 at 8:46 Comment(4)
You can use the SplashScreen API directly, but we strongly recommend using the Androidx SplashScreen compat library instead. The compat library uses the SplashScreen API, enables backward-compatibility, and creates a consistent look and feel for splash screen display across all Android versions.Jeana
thank you for your reply but I'm already using Androidx Splashscreen but it doesn't support before Android 21Archoplasm
It says that it supports all versions, can you show anything to prove that false?Jeana
I updated the question with the build error showing the library I'm usingArchoplasm
A
9

Androidx SplashScreen class works as following:

On API 31+ (Android 12+) this class calls the platform methods.

Prior API 31, the platform behavior is replicated with the exception of the Animated Vector Drawable support on the launch screen.

the problem is Animated Vector Drawable class was introduced with Android 21 so the current Androidx SplashScreen class backward compatible with Android +21 so i figured out some solution. I created two different splash screen activities one to handle the old versions and the second which use Androidx SplashScreen API. and I made the system lunches splash screen based on the current android version, so I did the following

1- to allow application compiling and build, I had to add this line to my manifest file

<uses-sdk tools:overrideLibrary="androidx.core.splashscreen"/>

2- create the new Splash screen activity which uses Androidx SplashScreen API by following the migration steps from documentation.

3- create bools.xml under values folder

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="new_splash_enabled">false</bool>
    <bool name="old_splash_enabled">false</bool>
</resources>

4- override bools.xml in values-vX (X is the minSdkVersion) in my case was 16 so i created values-v16 folder in the same level of values folder and create bools.xml under it like below

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="new_splash_enabled">false</bool>
    <bool name="old_splash_enabled">true</bool>
</resources>

5- override bools.xml in values-vX (X is the min version you want to apply the new SplashScreen so it is any number between 21 and 31)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="new_splash_enabled">true</bool>
    <bool name="old_splash_enabled">false</bool>
</resources>

6- in your manifest, i made the system decides which splash activity to launch based on values in bools.xml file

        <activity
            android:name=".NewSplash"
            android:theme="@style/Theme.App.Starting"
            android:enabled="@bool/new_splash_enabled"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".OldSplash"
            android:enabled="@bool/old_splash_enabled">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
Archoplasm answered 3/9, 2021 at 12:32 Comment(4)
That is some lovely Android hacking. I really hate how librarys constantly force us to NOT support old devices anymore. I will try this ...Scale
@Scale absolutely agree.. What a hell Google?! Are you making this for us or for self?Tragacanth
tnx but I don't understand what is the advantage of your answer ? we could remove "android:" prefix from "windowSplashScreenBackground" attribute. you did a lot stuff.Hill
Where is the OldSplash class? Could you provide the implementation for it?Janiculum
W
8

If you're using the Androidx Compat Library make sure you're using the attributes without the android tag. For example:

This will work fine

<item name="windowSplashScreenBackground">?colorPrimary</item>

This will give you a "require API 31" error

<item name="android:windowSplashScreenBackground">?colorPrimary</item>
Wurth answered 14/12, 2022 at 14:57 Comment(0)
S
2

Lazy approach: in short programmatically set theme -> done.

  • Advantage: Only one activity. Basically a one liner
  • Disadvantage: SDK <=21 No splash, but everyone else

Long answer, I don't like the two Activities logic. So:

  • Follow step 1 to 2 of @Ramy-Ibrahim's answer.

  • set in application block of your manifest:

    android:theme="@style/Theme.App.Starting"

  • My launcher activity has no theme set anymore instead in onCreate():

     //v6.0
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
         setTheme(R.style.Theme_App_Starting);
         SplashScreen.installSplashScreen(this);
     }else{
         setTheme(R.style.AppTheme);
     }
     //mind everything BEFORE super.onCreate()
     super.onCreate(savedInstanceState);
    

Tested in Android 11(SDK30) and Android 4.4 (SDk19) and Android 12.2 (SDK32)

Scale answered 30/12, 2022 at 18:50 Comment(1)
One less headache! I spend more time getting around Gaggle bugs and fragmentation than I actually spend on programming my apps' logic!Howlend
H
2

Unfortunately as you say SplashScreen is only available from API 21 (Android 5.0 Lollipop). You can force the implementation of the library as Wow Ot said, although it is not recommended since for Google these versions are already being deprecated.

However, in API 21-22 there is a compatibility problem in which the icon is not drawn, only the background works (See the documentation). Also the animated icon only works from API 31 (Android 12). So I recommend creating different Themes for each case:

themes

This will be the base theme from API 21 to the new themes file that we specify later.

<style name="Theme.Splash" parent="Theme.SplashScreen">
    <item name="android:windowBackground">@drawable/splash_scream</item>
    <item name="postSplashScreenTheme">@style/Theme.App</item>
</style>

Remember that @drawable/splash_scream must be a bitmap to work, for example .png) It goes like this:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:drawable="@color/light"/>
   <item>
      <bitmap android:gravity="center"
        android:src="@drawable/logo_base_v21"/>
   </item>
</layer-list>

themes-v23

<style name="Theme.Splash" parent="Theme.SplashScreen">
    <item name="windowSplashScreenBackground">@color/light</item>
    <item name="windowSplashScreenAnimatedIcon">@drawable/logo_base</item>
    <item name="windowSplashScreenAnimationDuration">1000</item>
    <item name="postSplashScreenTheme">@style/Theme.App</item>
</style>

themes-v31

<style name="Theme.Splash" parent="Theme.SplashScreen">
    <item name="android:windowSplashScreenAnimatedIcon">@drawable/logo_base_anim</item>
    <item name="android:windowSplashScreenBackground">@color/light</item>
    <item name="android:windowSplashScreenAnimationDuration">1000</item>
    <item name="postSplashScreenTheme">@style/Theme.App</item>
</style>

To use it in the MainActivity it would be like this:

override fun onCreate(savedInstanceState: Bundle?) {
    val screenSplash = installSplashScreen()

    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    screenSplash.setKeepOnScreenCondition{false}
}
Heterophyte answered 23/8, 2023 at 23:34 Comment(0)
U
1

What worked for me , and inspired by @Ramy Ibrahim answer

in your manifest file before <application> tag add

 <uses-sdk tools:overrideLibrary="androidx.core.splashscreen" />

in your theme/style

<style name="ThemeStarting" parent="Theme.SplashScreen">
    <item name="windowSplashScreenBackground">@color/_background_color</item>
    <item name="windowSplashScreenAnimatedIcon">@drawable/icon</item>
    <item name="windowSplashScreenAnimationDuration">1000</item>
    <item name="postSplashScreenTheme">@style/YOUR_THEME</item>
</style>

NewSplashActivity

public class NewSplashActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(getBaseContext(), MainActivity.class);
        startActivity(intent);
        finish();
    }
    else {
        setTheme(R.style.OldSplashTheme);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.new_spl);

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                Intent intent = new Intent(getBaseContext(), MainActivity.class);
                startActivity(intent);
                finish();
            }
        }, 1999);
    }

}


@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        
    }
}

}
Unprecedented answered 20/5, 2022 at 13:54 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.