TaskStackBuilder.java revision 5c43ec9328ba98fa88acc452b140f2d682a3042c
1dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell/*
2dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Copyright (C) 2012 The Android Open Source Project
3dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
4dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * you may not use this file except in compliance with the License.
6dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * You may obtain a copy of the License at
7dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
8dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
10dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Unless required by applicable law or agreed to in writing, software
11dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * See the License for the specific language governing permissions and
14dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * limitations under the License.
15dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell */
16dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
17dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellpackage android.app;
18dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
19dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.ComponentName;
20dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.Context;
21dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.Intent;
22dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.pm.ActivityInfo;
23dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.pm.PackageManager;
24dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.content.pm.PackageManager.NameNotFoundException;
25f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powellimport android.os.Bundle;
26dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport android.util.Log;
27dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
28dd8fab2629131b09367df747afd9a61e42dd1992Adam Powellimport java.util.ArrayList;
29dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
30dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell/**
31dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Utility class for constructing synthetic back stacks for cross-task navigation
32dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * on Android 3.0 and newer.
33dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
34dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for
35dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * app navigation using the back key changed. The back key's behavior is local
36dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * to the current task and does not capture navigation across different tasks.
37dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * Navigating across tasks and easily reaching the previous task is accomplished
38dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * through the "recents" UI, accessible through the software-provided Recents key
39dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * on the navigation or system bar. On devices with the older hardware button configuration
40dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * the recents UI can be accessed with a long press on the Home key.</p>
41dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
42dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <p>When crossing from one task stack to another post-Android 3.0,
43dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * the application should synthesize a back stack/history for the new task so that
44dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * the user may navigate out of the new task and back to the Launcher by repeated
45dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * presses of the back key. Back key presses should not navigate across task stacks.</p>
46dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
47dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <p>TaskStackBuilder provides a way to obey the correct conventions
48dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * around cross-task navigation.</p>
49dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell *
50dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <div class="special reference">
51dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <h3>About Navigation</h3>
52dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * For more detailed information about tasks, the back stack, and navigation design guidelines,
53dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * please read
54dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
55dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * from the developer guide and <a href="{@docRoot}design/patterns/navigation.html">Navigation</a>
56dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * from the design guide.
57dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell * </div>
58dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell */
59f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powellpublic class TaskStackBuilder {
60dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    private static final String TAG = "TaskStackBuilder";
61dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
62dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    private final ArrayList<Intent> mIntents = new ArrayList<Intent>();
63dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    private final Context mSourceContext;
64dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
65dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    private TaskStackBuilder(Context a) {
66dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        mSourceContext = a;
67dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
68dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
69dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
70dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Return a new TaskStackBuilder for launching a fresh task stack consisting
71dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * of a series of activities.
72dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
73dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param context The context that will launch the new task stack or generate a PendingIntent
74dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return A new TaskStackBuilder
75dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
76f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public static TaskStackBuilder create(Context context) {
77dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return new TaskStackBuilder(context);
78dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
79dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
80dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
81dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Add a new Intent to the task stack. The most recently added Intent will invoke
82dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * the Activity at the top of the final task stack.
83dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
84dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param nextIntent Intent for the next Activity in the synthesized task stack
85dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return This TaskStackBuilder for method chaining
86dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
87dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    public TaskStackBuilder addNextIntent(Intent nextIntent) {
88dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        mIntents.add(nextIntent);
89dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return this;
90dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
91dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
92dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
93f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Add a new Intent with the resolved chain of parents for the target activity to
94f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * the task stack.
95f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
96f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * <p>This is equivalent to calling {@link #addParentStack(ComponentName) addParentStack}
97f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * with the resolved ComponentName of nextIntent (if it can be resolved), followed by
98f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * {@link #addNextIntent(Intent) addNextIntent} with nextIntent.</p>
99f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
100f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @param nextIntent Intent for the topmost Activity in the synthesized task stack.
101f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *                   Its chain of parents as specified in the manifest will be added.
102f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @return This TaskStackBuilder for method chaining.
103f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     */
104f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public TaskStackBuilder addNextIntentWithParentStack(Intent nextIntent) {
105f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        ComponentName target = nextIntent.getComponent();
106f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        if (target == null) {
107f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell            target = nextIntent.resolveActivity(mSourceContext.getPackageManager());
108f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        }
109f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        if (target != null) {
110f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell            addParentStack(target);
111f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        }
112f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        addNextIntent(nextIntent);
113f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        return this;
114f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    }
115f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell
116f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    /**
117dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Add the activity parent chain as specified by the
1183c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * {@link Activity#getParentActivityIntent() getParentActivityIntent()} method of the activity
1193c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * specified and the {@link android.R.attr#parentActivityName parentActivityName} attributes
1203c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * of each successive activity (or activity-alias) element in the application's manifest
1213c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * to the task stack builder.
122dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
123dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param sourceActivity All parents of this activity will be added
124dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return This TaskStackBuilder for method chaining
125dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
126dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    public TaskStackBuilder addParentStack(Activity sourceActivity) {
127dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        final int insertAt = mIntents.size();
128dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        Intent parent = sourceActivity.getParentActivityIntent();
129dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        PackageManager pm = sourceActivity.getPackageManager();
130dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        while (parent != null) {
131dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            mIntents.add(insertAt, parent);
132dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            try {
133dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                ActivityInfo info = pm.getActivityInfo(parent.getComponent(), 0);
134dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                String parentActivity = info.parentActivityName;
135dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                if (parentActivity != null) {
136dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                    parent = new Intent().setComponent(
137dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                            new ComponentName(mSourceContext, parentActivity));
138dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                } else {
139dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                    parent = null;
140dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                }
141dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            } catch (NameNotFoundException e) {
142dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
143dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                throw new IllegalArgumentException(e);
144dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            }
145dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        }
146dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return this;
147dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
148dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
149dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
150dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Add the activity parent chain as specified by the
151dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
152dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * (or activity-alias) element in the application's manifest to the task stack builder.
153dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
154dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param sourceActivityClass All parents of this activity will be added
155dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return This TaskStackBuilder for method chaining
156dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
157dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    public TaskStackBuilder addParentStack(Class<?> sourceActivityClass) {
158dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        final int insertAt = mIntents.size();
159dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        PackageManager pm = mSourceContext.getPackageManager();
160dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        try {
161dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            ActivityInfo info = pm.getActivityInfo(
162dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                    new ComponentName(mSourceContext, sourceActivityClass), 0);
163dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            String parentActivity = info.parentActivityName;
164dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            Intent parent = new Intent().setComponent(
165dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                    new ComponentName(mSourceContext, parentActivity));
166dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            while (parent != null) {
167dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                mIntents.add(insertAt, parent);
168dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                info = pm.getActivityInfo(parent.getComponent(), 0);
169dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                parentActivity = info.parentActivityName;
170dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                if (parentActivity != null) {
171dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                    parent = new Intent().setComponent(
172dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                            new ComponentName(mSourceContext, parentActivity));
173dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                } else {
174dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                    parent = null;
175dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                }
176dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            }
177dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        } catch (NameNotFoundException e) {
178dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
179dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            throw new IllegalArgumentException(e);
180dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        }
181dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return this;
182dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
183dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
184dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
1853c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * Add the activity parent chain as specified by the
1863c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * {@link android.R.attr#parentActivityName parentActivityName} attribute of the activity
1873c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * (or activity-alias) element in the application's manifest to the task stack builder.
1883c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     *
1893c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * @param sourceActivityName Must specify an Activity component. All parents of
1903c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     *                           this activity will be added
1913c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     * @return This TaskStackBuilder for method chaining
1923c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell     */
1933c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell    public TaskStackBuilder addParentStack(ComponentName sourceActivityName) {
1943c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        final int insertAt = mIntents.size();
1953c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        PackageManager pm = mSourceContext.getPackageManager();
1963c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        try {
1973c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            ActivityInfo info = pm.getActivityInfo(sourceActivityName, 0);
1983c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            String parentActivity = info.parentActivityName;
1995c43ec9328ba98fa88acc452b140f2d682a3042cAdam Powell            while (parentActivity != null) {
2005c43ec9328ba98fa88acc452b140f2d682a3042cAdam Powell                Intent parent = new Intent().setComponent(
2015c43ec9328ba98fa88acc452b140f2d682a3042cAdam Powell                        new ComponentName(info.packageName, parentActivity));
2023c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell                mIntents.add(insertAt, parent);
2033c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell                info = pm.getActivityInfo(parent.getComponent(), 0);
2043c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell                parentActivity = info.parentActivityName;
2053c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            }
2063c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        } catch (NameNotFoundException e) {
2073c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
2083c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell            throw new IllegalArgumentException(e);
2093c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        }
2103c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell        return this;
2113c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell    }
2123c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell
2133c464bdefe37f75153e8a8c978c3457ae4d1f37eAdam Powell    /**
214dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return the number of intents added so far.
215dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
216dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    public int getIntentCount() {
217dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return mIntents.size();
218dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
219dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
220dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
221f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Return the intent at the specified index for modification.
222dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Useful if you need to modify the flags or extras of an intent that was previously added,
223dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * for example with {@link #addParentStack(Activity)}.
224dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
225dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param index Index from 0-getIntentCount()
226dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return the intent at position index
227dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
228f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public Intent editIntentAt(int index) {
229dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        return mIntents.get(index);
230dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
231dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
232f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    /**
233f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Start the task stack constructed by this builder.
234f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     */
235f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public void startActivities() {
236f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        startActivities(null);
237dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
238dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
239dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
240dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Start the task stack constructed by this builder.
241f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
242f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @param options Additional options for how the Activity should be started.
243f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * See {@link android.content.Context#startActivity(Intent, Bundle)
244f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Context.startActivity(Intent, Bundle)} for more details.
245dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
246f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public void startActivities(Bundle options) {
247dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        if (mIntents.isEmpty()) {
248dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell            throw new IllegalStateException(
249dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                    "No intents added to TaskStackBuilder; cannot startActivities");
250dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        }
251dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
252dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        Intent[] intents = mIntents.toArray(new Intent[mIntents.size()]);
253dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
254dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                Intent.FLAG_ACTIVITY_CLEAR_TASK |
255dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell                Intent.FLAG_ACTIVITY_TASK_ON_HOME);
256f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        mSourceContext.startActivities(intents, options);
257dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
258dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell
259dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    /**
260dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * Obtain a {@link PendingIntent} for launching the task constructed by this builder so far.
261dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *
262dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param requestCode Private request code for the sender
263dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT},
264dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *              {@link PendingIntent#FLAG_NO_CREATE}, {@link PendingIntent#FLAG_CANCEL_CURRENT},
265dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *              {@link PendingIntent#FLAG_UPDATE_CURRENT}, or any of the flags supported by
266dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *              {@link Intent#fillIn(Intent, int)} to control which unspecified parts of the
267dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     *              intent that can be supplied when the actual send happens.
268f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
269dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     * @return The obtained PendingIntent
270dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell     */
271dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    public PendingIntent getPendingIntent(int requestCode, int flags) {
272f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        return getPendingIntent(requestCode, flags, null);
273f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    }
274f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell
275f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    /**
276f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Obtain a {@link PendingIntent} for launching the task constructed by this builder so far.
277f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
278f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @param requestCode Private request code for the sender
279f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT},
280f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *              {@link PendingIntent#FLAG_NO_CREATE}, {@link PendingIntent#FLAG_CANCEL_CURRENT},
281f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *              {@link PendingIntent#FLAG_UPDATE_CURRENT}, or any of the flags supported by
282f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *              {@link Intent#fillIn(Intent, int)} to control which unspecified parts of the
283f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *              intent that can be supplied when the actual send happens.
284f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @param options Additional options for how the Activity should be started.
285f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * See {@link android.content.Context#startActivity(Intent, Bundle)
286f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Context.startActivity(Intent, Bundle)} for more details.
287f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
288f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @return The obtained PendingIntent
289f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     */
290f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public PendingIntent getPendingIntent(int requestCode, int flags, Bundle options) {
2918ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell        if (mIntents.isEmpty()) {
2928ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell            throw new IllegalStateException(
2938ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell                    "No intents added to TaskStackBuilder; cannot getPendingIntent");
2948ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell        }
2958ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell
296dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell        Intent[] intents = mIntents.toArray(new Intent[mIntents.size()]);
2978ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell        intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
2988ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell                Intent.FLAG_ACTIVITY_CLEAR_TASK |
2998ab700cbbab60f7a01a86cbf16496e1f34236dd6Adam Powell                Intent.FLAG_ACTIVITY_TASK_ON_HOME);
300f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        return PendingIntent.getActivities(mSourceContext, requestCode, intents, flags, options);
301f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    }
302f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell
303f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    /**
304f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * Return an array containing the intents added to this builder. The intent at the
305f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * root of the task stack will appear as the first item in the array and the
306f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * intent at the top of the stack will appear as the last item.
307f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     *
308f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     * @return An array containing the intents added to this builder.
309f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell     */
310f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell    public Intent[] getIntents() {
311f78a8444a9b21b0d1daca8667d580dd0ec04a310Adam Powell        return mIntents.toArray(new Intent[mIntents.size()]);
312dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell    }
313dd8fab2629131b09367df747afd9a61e42dd1992Adam Powell}
314