7

I'm writing an application which have two "modes"; one view mode and one edit mode. The application exposes two main/launcher activities (say, A and D) which in turn have their own activity chains (B, C and E, F respectively). The two entry point activities A and D will expose two icons with separate labels in the home screen and the two chains are never crossed, i.e. once you start the application in a view mode with activity A, the only route you can walk back and forth is A, B, C and if you start the application in edit mode with activity D, the only available activity chain is D, E, F.

Now, my problem is that if start the application in, e.g. view mode (activity chain A, B, C) and press the Home button from any activity in that chain I get back to the home screen (of course) but if I then re-start the application in edit mode (activity chain D, E, F) I get to the activity I was on when pressing the Home button (that is, an activity in the wrong chain) - not the expected entry point for edit mode; activity D.

How do I solve this?

I have tried various combinations of android:noHistory, android:clearTaskOnLaunch and other attributes in AndroidManifest.xml for the involved activities. But they only seem to affect the very activity, not the entire chain.

I would like to remove the entire chain of activities (A, B, C or D, E, F) from the history stack when the Home button is pressed but still keep the stack intact while I'm still in the chain (I want to be able to press the back button from, say, activity B and get to activity A).

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
dbm
  • 10,376
  • 6
  • 44
  • 56
  • 1
    You should have eye on that http://stackoverflow.com/questions/3473168/clear-the-entire-history-stack-and-start-a-new-activity-on-android – himanshu Jan 06 '12 at 12:42
  • 1
    @dbm : r u looking fr this http://nisha113a5.blogspot.com/?? do revert – Pratik Bhat Jan 06 '12 at 19:13
  • Hi @himanshu! Yes, that question would probably also have led me to a working conclusion. Thanks for the tip! – dbm Jan 08 '12 at 09:21
  • Hi @android_hungry! That solution would probably work. I'm not sure, however, if I would chose it as my primary implementation. To me it feels a bit like "dark which-craft" which is bound not to work on certain devices. That is a short-cut I don't have the luxury of taking. – dbm Jan 08 '12 at 09:26
  • @dbm: yes u r right, just happened to go thru that post on the same day when i read ur question.. – Pratik Bhat Jan 08 '12 at 09:34

3 Answers3

4

Sounds like you need to use the Intent.FLAG_ACTIVITY_CLEAR_TOP flag on your home activities, but of course you can't add these flags in the AndroidManifest.xml file. Maybe you should have a single point of entry which then launches the correct Activity - you can use an activity-alias to make it look like two points of entry to the user.

For example - you define the activities in your manifest file:

   <activity-alias
        android:label="@string/edit_app_name"
        android:name="launch_edit"
        android:targetActivity=".activities.LaunchActivity">
        <meta-data android:name="launch_type" android:resource="@string/launch_edit" />
    </activity-alias>
    <activity-alias
        android:label="@string/view_app_name"
        android:name="launch_view"
        android:targetActivity=".activities.LaunchActivity">
        <meta-data android:name="launch_type" android:resource="@string/launch_view" />
    </activity-alias>

Then in your LaunchActivity you have:

ActivityInfo activityInfo = getPackageManager().getPackageInfo( this.getComponentName(), PackageManager.GET_ACTIVITIES|PackageManager.GET_META_DATA);
int launchTypeResource = activityInfo.metaData.getInt("launch_type");
String launchType = context.getString(launchTypeResource);
if(launchType == null) {
   // handle error
   throw new Exception();
}
Intent newIntent;
if(launchType.equals(context.getString(R.string.launch_view)) {
    newIntent = createIntent(ViewActivity.class);
} else if(launchType.equals(context.getString(R.string.launch_edit)) {
    newIntent = createIntent(EditActivity.class);
}
newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(newIntent);
Martyn
  • 16,432
  • 24
  • 71
  • 104
  • Hi @Martin! I took me the liberty of slightly modifying your code snippet on how to actually fetch the meta-data associated with the `activity-alias`. It turned out it's not sent through the calling `Intent` but rather read from the `ActivityInfo` data structure. – dbm Jan 08 '12 at 09:02
  • 1
    Great answer! Taking the amount of effort you put in it and the fact that your answer was the first (correct and working-ish, just granted you a green check-mark :-) – dbm Jan 08 '12 at 09:05
  • @Martyn can you edit your answer to contain the correct reading of data? – Ovidiu Latcu Jan 09 '12 at 09:36
  • @OvidiuLatcu, I have now re-suggested my proposed fix. Unfortunately I don't seem to have the right to edit other peoples questions/answers yet, hence I can't do much more but await Martyn's review. – dbm Jan 10 '12 at 07:43
  • 1
    Apologies - was on holiday! :D Have corrected the code - thanks for pointing it out. – Martyn Jan 16 '12 at 10:33
4

Please use following method on press of home button:

Intent intent=new Intent(this, HomeClass.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
jeet
  • 29,001
  • 6
  • 52
  • 53
  • I assume this would actually be the easiest way of fixing my issue. I will however use another implementation which renders this solution not suitable for my application this time. I did, however, learn something by your answer and for that I thank you. – dbm Jan 08 '12 at 09:13
1

You could consider using only one Activity for each chain (that would be only A and D).

Then implement the content of A, B and C and D, E and F as Fragments and just change the Fragment shown on the Activity when navigating back and forth.

Combine this with android:noHistory and you should get the desired effect - although it would require some rewriting and that you include the compatability package into your project if you plan to target version below Honeycomb.

kaspermoerch
  • 16,127
  • 4
  • 44
  • 67
  • This was actually a very elegant use of fragments and since my application already is built up by fragments it wouldn't even be such a huge rewrite. Even though I think it was the fair thing to do to accept @Martyn 's answer, I think this is the architectural choice I will go with in the end. Thanks for the great idea! – dbm Jan 08 '12 at 09:09