Iakovos
Iakovos

Reputation: 1982

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.

Upvotes: 0

Views: 1375

Answers (3)

ThugKd
ThugKd

Reputation: 11

I solve the problem using the following code:

<item name="android:windowSplashScreenBehavior">icon_preferred</item>

https://developer.android.com/develop/ui/views/launch/splash-screen?hl=zh-cn

Upvotes: 1

Iakovos
Iakovos

Reputation: 1982

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();
    }
}

Upvotes: 0

David Wasser
David Wasser

Reputation: 95568

This makes no sense. According to the documentation if you call finish() inside onCreate(), none of the remaining lifecycle methods will be called. In your code, you are calling finish() inside SplashActivity.onCreate() so your splash screen should never be shown.

Upvotes: 0

Related Questions