Search code examples
androidandroid-intentsplash-screenapp-startup

Splash Screen not appearing when using intent-filter for file extension


I am implementing a splash screen that is visible until the main Activity of my app manages to render a PDF. When I am opening the app, by clicking on the launcher icon, I can see the splash screen normally.

When I try to open a PDF with the app, there is a delay until MainActivity's onCreate() completes, and then MainActivity is displayed directly (without presenting the splash image first). However, I have noticed that the SplashActivity's onCreate() method is executed.

My code so far:

The Splash Activity:

public class SplashActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        Uri uri = intent.getData();

        Intent intentForActivity = new Intent(this, MainActivity.class);

        if (uri != null)
            intentForActivity.putExtra("URI", uri.toString());

        startActivity(intentForActivity);
        finish();
    }
}

The Activity that I am waiting for (MainActivity):

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);

        // some dummy delay for this example, so that the Splash Screen
        // is displayed until this Activity is ready
        // (this is NOT the actual code of my application!)
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

The relevant part of the Manifest file:

<activity
    android:name=".SplashActivity"
    android:theme="@style/SplashTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter tools:ignore="AppLinkUrlError">
        <action android:name="android.intent.action.VIEW" />
        <action android:name="android.intent.action.EDIT" />
        <action android:name="android.intent.action.PICK" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:mimeType="application/pdf" />
        <data android:pathPattern="*\\.pdf" />
    </intent-filter>
</activity>
    <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme.NoActionBar" />

The problem seems to be in the intent-filter for handling PDF files, but I cannot figure what is wrong and why.

UPDATE: Adding android:launchMode="singleInstance" in the configuration of SplashActivity in the Manifest solves the issue, but creates many other issues for me.


Solution

  • I managed to solve the issue by doing the following:

    As David Wasser correctly mentioned, this occurs when my app is launched in the task of the app that launches it (i.e., when I open a PDF from within a file manager).

    To solve this, in the Manifest, I added this to the configuration of the SplashActivity: android:launchMode="singleTask".

    Then, I noticed that this way, multiple instances of the MainActivity would initiate. Hitting the back button would navigate me between them. To solve this, in the SplashActivity class, before I called startActivity() I added: intentForActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); (documentation: FLAG_ACTIVITY_CLEAR_TASK).

    A problem that I noticed is that the onDestroy() method of the old MainActivity sometimes executes after the onCreate() of the new one. So, you should be careful when and what you modify/create/delete/etc in your onDestroy() method.

    There might be better ways to achieve this result, but this worked well for me.

    My updated relevant part of the Manifest:

    <activity
        android:name=".SplashActivity"
        android:launchMode="singleTask"
        android:theme="@style/SplashTheme">
    

    My updated SplashActivity:

    public class SplashActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            Intent intent = getIntent();
            final Uri uri = intent.getData();
    
            Intent intentForActivity = new Intent(this, MainActivity.class);
            if (uri != null)
                intentForActivity.putExtra("URI", uri.toString());
    
            intentForActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(intentForActivity);
            this.finish();
        }
    }