0

I'm developing an app which contain TabHost ,in one of those tabs i have an ActivityGroup , and from this ActivityGroup, i launch another SubActivity ( let's say that i Launch an Activity A ), and until this , everything is OK.

The problem is when i press the BackButton ,the CurrentActivity( Activity A ) is destroyed, but the ParentActivity( The ActivityGroup ) is not resumed , and the app show just a null Window with the Title of My App ( "My Application Title" ) .

The Code to launch the Activity A from my ActivityGroup is :

View view = getLocalActivityManager().startActivity(id,newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) .getDecorView();
this.setContentView(view);

and i have overrided the method onKeyDown like this in my ActivityGroup :

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.i(TAG, "onKeyDown");
        if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0){
            Activity current = getLocalActivityManager().getCurrentActivity();
            Log.i(TAG, current.getIntent().getStringExtra("id"));
            current.finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

but it seems that the method onKeyDown is never called because a i didn't get the Log "onKeyDown" displayed.

and the logcat display just this :

01-05 11:04:38.012: W/KeyCharacterMap(401): No keyboard for id 0
01-05 11:04:38.012: W/KeyCharacterMap(401): Using default keymap: /system/usr/keychars/qwerty.kcm.bin

what i want is to display the ActivityGroup when my Activity A is Destroyed.

NB : my app level is 4 : *Android 1.6* , so i can't override the method onBackPressed()

Thank you all for your help

-----------------------------------EDIT ----------------------------------------

I have added the code of my onKeyDown like this on my Activity A :

@Override public boolean onKeyDown(int keyCode, KeyEvent event) {

    if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0){
        ParentActivity parentActivity = (ParentActivity) this.getParent();
        parentActivity.onKeyDown(keyCode, event);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

And in my ParentActivity , i have :

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0){
            Log.i(TAG, "onKeyDown");
            int len = idOfSubActivities.size();
            String idOfCurrentActivity = idOfSubActivities.get(len-1);
            Activity currentActivity = getLocalActivityManager().getActivity(idOfCurrentActivity);
            currentActivity.finish();
            idOfSubActivities.remove(len - 1);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

I got the same result , the Activity A is stopped , but it still give me the null window with the title of my app , and it doesn't display my ActivityGroup (ParentActivity)

gherkins
  • 14,603
  • 6
  • 44
  • 70
Houcine
  • 24,001
  • 13
  • 56
  • 83

1 Answers1

1

I faced a problem similar to this when I first started experimenting with ActivityGroups. The issue is that you need to place your onKeyDown() in your Activity. However, you need the Activity to have a reference to the ActivityGroup. Then, when you press back, just call your own onBack() in the ActivityGroup.

(EDIT) Here's a Sample for you

Below is the stripped down ActivityGroup code that handles navigation and history in my apps. It has been adjusted on the fly, so there might be an error. Notice a couple of finer points.

public class MyGroup extends ActivityGroup
{
/** Static Reference to this Group. */
    static MyGroup instance;
/** Keeps Track of the History as a Stack. */
    private ArrayList<View> myActivityHistory;

    @Override protected void onCreate(final Bundle savedInstanceState)
    {//Call the Base Implementation
        super.onCreate(savedInstanceState);

    // Initialize the Activity History
        myActivityHistory = new ArrayList<View>();

    // Build the Intent
        Intent _root = null;
    //Lists the Applications
        _root = new Intent(this, MyActivity.class);
    // Send the Index to the Child Activity
        _root.setAction(Intent.ACTION_VIEW);
    // Forward the Extras, if they are there
    // Start the root Activity within the Group and get its View
        final View _view = getLocalActivityManager().startActivity("App Preferences", _root).getDecorView();
    // Start the History
        addNewLevel(_view);
    }

    /**
     * Gets the instance of the {@link ApplicationGroup} that the child Activity
     * belongs to.
     *
     * @param index
     *  The Group that was passed to the child in the {@link android.content.Intent
     *  Intent} via an Extra (int).
     * @return
     *  <b>ApplicationGroup -</b> The group that this child was assigned to.
     */
    static public ApplicationGroup getGroup()
    {   if (instance != null)
            return instance;
    }

    /**
     * Allows the Child to replace the {@link ApplicationGroup}'s current
     * {@link android.view.View View} with the specified View. This is
     * intended to be used specifically by the Child.
     *
     * @param withView
     *  The View to use for replacement.
     */
    public void addNewLevel(final View withView)
    {//Adds the old one to history
        myActivityHistory.add(withView);
    // Changes this Groups View to the new View.
        setContentView(withView);
    }

    /**
     * Takes the specified {@link android.app.ActivityGroup ActivityGroup} back
     * one step in the History to the previous {@link android.view.View View}.
     */
    public void back()
    {   Log.d("Group", "Back overridden");
        //If there are more than one screen
        if (myActivityHistory.size() > 1)
        {   Log.d("Group", "History called");
        // Remove the most recent View
            myActivityHistory.remove(myActivityHistory.size()-1);
        // Change the View back.
            setContentView(myActivityHistory.get(myActivityHistory.size()-1));
        }
    // Otherwise Exit
        else
        {   Log.d("Group", "Program finished");
            finish();
        }
    }

}

Next is the pertinent code for the Activity:

public boolean onKeyDown(int keyCode, KeyEvent event)
{//If back was pressed
    if (keyCode==KeyEvent.KEYCODE_BACK)
    {   MyGroup.getGroup().back();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

Just make sure that you aren't setting the KeyDownListener to anything funny and it should work fine. :) The changes that I made are because I actually have them in an array of Groups (3 at one time). Essentially, just make the Group a Singleton so you can always have the same instance, and keep an array of your Views so that you have a History. Then reference the History when you click Back or when you add a View.

Hope this helps, FuzzicalLogic

Fuzzical Logic
  • 12,947
  • 2
  • 30
  • 58
  • please see my edit, i've done what you told me and i got the same result , can you please provide some of your code you talked about ?thanks – Houcine Jan 05 '12 at 12:51
  • Yes, give me a few hours to grab it. (I'm at work and the application I used it in is at home)... – Fuzzical Logic Jan 05 '12 at 13:20
  • thanks a lot for your help , i have used the same concept of the history ..Etc but i will try your method by using the HistoryArray typped with View . tanks a gain , i will try this tomorrow – Houcine Jan 05 '12 at 23:25
  • thanks to you, i've fixed the problem with my own way , i followed this tutorial and it works great : http://ericharlow.blogspot.com/2010/09/experience-multiple-android-activities.html . – Houcine Jan 06 '12 at 11:22
  • Doht! For some reason I totally missed the TabHost up there. LOL. My example was modified from a TabActivity with Child ListViews. I'm glad you got your answer!! – Fuzzical Logic Jan 07 '12 at 01:48