Programmatically Resume a child activity

726 views Asked by At

Long story short, I am developing a multi-activity app for the Amazon Kindle. Kindle has a somewhat exotic launcher that does not support (correctly) more than one LAUNCHER activity in the manifest, so if you are on a child activity, go to home screen, then press the app icon again, the child activity is killed and the main activity is re-launched.

I have 2 activities: ACTIVITY_PLAY and ACTIVITY_DESIGNER. Typical session starts in ACTIVITY_PLAY, then the user might go to ACTIVITY_DESIGNER to do some work. This activity is instantiated by ACTIVITY_PLAY. If he/she leaves the app for a moment (ie. check mail) then attempting to return will cause PLAY_MODE to be started.

To solve this, I've created a "Launcher" activity (see source below), that is now the only application entry point. This activity decides wether to launch ACTIVITY_PLAY or ACTIVITY_DESIGN depending on a static value that I change from those activities' "onResume": The latest onResume received is the last activity the user was working on.

My problem is, now when I select the app icon in the launcher, it launches the correct activity BUT restarts it, even though all involved activities have android:launchmode = singleTask. Also all involved activities have the same android:taskAffinity.

Any ideas? Is it correct to declare the 3 activities (Launcher/Play/Design) with the same taskAffinity? Shouldn't this work?

public class Launcher extends Activity {

    private static final String TAG = "Launcher";
    public static final int ACTIVITY_PLAY=1, ACTIVITY_DESIGN=2, ACTIVITY_QUIT=3;

    private static int msFocused=FUNQ_PLAY;

    private void launch() {

        Bundle bundle=getIntent().getExtras();

        switch (msFocused) {
        case ACTIVITY_DESIGN:
            Log.v(TAG, "*** Launcher launch DESIGNER");
            Misc.runActivity(this, DesignActivity.class, bundle);
            break;
        case ACTIVITY_QUIT: // special code to quit instead of launching anything
            finish();
            setFocused(ACTIVITY_PLAY); // so next button press will launch play mode if the app is still alive
            break;
        case ACTIVITY_PLAY:
        default:
            Log.v(TAG, "*** Launcher launch PLAYER");
            Misc.runActivity(this, PlayActivity.class, bundle);
            break;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        launch();
    }

    // called from the child activities' onResume.
    public static void setFocused(int activityCode) {
        Log.i(TAG, "*** CURRENTLY FOCUSED IS "+activityCode);
        msFocused=activityCode;
    }

}
2

There are 2 answers

0
rupps On BEST ANSWER

I managed to solve it, hope it is useful to somebody.

Launcher: taskAffinity=".launcher" launchMode="normal"
Master Activity: taskAffinity=".workflow" launchMode="singleTop"
Child Activity: taskAffinity=".workflow" launchMode="singleTop"

Detaching the launcher from the workflow task, and normal launchMode seems to do the trick for the Kindle. The singleTop thing is specific for my apps, maybe not related to the problem, but I initially used singleTop in the launcher too, and that apparently led to the side-effect of my question.

9
Arda Kara On

You can use SharedPreferences to save last state then check the SharedPreferences to decide which activity to start. I will add an example code in a minute.

Edit: Here is the example code:

in your launcher activities onCreateView function do something like this:

SharedPreferences reader = pActivity.getSharedPreferences( "PutDesiredPrefNameHere", Context.MODE_PRIVATE);

int lastState = reader.getInt( "LAST_STATE", 0 ); //if there is no last state saved it will return second parameter. 0 in this situation.

switch( lastState ){

     case 0:
            Intent i=new Intent( this, PlayModeActivity.class);
        startActivity(i);

        //Remove launcher activity
        finish();
            break;

     case 1:
            Intent i=new Intent( this, EditModeActivity.class);
        startActivity(i);

        //Remove launcher activity
        finish();
            break;

}

and in your PlayModeActivity's onCreateView method call this:

  SharedPreferences.Editor writer = pActivity.getSharedPreferences( "PutDesiredPrefNameHere" , Context.MODE_PRIVATE).edit();   //Don't forget pref names must be same

  write.putInt( "LAST_STATE" ,0 );
  write.comit();

and in your EditModeActivity's onCreateView method call this:

  SharedPreferences.Editor writer = pActivity.getSharedPreferences( "PutDesiredPrefNameHere" , Context.MODE_PRIVATE).edit();   //Don't forget pref names must be same

  write.putInt( "LAST_STATE" ,0 );
  write.comit();

Here is a link about SharedPreferences:

http://www.tutorialspoint.com/android/android_shared_preferences.htm