7

I have an application, which starts with a SplashScreenActivity. Afterwards, a LoginActivity is shown, or if the user is already logged in, a MainActivity is shown. If the application is already running, SplashScreenActivity is dismissed with the following

//SplashScreenActivity
 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //Adding this check for following cases
    if (!isTaskRoot())
    {
        String intentAction = getIntent().getAction();
        if (getIntent().hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
            finish();
            return;
        }

        if(getIntent().getCategories().contains(GCMIntentService.INTENT_CATEGORY_GH_NOTIFICATION)){
            finish();
            return;
        }
    }

Problem occurs

If I start the application from another activity like PlayStore, it resumes at the right activity if already running. This is the Intent I'm using to reproduce within a second app

//AnotherApplication.apk
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("my.package.name");
startActivity(launchIntent);

However, this action is somehow breaking the Backstack. Instead of closing the application on backpress in the MainActivity, it restarts the application.

//MainActivity.class
@Override
public void onBackPressed() {
    if (getNavDrawerMain().isDrawerOpen()) {
        getNavDrawerMain().closeDrawer();
    } else {
        closeApp();
    }
}

protected void closeApp() {
    if (doubleBackToExitPressedOnce) {
        //super.onBackPressed();   //i tried both, but behaviour is the same
        finish();
        return;
    }
    this.doubleBackToExitPressedOnce = true;

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() 
            doubleBackToExitPressedOnce = false;
        }
    }, 500);
}

I used breakpoints and found out that MainActivity:onDestroy() get called, but instead of resuming application to the HomeScreen, it always restarts and I don't know why.

I tried the following: - Used different launchmodes like singleTask and singleInstance, but it didn't make any difference. onNewIntent is called, but if i call finish, HomeActivity restarts - as commeted below, i tried moveTaskToBack(true), but Activity is restaring too (and we really want to close the app instead of moving it to the BackStack)

longi
  • 11,104
  • 10
  • 55
  • 89
  • 1
    In my experience, `getLaunchIntentForPackage(...)` *does not* return a launcher intent. A launcher intent will raise the existing task, but the intents returned by `getLaunchIntentForPackage(...)` will actually start a new one. Your app may not be restarting when you back out of it; you may simply be seeing another copy of it. – Kevin Krumwiede Aug 06 '15 at 16:12
  • 1
    @KevinKrumwiede: Intent has following type `android.intent.action.MAIN`, i just added some additional code, how i handle the intent – longi Aug 07 '15 at 08:28
  • 1
    I can't find anything that explicitly says so, but I suspect that only the system is allowed to receive `ACTION_MAIN`. – Kevin Krumwiede Aug 07 '15 at 20:35
  • 1
    It seems splash activity is always in stack. Did you set it as parent of MainActivity in manifest ? – S.D. Aug 15 '15 at 22:32
  • 1
    Can you show us your Manifest? I wonder if it's connected to your launchmode. – Laurent Aug 17 '15 at 01:13
  • 1
    I am a bit confused with your problem description. To make it clear: Do you mean user: opens Play Store > Open your App > hit back key, at this moment, you want your app to be closed but, it gets restarted, right? – LiuWenbin_NO. Aug 17 '15 at 03:07

2 Answers2

2

Try with moveTaskToBack(true); instead of finish(); to close the app. It will then go to OnRestart() and then OnStart()->OnResume() (and won't go to OnCreate).

And make sure you don't have the "Don't keep activities" marked at Developer Options in your Android Settings (destroy every activity as soon as the user leaves it).

Joanmi Bardera
  • 351
  • 1
  • 7
  • Make sure you don't have the "Don't keep activities" marked at Developer Options in your Android Settings (destroy every activity as soon as the user leaves it). – Joanmi Bardera Sep 04 '15 at 20:29
1

Trying adding this flag to your intent starting your app: RESET_TASK_IF_NEEDED, URL=http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

What it does:

If set, and this activity is either being started in a new task or bringing to the top an existing task, then it will be launched as the front door of the task.

You may also use: http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_REORDER_TO_FRONT

What it does:

If set in an Intent passed to Context.startActivity(), this flag will cause the launched activity to be brought to the front of its task's history stack if it is already running.

Which one you use depend on the desired end result.

If you can't control who starts you you need to set or launch mode to single task or single instance.

Described here:

http://inthecheesefactory.com/blog/understand-android-activity-launchmode/en

The interesting part:

singleTask

This mode is quite different from standard and singleTop. An Activity with singleTask launchMode is allowed to have only one instance in the system (a.k.a. Singleton). If there is an existed Activity instance in the system, the whole Task hold the instance would be moved to top while Intent would be delivered through onNewIntent() method. Otherwise, new Activity would be created and placed in the proper Task.

JohanShogun
  • 2,956
  • 21
  • 30
  • the problem is, that the `Intent` where I should add the flags is started from (in our case) `Google Play Store` or `HockeyApp`, so we cannot change them. Or did I misunderstand your question? – longi Aug 12 '15 at 15:04
  • Oh, then you just need a single instance task, updated answer. – JohanShogun Aug 12 '15 at 16:08
  • "...tried different launchmodes, but it didn't make any difference..." maybe I should have make this point more clear. I tried `singleTop` , `singleTask` etc... Doesn't make any difference. I see, that Activity is destroyed, but instead of reuming to prevoius stack, it calls `onCreate()` again – longi Aug 13 '15 at 12:13
  • Post complete logs and describe in detail exactly what you did – JohanShogun Aug 13 '15 at 16:49
  • guess i posted the main parts or what else could help? guess i should rebuild this behaviour in a plain project, and commit this to github, but at the moment there s no time for that :-/ – longi Aug 16 '15 at 15:16