I have a special navigation in my application and i'm wondering how can I set it properly.
An activity H is the homescreen of my application. From this activity, we can launch activities A, B, C, and D. From activity A we can launch A' that launch A'', from activity B we can launch B', that launch B'', etc.
The problem is that from ANY activity, we can go to the activity H, A, B, C or D. But, when the user launch A->A'->A''->C, and then go back on A, he has to be redirected to A''. Moreover, still with this example, if the user press back on A'', he has to be redirected to A' and not to C. If he press back again he has to be redirected to A, and back again should redirect him to the H (home screen) activity, not to C !
Finally, when the user press back from H, and only at this moment, the application (and all tasks if the solution choosen is to create separated tasks) should shutdown.
Other example : H -> A -> B -> H -> back -> end of application
How can I achieve this ? I have thinked to use task like that :
<!-- A-->
<activity
android:name=".A"
android:excludeFromRecents="true"
android:taskAffinity=".A"
android:label="@string/my_A_label">
</activity>
<activity
android:name=".A'"
android:taskAffinity=".A"
android:label="@string/my_A'_label">
</activity>
<activity
android:name=".A''"
android:taskAffinity=".A"
android:label="@string/my_A''_label">
</activity>
<!-- B-->
<activity
android:name=".B"
android:excludeFromRecents="true"
android:taskAffinity=".B"
android:label="@string/my_B_label">
</activity>
<activity
android:name=".B'"
android:taskAffinity=".B"
android:label="@string/my_B'_label">
</activity>
<activity
android:name=".B''"
android:taskAffinity=".B"
android:label="@string/my_B''_label">
</activity>
...
As you can see, I have created tasks for each main page : A, B, C, D. I don't know if it's the good thing to do because, for example, with task, the user can see all theses activities on long press on his home button with the "last task" option, and I don't want have this behaviour. For that, activities A, B, C, D (root screen of each task) have the attribute android:excludeFromRecents="true". But now, another problem : when the user click on his home button, and go back to my application, he go back to home screen, not to the last activity launched...
Moreover, my second example is not respected.
Have you an idea to resolve all these problems ?
P.S : Please don't tell me to change my navigation system :-)
EDIT : here a flow chart that represents the back comportment needed. This comportment seems to be normal. What is differring in my case doesn't appear on this chart. Indeed, only back button is represented. Each context - represented by a different color - can switch to another context, without override the back comportment described here.
EDIT2 : Thanks to advices of David Wasser, I have implemented two classes that exactly do the comportment that I have described, without using of android tasks. Thanks to JoxTraex for his help too :-) Here what I've done : my activities A,B,C,D extend RootActivity, the other except H extend CustomNavigationActivity.
RootActivity :
import android.content.Intent;
public abstract class RootActivity extends CustomNavigationActivity{
@Override
public void onBackPressed(){
Intent intent = new Intent(this, HomeScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
}
CustomNavigationActivity :
import android.content.Intent;
public abstract class CustomNavigationActivity extends Activity{
private int actualRequestCode;
private int menuRequestCode = -1;
@Override
protected void onResume(){
if (getIntent().hasExtra("childLaunched")){
Intent intent = new Intent(this, (Class<?>) getIntent().getExtras().get("childLaunched"));
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
super.onResume();
}
@Override
public void startActivity (Intent intent) {
this.startActivityForResult(intent, 0);
}
@Override
public void startActivityForResult(Intent intent, int requestCode){
Class<?> targetClass = null;
this.actualRequestCode = requestCode;
if (this.actualRequestCode == this.menuRequestCode){
this.menuRequestCode -= 1;
}
try {
if (intent.getComponent() != null){
targetClass = Class.forName(intent.getComponent().getClassName());
}
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (targetClass == null){
super.startActivityForResult(intent, this.actualRequestCode);
}
else if (!targetClass.equals(Menu.class)){
getIntent().putExtra("childLaunched", targetClass);
super.startActivityForResult(intent, this.actualRequestCode);
}
else{
super.startActivityForResult(intent, this.menuRequestCode);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == this.actualRequestCode){
getIntent().removeExtra("childLaunched");
}
}
}