Activity.java revision 04fe6ebb9f919f196ec06a19bebc09b8e943f95b
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.app; 18 19import com.android.internal.app.ActionBarImpl; 20import com.android.internal.policy.PolicyManager; 21 22import android.content.ComponentCallbacks2; 23import android.content.ComponentName; 24import android.content.ContentResolver; 25import android.content.Context; 26import android.content.CursorLoader; 27import android.content.IIntentSender; 28import android.content.Intent; 29import android.content.IntentSender; 30import android.content.SharedPreferences; 31import android.content.pm.ActivityInfo; 32import android.content.pm.PackageManager; 33import android.content.pm.PackageManager.NameNotFoundException; 34import android.content.res.Configuration; 35import android.content.res.Resources; 36import android.content.res.TypedArray; 37import android.database.Cursor; 38import android.graphics.Bitmap; 39import android.graphics.Canvas; 40import android.graphics.drawable.Drawable; 41import android.media.AudioManager; 42import android.net.Uri; 43import android.os.Build; 44import android.os.Bundle; 45import android.os.Handler; 46import android.os.IBinder; 47import android.os.Looper; 48import android.os.Parcelable; 49import android.os.RemoteException; 50import android.os.StrictMode; 51import android.os.UserHandle; 52import android.text.Selection; 53import android.text.SpannableStringBuilder; 54import android.text.TextUtils; 55import android.text.method.TextKeyListener; 56import android.util.AttributeSet; 57import android.util.EventLog; 58import android.util.Log; 59import android.util.Slog; 60import android.util.SparseArray; 61import android.view.ActionMode; 62import android.view.ContextMenu; 63import android.view.ContextMenu.ContextMenuInfo; 64import android.view.ContextThemeWrapper; 65import android.view.KeyEvent; 66import android.view.LayoutInflater; 67import android.view.Menu; 68import android.view.MenuInflater; 69import android.view.MenuItem; 70import android.view.MotionEvent; 71import android.view.View; 72import android.view.View.OnCreateContextMenuListener; 73import android.view.ViewGroup; 74import android.view.ViewGroup.LayoutParams; 75import android.view.ViewManager; 76import android.view.Window; 77import android.view.WindowManager; 78import android.view.WindowManagerGlobal; 79import android.view.accessibility.AccessibilityEvent; 80import android.widget.AdapterView; 81 82import java.io.FileDescriptor; 83import java.io.PrintWriter; 84import java.util.ArrayList; 85import java.util.HashMap; 86 87/** 88 * An activity is a single, focused thing that the user can do. Almost all 89 * activities interact with the user, so the Activity class takes care of 90 * creating a window for you in which you can place your UI with 91 * {@link #setContentView}. While activities are often presented to the user 92 * as full-screen windows, they can also be used in other ways: as floating 93 * windows (via a theme with {@link android.R.attr#windowIsFloating} set) 94 * or embedded inside of another activity (using {@link ActivityGroup}). 95 * 96 * There are two methods almost all subclasses of Activity will implement: 97 * 98 * <ul> 99 * <li> {@link #onCreate} is where you initialize your activity. Most 100 * importantly, here you will usually call {@link #setContentView(int)} 101 * with a layout resource defining your UI, and using {@link #findViewById} 102 * to retrieve the widgets in that UI that you need to interact with 103 * programmatically. 104 * 105 * <li> {@link #onPause} is where you deal with the user leaving your 106 * activity. Most importantly, any changes made by the user should at this 107 * point be committed (usually to the 108 * {@link android.content.ContentProvider} holding the data). 109 * </ul> 110 * 111 * <p>To be of use with {@link android.content.Context#startActivity Context.startActivity()}, all 112 * activity classes must have a corresponding 113 * {@link android.R.styleable#AndroidManifestActivity <activity>} 114 * declaration in their package's <code>AndroidManifest.xml</code>.</p> 115 * 116 * <p>Topics covered here: 117 * <ol> 118 * <li><a href="#Fragments">Fragments</a> 119 * <li><a href="#ActivityLifecycle">Activity Lifecycle</a> 120 * <li><a href="#ConfigurationChanges">Configuration Changes</a> 121 * <li><a href="#StartingActivities">Starting Activities and Getting Results</a> 122 * <li><a href="#SavingPersistentState">Saving Persistent State</a> 123 * <li><a href="#Permissions">Permissions</a> 124 * <li><a href="#ProcessLifecycle">Process Lifecycle</a> 125 * </ol> 126 * 127 * <div class="special reference"> 128 * <h3>Developer Guides</h3> 129 * <p>The Activity class is an important part of an application's overall lifecycle, 130 * and the way activities are launched and put together is a fundamental 131 * part of the platform's application model. For a detailed perspective on the structure of an 132 * Android application and how activities behave, please read the 133 * <a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> and 134 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a> 135 * developer guides.</p> 136 * 137 * <p>You can also find a detailed discussion about how to create activities in the 138 * <a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a> 139 * developer guide.</p> 140 * </div> 141 * 142 * <a name="Fragments"></a> 143 * <h3>Fragments</h3> 144 * 145 * <p>Starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB}, Activity 146 * implementations can make use of the {@link Fragment} class to better 147 * modularize their code, build more sophisticated user interfaces for larger 148 * screens, and help scale their application between small and large screens. 149 * 150 * <a name="ActivityLifecycle"></a> 151 * <h3>Activity Lifecycle</h3> 152 * 153 * <p>Activities in the system are managed as an <em>activity stack</em>. 154 * When a new activity is started, it is placed on the top of the stack 155 * and becomes the running activity -- the previous activity always remains 156 * below it in the stack, and will not come to the foreground again until 157 * the new activity exits.</p> 158 * 159 * <p>An activity has essentially four states:</p> 160 * <ul> 161 * <li> If an activity in the foreground of the screen (at the top of 162 * the stack), 163 * it is <em>active</em> or <em>running</em>. </li> 164 * <li>If an activity has lost focus but is still visible (that is, a new non-full-sized 165 * or transparent activity has focus on top of your activity), it 166 * is <em>paused</em>. A paused activity is completely alive (it 167 * maintains all state and member information and remains attached to 168 * the window manager), but can be killed by the system in extreme 169 * low memory situations. 170 * <li>If an activity is completely obscured by another activity, 171 * it is <em>stopped</em>. It still retains all state and member information, 172 * however, it is no longer visible to the user so its window is hidden 173 * and it will often be killed by the system when memory is needed 174 * elsewhere.</li> 175 * <li>If an activity is paused or stopped, the system can drop the activity 176 * from memory by either asking it to finish, or simply killing its 177 * process. When it is displayed again to the user, it must be 178 * completely restarted and restored to its previous state.</li> 179 * </ul> 180 * 181 * <p>The following diagram shows the important state paths of an Activity. 182 * The square rectangles represent callback methods you can implement to 183 * perform operations when the Activity moves between states. The colored 184 * ovals are major states the Activity can be in.</p> 185 * 186 * <p><img src="../../../images/activity_lifecycle.png" 187 * alt="State diagram for an Android Activity Lifecycle." border="0" /></p> 188 * 189 * <p>There are three key loops you may be interested in monitoring within your 190 * activity: 191 * 192 * <ul> 193 * <li>The <b>entire lifetime</b> of an activity happens between the first call 194 * to {@link android.app.Activity#onCreate} through to a single final call 195 * to {@link android.app.Activity#onDestroy}. An activity will do all setup 196 * of "global" state in onCreate(), and release all remaining resources in 197 * onDestroy(). For example, if it has a thread running in the background 198 * to download data from the network, it may create that thread in onCreate() 199 * and then stop the thread in onDestroy(). 200 * 201 * <li>The <b>visible lifetime</b> of an activity happens between a call to 202 * {@link android.app.Activity#onStart} until a corresponding call to 203 * {@link android.app.Activity#onStop}. During this time the user can see the 204 * activity on-screen, though it may not be in the foreground and interacting 205 * with the user. Between these two methods you can maintain resources that 206 * are needed to show the activity to the user. For example, you can register 207 * a {@link android.content.BroadcastReceiver} in onStart() to monitor for changes 208 * that impact your UI, and unregister it in onStop() when the user no 209 * longer sees what you are displaying. The onStart() and onStop() methods 210 * can be called multiple times, as the activity becomes visible and hidden 211 * to the user. 212 * 213 * <li>The <b>foreground lifetime</b> of an activity happens between a call to 214 * {@link android.app.Activity#onResume} until a corresponding call to 215 * {@link android.app.Activity#onPause}. During this time the activity is 216 * in front of all other activities and interacting with the user. An activity 217 * can frequently go between the resumed and paused states -- for example when 218 * the device goes to sleep, when an activity result is delivered, when a new 219 * intent is delivered -- so the code in these methods should be fairly 220 * lightweight. 221 * </ul> 222 * 223 * <p>The entire lifecycle of an activity is defined by the following 224 * Activity methods. All of these are hooks that you can override 225 * to do appropriate work when the activity changes state. All 226 * activities will implement {@link android.app.Activity#onCreate} 227 * to do their initial setup; many will also implement 228 * {@link android.app.Activity#onPause} to commit changes to data and 229 * otherwise prepare to stop interacting with the user. You should always 230 * call up to your superclass when implementing these methods.</p> 231 * 232 * </p> 233 * <pre class="prettyprint"> 234 * public class Activity extends ApplicationContext { 235 * protected void onCreate(Bundle savedInstanceState); 236 * 237 * protected void onStart(); 238 * 239 * protected void onRestart(); 240 * 241 * protected void onResume(); 242 * 243 * protected void onPause(); 244 * 245 * protected void onStop(); 246 * 247 * protected void onDestroy(); 248 * } 249 * </pre> 250 * 251 * <p>In general the movement through an activity's lifecycle looks like 252 * this:</p> 253 * 254 * <table border="2" width="85%" align="center" frame="hsides" rules="rows"> 255 * <colgroup align="left" span="3" /> 256 * <colgroup align="left" /> 257 * <colgroup align="center" /> 258 * <colgroup align="center" /> 259 * 260 * <thead> 261 * <tr><th colspan="3">Method</th> <th>Description</th> <th>Killable?</th> <th>Next</th></tr> 262 * </thead> 263 * 264 * <tbody> 265 * <tr><th colspan="3" align="left" border="0">{@link android.app.Activity#onCreate onCreate()}</th> 266 * <td>Called when the activity is first created. 267 * This is where you should do all of your normal static set up: 268 * create views, bind data to lists, etc. This method also 269 * provides you with a Bundle containing the activity's previously 270 * frozen state, if there was one. 271 * <p>Always followed by <code>onStart()</code>.</td> 272 * <td align="center">No</td> 273 * <td align="center"><code>onStart()</code></td> 274 * </tr> 275 * 276 * <tr><td rowspan="5" style="border-left: none; border-right: none;"> </td> 277 * <th colspan="2" align="left" border="0">{@link android.app.Activity#onRestart onRestart()}</th> 278 * <td>Called after your activity has been stopped, prior to it being 279 * started again. 280 * <p>Always followed by <code>onStart()</code></td> 281 * <td align="center">No</td> 282 * <td align="center"><code>onStart()</code></td> 283 * </tr> 284 * 285 * <tr><th colspan="2" align="left" border="0">{@link android.app.Activity#onStart onStart()}</th> 286 * <td>Called when the activity is becoming visible to the user. 287 * <p>Followed by <code>onResume()</code> if the activity comes 288 * to the foreground, or <code>onStop()</code> if it becomes hidden.</td> 289 * <td align="center">No</td> 290 * <td align="center"><code>onResume()</code> or <code>onStop()</code></td> 291 * </tr> 292 * 293 * <tr><td rowspan="2" style="border-left: none;"> </td> 294 * <th align="left" border="0">{@link android.app.Activity#onResume onResume()}</th> 295 * <td>Called when the activity will start 296 * interacting with the user. At this point your activity is at 297 * the top of the activity stack, with user input going to it. 298 * <p>Always followed by <code>onPause()</code>.</td> 299 * <td align="center">No</td> 300 * <td align="center"><code>onPause()</code></td> 301 * </tr> 302 * 303 * <tr><th align="left" border="0">{@link android.app.Activity#onPause onPause()}</th> 304 * <td>Called when the system is about to start resuming a previous 305 * activity. This is typically used to commit unsaved changes to 306 * persistent data, stop animations and other things that may be consuming 307 * CPU, etc. Implementations of this method must be very quick because 308 * the next activity will not be resumed until this method returns. 309 * <p>Followed by either <code>onResume()</code> if the activity 310 * returns back to the front, or <code>onStop()</code> if it becomes 311 * invisible to the user.</td> 312 * <td align="center"><font color="#800000"><strong>Pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB}</strong></font></td> 313 * <td align="center"><code>onResume()</code> or<br> 314 * <code>onStop()</code></td> 315 * </tr> 316 * 317 * <tr><th colspan="2" align="left" border="0">{@link android.app.Activity#onStop onStop()}</th> 318 * <td>Called when the activity is no longer visible to the user, because 319 * another activity has been resumed and is covering this one. This 320 * may happen either because a new activity is being started, an existing 321 * one is being brought in front of this one, or this one is being 322 * destroyed. 323 * <p>Followed by either <code>onRestart()</code> if 324 * this activity is coming back to interact with the user, or 325 * <code>onDestroy()</code> if this activity is going away.</td> 326 * <td align="center"><font color="#800000"><strong>Yes</strong></font></td> 327 * <td align="center"><code>onRestart()</code> or<br> 328 * <code>onDestroy()</code></td> 329 * </tr> 330 * 331 * <tr><th colspan="3" align="left" border="0">{@link android.app.Activity#onDestroy onDestroy()}</th> 332 * <td>The final call you receive before your 333 * activity is destroyed. This can happen either because the 334 * activity is finishing (someone called {@link Activity#finish} on 335 * it, or because the system is temporarily destroying this 336 * instance of the activity to save space. You can distinguish 337 * between these two scenarios with the {@link 338 * Activity#isFinishing} method.</td> 339 * <td align="center"><font color="#800000"><strong>Yes</strong></font></td> 340 * <td align="center"><em>nothing</em></td> 341 * </tr> 342 * </tbody> 343 * </table> 344 * 345 * <p>Note the "Killable" column in the above table -- for those methods that 346 * are marked as being killable, after that method returns the process hosting the 347 * activity may killed by the system <em>at any time</em> without another line 348 * of its code being executed. Because of this, you should use the 349 * {@link #onPause} method to write any persistent data (such as user edits) 350 * to storage. In addition, the method 351 * {@link #onSaveInstanceState(Bundle)} is called before placing the activity 352 * in such a background state, allowing you to save away any dynamic instance 353 * state in your activity into the given Bundle, to be later received in 354 * {@link #onCreate} if the activity needs to be re-created. 355 * See the <a href="#ProcessLifecycle">Process Lifecycle</a> 356 * section for more information on how the lifecycle of a process is tied 357 * to the activities it is hosting. Note that it is important to save 358 * persistent data in {@link #onPause} instead of {@link #onSaveInstanceState} 359 * because the latter is not part of the lifecycle callbacks, so will not 360 * be called in every situation as described in its documentation.</p> 361 * 362 * <p class="note">Be aware that these semantics will change slightly between 363 * applications targeting platforms starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB} 364 * vs. those targeting prior platforms. Starting with Honeycomb, an application 365 * is not in the killable state until its {@link #onStop} has returned. This 366 * impacts when {@link #onSaveInstanceState(Bundle)} may be called (it may be 367 * safely called after {@link #onPause()} and allows and application to safely 368 * wait until {@link #onStop()} to save persistent state.</p> 369 * 370 * <p>For those methods that are not marked as being killable, the activity's 371 * process will not be killed by the system starting from the time the method 372 * is called and continuing after it returns. Thus an activity is in the killable 373 * state, for example, between after <code>onPause()</code> to the start of 374 * <code>onResume()</code>.</p> 375 * 376 * <a name="ConfigurationChanges"></a> 377 * <h3>Configuration Changes</h3> 378 * 379 * <p>If the configuration of the device (as defined by the 380 * {@link Configuration Resources.Configuration} class) changes, 381 * then anything displaying a user interface will need to update to match that 382 * configuration. Because Activity is the primary mechanism for interacting 383 * with the user, it includes special support for handling configuration 384 * changes.</p> 385 * 386 * <p>Unless you specify otherwise, a configuration change (such as a change 387 * in screen orientation, language, input devices, etc) will cause your 388 * current activity to be <em>destroyed</em>, going through the normal activity 389 * lifecycle process of {@link #onPause}, 390 * {@link #onStop}, and {@link #onDestroy} as appropriate. If the activity 391 * had been in the foreground or visible to the user, once {@link #onDestroy} is 392 * called in that instance then a new instance of the activity will be 393 * created, with whatever savedInstanceState the previous instance had generated 394 * from {@link #onSaveInstanceState}.</p> 395 * 396 * <p>This is done because any application resource, 397 * including layout files, can change based on any configuration value. Thus 398 * the only safe way to handle a configuration change is to re-retrieve all 399 * resources, including layouts, drawables, and strings. Because activities 400 * must already know how to save their state and re-create themselves from 401 * that state, this is a convenient way to have an activity restart itself 402 * with a new configuration.</p> 403 * 404 * <p>In some special cases, you may want to bypass restarting of your 405 * activity based on one or more types of configuration changes. This is 406 * done with the {@link android.R.attr#configChanges android:configChanges} 407 * attribute in its manifest. For any types of configuration changes you say 408 * that you handle there, you will receive a call to your current activity's 409 * {@link #onConfigurationChanged} method instead of being restarted. If 410 * a configuration change involves any that you do not handle, however, the 411 * activity will still be restarted and {@link #onConfigurationChanged} 412 * will not be called.</p> 413 * 414 * <a name="StartingActivities"></a> 415 * <h3>Starting Activities and Getting Results</h3> 416 * 417 * <p>The {@link android.app.Activity#startActivity} 418 * method is used to start a 419 * new activity, which will be placed at the top of the activity stack. It 420 * takes a single argument, an {@link android.content.Intent Intent}, 421 * which describes the activity 422 * to be executed.</p> 423 * 424 * <p>Sometimes you want to get a result back from an activity when it 425 * ends. For example, you may start an activity that lets the user pick 426 * a person in a list of contacts; when it ends, it returns the person 427 * that was selected. To do this, you call the 428 * {@link android.app.Activity#startActivityForResult(Intent, int)} 429 * version with a second integer parameter identifying the call. The result 430 * will come back through your {@link android.app.Activity#onActivityResult} 431 * method.</p> 432 * 433 * <p>When an activity exits, it can call 434 * {@link android.app.Activity#setResult(int)} 435 * to return data back to its parent. It must always supply a result code, 436 * which can be the standard results RESULT_CANCELED, RESULT_OK, or any 437 * custom values starting at RESULT_FIRST_USER. In addition, it can optionally 438 * return back an Intent containing any additional data it wants. All of this 439 * information appears back on the 440 * parent's <code>Activity.onActivityResult()</code>, along with the integer 441 * identifier it originally supplied.</p> 442 * 443 * <p>If a child activity fails for any reason (such as crashing), the parent 444 * activity will receive a result with the code RESULT_CANCELED.</p> 445 * 446 * <pre class="prettyprint"> 447 * public class MyActivity extends Activity { 448 * ... 449 * 450 * static final int PICK_CONTACT_REQUEST = 0; 451 * 452 * protected boolean onKeyDown(int keyCode, KeyEvent event) { 453 * if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 454 * // When the user center presses, let them pick a contact. 455 * startActivityForResult( 456 * new Intent(Intent.ACTION_PICK, 457 * new Uri("content://contacts")), 458 * PICK_CONTACT_REQUEST); 459 * return true; 460 * } 461 * return false; 462 * } 463 * 464 * protected void onActivityResult(int requestCode, int resultCode, 465 * Intent data) { 466 * if (requestCode == PICK_CONTACT_REQUEST) { 467 * if (resultCode == RESULT_OK) { 468 * // A contact was picked. Here we will just display it 469 * // to the user. 470 * startActivity(new Intent(Intent.ACTION_VIEW, data)); 471 * } 472 * } 473 * } 474 * } 475 * </pre> 476 * 477 * <a name="SavingPersistentState"></a> 478 * <h3>Saving Persistent State</h3> 479 * 480 * <p>There are generally two kinds of persistent state than an activity 481 * will deal with: shared document-like data (typically stored in a SQLite 482 * database using a {@linkplain android.content.ContentProvider content provider}) 483 * and internal state such as user preferences.</p> 484 * 485 * <p>For content provider data, we suggest that activities use a 486 * "edit in place" user model. That is, any edits a user makes are effectively 487 * made immediately without requiring an additional confirmation step. 488 * Supporting this model is generally a simple matter of following two rules:</p> 489 * 490 * <ul> 491 * <li> <p>When creating a new document, the backing database entry or file for 492 * it is created immediately. For example, if the user chooses to write 493 * a new e-mail, a new entry for that e-mail is created as soon as they 494 * start entering data, so that if they go to any other activity after 495 * that point this e-mail will now appear in the list of drafts.</p> 496 * <li> <p>When an activity's <code>onPause()</code> method is called, it should 497 * commit to the backing content provider or file any changes the user 498 * has made. This ensures that those changes will be seen by any other 499 * activity that is about to run. You will probably want to commit 500 * your data even more aggressively at key times during your 501 * activity's lifecycle: for example before starting a new 502 * activity, before finishing your own activity, when the user 503 * switches between input fields, etc.</p> 504 * </ul> 505 * 506 * <p>This model is designed to prevent data loss when a user is navigating 507 * between activities, and allows the system to safely kill an activity (because 508 * system resources are needed somewhere else) at any time after it has been 509 * paused. Note this implies 510 * that the user pressing BACK from your activity does <em>not</em> 511 * mean "cancel" -- it means to leave the activity with its current contents 512 * saved away. Canceling edits in an activity must be provided through 513 * some other mechanism, such as an explicit "revert" or "undo" option.</p> 514 * 515 * <p>See the {@linkplain android.content.ContentProvider content package} for 516 * more information about content providers. These are a key aspect of how 517 * different activities invoke and propagate data between themselves.</p> 518 * 519 * <p>The Activity class also provides an API for managing internal persistent state 520 * associated with an activity. This can be used, for example, to remember 521 * the user's preferred initial display in a calendar (day view or week view) 522 * or the user's default home page in a web browser.</p> 523 * 524 * <p>Activity persistent state is managed 525 * with the method {@link #getPreferences}, 526 * allowing you to retrieve and 527 * modify a set of name/value pairs associated with the activity. To use 528 * preferences that are shared across multiple application components 529 * (activities, receivers, services, providers), you can use the underlying 530 * {@link Context#getSharedPreferences Context.getSharedPreferences()} method 531 * to retrieve a preferences 532 * object stored under a specific name. 533 * (Note that it is not possible to share settings data across application 534 * packages -- for that you will need a content provider.)</p> 535 * 536 * <p>Here is an excerpt from a calendar activity that stores the user's 537 * preferred view mode in its persistent settings:</p> 538 * 539 * <pre class="prettyprint"> 540 * public class CalendarActivity extends Activity { 541 * ... 542 * 543 * static final int DAY_VIEW_MODE = 0; 544 * static final int WEEK_VIEW_MODE = 1; 545 * 546 * private SharedPreferences mPrefs; 547 * private int mCurViewMode; 548 * 549 * protected void onCreate(Bundle savedInstanceState) { 550 * super.onCreate(savedInstanceState); 551 * 552 * SharedPreferences mPrefs = getSharedPreferences(); 553 * mCurViewMode = mPrefs.getInt("view_mode", DAY_VIEW_MODE); 554 * } 555 * 556 * protected void onPause() { 557 * super.onPause(); 558 * 559 * SharedPreferences.Editor ed = mPrefs.edit(); 560 * ed.putInt("view_mode", mCurViewMode); 561 * ed.commit(); 562 * } 563 * } 564 * </pre> 565 * 566 * <a name="Permissions"></a> 567 * <h3>Permissions</h3> 568 * 569 * <p>The ability to start a particular Activity can be enforced when it is 570 * declared in its 571 * manifest's {@link android.R.styleable#AndroidManifestActivity <activity>} 572 * tag. By doing so, other applications will need to declare a corresponding 573 * {@link android.R.styleable#AndroidManifestUsesPermission <uses-permission>} 574 * element in their own manifest to be able to start that activity. 575 * 576 * <p>When starting an Activity you can set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION 577 * Intent.FLAG_GRANT_READ_URI_PERMISSION} and/or {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION 578 * Intent.FLAG_GRANT_WRITE_URI_PERMISSION} on the Intent. This will grant the 579 * Activity access to the specific URIs in the Intent. Access will remain 580 * until the Activity has finished (it will remain across the hosting 581 * process being killed and other temporary destruction). As of 582 * {@link android.os.Build.VERSION_CODES#GINGERBREAD}, if the Activity 583 * was already created and a new Intent is being delivered to 584 * {@link #onNewIntent(Intent)}, any newly granted URI permissions will be added 585 * to the existing ones it holds. 586 * 587 * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> 588 * document for more information on permissions and security in general. 589 * 590 * <a name="ProcessLifecycle"></a> 591 * <h3>Process Lifecycle</h3> 592 * 593 * <p>The Android system attempts to keep application process around for as 594 * long as possible, but eventually will need to remove old processes when 595 * memory runs low. As described in <a href="#ActivityLifecycle">Activity 596 * Lifecycle</a>, the decision about which process to remove is intimately 597 * tied to the state of the user's interaction with it. In general, there 598 * are four states a process can be in based on the activities running in it, 599 * listed here in order of importance. The system will kill less important 600 * processes (the last ones) before it resorts to killing more important 601 * processes (the first ones). 602 * 603 * <ol> 604 * <li> <p>The <b>foreground activity</b> (the activity at the top of the screen 605 * that the user is currently interacting with) is considered the most important. 606 * Its process will only be killed as a last resort, if it uses more memory 607 * than is available on the device. Generally at this point the device has 608 * reached a memory paging state, so this is required in order to keep the user 609 * interface responsive. 610 * <li> <p>A <b>visible activity</b> (an activity that is visible to the user 611 * but not in the foreground, such as one sitting behind a foreground dialog) 612 * is considered extremely important and will not be killed unless that is 613 * required to keep the foreground activity running. 614 * <li> <p>A <b>background activity</b> (an activity that is not visible to 615 * the user and has been paused) is no longer critical, so the system may 616 * safely kill its process to reclaim memory for other foreground or 617 * visible processes. If its process needs to be killed, when the user navigates 618 * back to the activity (making it visible on the screen again), its 619 * {@link #onCreate} method will be called with the savedInstanceState it had previously 620 * supplied in {@link #onSaveInstanceState} so that it can restart itself in the same 621 * state as the user last left it. 622 * <li> <p>An <b>empty process</b> is one hosting no activities or other 623 * application components (such as {@link Service} or 624 * {@link android.content.BroadcastReceiver} classes). These are killed very 625 * quickly by the system as memory becomes low. For this reason, any 626 * background operation you do outside of an activity must be executed in the 627 * context of an activity BroadcastReceiver or Service to ensure that the system 628 * knows it needs to keep your process around. 629 * </ol> 630 * 631 * <p>Sometimes an Activity may need to do a long-running operation that exists 632 * independently of the activity lifecycle itself. An example may be a camera 633 * application that allows you to upload a picture to a web site. The upload 634 * may take a long time, and the application should allow the user to leave 635 * the application will it is executing. To accomplish this, your Activity 636 * should start a {@link Service} in which the upload takes place. This allows 637 * the system to properly prioritize your process (considering it to be more 638 * important than other non-visible applications) for the duration of the 639 * upload, independent of whether the original activity is paused, stopped, 640 * or finished. 641 */ 642public class Activity extends ContextThemeWrapper 643 implements LayoutInflater.Factory2, 644 Window.Callback, KeyEvent.Callback, 645 OnCreateContextMenuListener, ComponentCallbacks2 { 646 private static final String TAG = "Activity"; 647 private static final boolean DEBUG_LIFECYCLE = false; 648 649 /** Standard activity result: operation canceled. */ 650 public static final int RESULT_CANCELED = 0; 651 /** Standard activity result: operation succeeded. */ 652 public static final int RESULT_OK = -1; 653 /** Start of user-defined activity results. */ 654 public static final int RESULT_FIRST_USER = 1; 655 656 static final String FRAGMENTS_TAG = "android:fragments"; 657 658 private static final String WINDOW_HIERARCHY_TAG = "android:viewHierarchyState"; 659 private static final String SAVED_DIALOG_IDS_KEY = "android:savedDialogIds"; 660 private static final String SAVED_DIALOGS_TAG = "android:savedDialogs"; 661 private static final String SAVED_DIALOG_KEY_PREFIX = "android:dialog_"; 662 private static final String SAVED_DIALOG_ARGS_KEY_PREFIX = "android:dialog_args_"; 663 664 private static class ManagedDialog { 665 Dialog mDialog; 666 Bundle mArgs; 667 } 668 private SparseArray<ManagedDialog> mManagedDialogs; 669 670 // set by the thread after the constructor and before onCreate(Bundle savedInstanceState) is called. 671 private Instrumentation mInstrumentation; 672 private IBinder mToken; 673 private int mIdent; 674 /*package*/ String mEmbeddedID; 675 private Application mApplication; 676 /*package*/ Intent mIntent; 677 private ComponentName mComponent; 678 /*package*/ ActivityInfo mActivityInfo; 679 /*package*/ ActivityThread mMainThread; 680 Activity mParent; 681 boolean mCalled; 682 boolean mCheckedForLoaderManager; 683 boolean mLoadersStarted; 684 /*package*/ boolean mResumed; 685 private boolean mStopped; 686 boolean mFinished; 687 boolean mStartedActivity; 688 private boolean mDestroyed; 689 /** true if the activity is going through a transient pause */ 690 /*package*/ boolean mTemporaryPause = false; 691 /** true if the activity is being destroyed in order to recreate it with a new configuration */ 692 /*package*/ boolean mChangingConfigurations = false; 693 /*package*/ int mConfigChangeFlags; 694 /*package*/ Configuration mCurrentConfig; 695 private SearchManager mSearchManager; 696 private MenuInflater mMenuInflater; 697 698 static final class NonConfigurationInstances { 699 Object activity; 700 HashMap<String, Object> children; 701 ArrayList<Fragment> fragments; 702 HashMap<String, LoaderManagerImpl> loaders; 703 } 704 /* package */ NonConfigurationInstances mLastNonConfigurationInstances; 705 706 private Window mWindow; 707 708 private WindowManager mWindowManager; 709 /*package*/ View mDecor = null; 710 /*package*/ boolean mWindowAdded = false; 711 /*package*/ boolean mVisibleFromServer = false; 712 /*package*/ boolean mVisibleFromClient = true; 713 /*package*/ ActionBarImpl mActionBar = null; 714 private boolean mEnableDefaultActionBarUp; 715 716 private CharSequence mTitle; 717 private int mTitleColor = 0; 718 719 final FragmentManagerImpl mFragments = new FragmentManagerImpl(); 720 final FragmentContainer mContainer = new FragmentContainer() { 721 @Override 722 public View findViewById(int id) { 723 return Activity.this.findViewById(id); 724 } 725 }; 726 727 HashMap<String, LoaderManagerImpl> mAllLoaderManagers; 728 LoaderManagerImpl mLoaderManager; 729 730 private static final class ManagedCursor { 731 ManagedCursor(Cursor cursor) { 732 mCursor = cursor; 733 mReleased = false; 734 mUpdated = false; 735 } 736 737 private final Cursor mCursor; 738 private boolean mReleased; 739 private boolean mUpdated; 740 } 741 private final ArrayList<ManagedCursor> mManagedCursors = 742 new ArrayList<ManagedCursor>(); 743 744 // protected by synchronized (this) 745 int mResultCode = RESULT_CANCELED; 746 Intent mResultData = null; 747 748 private boolean mTitleReady = false; 749 750 private int mDefaultKeyMode = DEFAULT_KEYS_DISABLE; 751 private SpannableStringBuilder mDefaultKeySsb = null; 752 753 protected static final int[] FOCUSED_STATE_SET = {com.android.internal.R.attr.state_focused}; 754 755 @SuppressWarnings("unused") 756 private final Object mInstanceTracker = StrictMode.trackActivity(this); 757 758 private Thread mUiThread; 759 final Handler mHandler = new Handler(); 760 761 /** Return the intent that started this activity. */ 762 public Intent getIntent() { 763 return mIntent; 764 } 765 766 /** 767 * Change the intent returned by {@link #getIntent}. This holds a 768 * reference to the given intent; it does not copy it. Often used in 769 * conjunction with {@link #onNewIntent}. 770 * 771 * @param newIntent The new Intent object to return from getIntent 772 * 773 * @see #getIntent 774 * @see #onNewIntent 775 */ 776 public void setIntent(Intent newIntent) { 777 mIntent = newIntent; 778 } 779 780 /** Return the application that owns this activity. */ 781 public final Application getApplication() { 782 return mApplication; 783 } 784 785 /** Is this activity embedded inside of another activity? */ 786 public final boolean isChild() { 787 return mParent != null; 788 } 789 790 /** Return the parent activity if this view is an embedded child. */ 791 public final Activity getParent() { 792 return mParent; 793 } 794 795 /** Retrieve the window manager for showing custom windows. */ 796 public WindowManager getWindowManager() { 797 return mWindowManager; 798 } 799 800 /** 801 * Retrieve the current {@link android.view.Window} for the activity. 802 * This can be used to directly access parts of the Window API that 803 * are not available through Activity/Screen. 804 * 805 * @return Window The current window, or null if the activity is not 806 * visual. 807 */ 808 public Window getWindow() { 809 return mWindow; 810 } 811 812 /** 813 * Return the LoaderManager for this fragment, creating it if needed. 814 */ 815 public LoaderManager getLoaderManager() { 816 if (mLoaderManager != null) { 817 return mLoaderManager; 818 } 819 mCheckedForLoaderManager = true; 820 mLoaderManager = getLoaderManager(null, mLoadersStarted, true); 821 return mLoaderManager; 822 } 823 824 LoaderManagerImpl getLoaderManager(String who, boolean started, boolean create) { 825 if (mAllLoaderManagers == null) { 826 mAllLoaderManagers = new HashMap<String, LoaderManagerImpl>(); 827 } 828 LoaderManagerImpl lm = mAllLoaderManagers.get(who); 829 if (lm == null) { 830 if (create) { 831 lm = new LoaderManagerImpl(who, this, started); 832 mAllLoaderManagers.put(who, lm); 833 } 834 } else { 835 lm.updateActivity(this); 836 } 837 return lm; 838 } 839 840 /** 841 * Calls {@link android.view.Window#getCurrentFocus} on the 842 * Window of this Activity to return the currently focused view. 843 * 844 * @return View The current View with focus or null. 845 * 846 * @see #getWindow 847 * @see android.view.Window#getCurrentFocus 848 */ 849 public View getCurrentFocus() { 850 return mWindow != null ? mWindow.getCurrentFocus() : null; 851 } 852 853 /** 854 * Called when the activity is starting. This is where most initialization 855 * should go: calling {@link #setContentView(int)} to inflate the 856 * activity's UI, using {@link #findViewById} to programmatically interact 857 * with widgets in the UI, calling 858 * {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve 859 * cursors for data being displayed, etc. 860 * 861 * <p>You can call {@link #finish} from within this function, in 862 * which case onDestroy() will be immediately called without any of the rest 863 * of the activity lifecycle ({@link #onStart}, {@link #onResume}, 864 * {@link #onPause}, etc) executing. 865 * 866 * <p><em>Derived classes must call through to the super class's 867 * implementation of this method. If they do not, an exception will be 868 * thrown.</em></p> 869 * 870 * @param savedInstanceState If the activity is being re-initialized after 871 * previously being shut down then this Bundle contains the data it most 872 * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b> 873 * 874 * @see #onStart 875 * @see #onSaveInstanceState 876 * @see #onRestoreInstanceState 877 * @see #onPostCreate 878 */ 879 protected void onCreate(Bundle savedInstanceState) { 880 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState); 881 if (mLastNonConfigurationInstances != null) { 882 mAllLoaderManagers = mLastNonConfigurationInstances.loaders; 883 } 884 if (mActivityInfo.parentActivityName != null) { 885 if (mActionBar == null) { 886 mEnableDefaultActionBarUp = true; 887 } else { 888 mActionBar.setDefaultDisplayHomeAsUpEnabled(true); 889 } 890 } 891 if (savedInstanceState != null) { 892 Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG); 893 mFragments.restoreAllState(p, mLastNonConfigurationInstances != null 894 ? mLastNonConfigurationInstances.fragments : null); 895 } 896 mFragments.dispatchCreate(); 897 getApplication().dispatchActivityCreated(this, savedInstanceState); 898 mCalled = true; 899 } 900 901 /** 902 * The hook for {@link ActivityThread} to restore the state of this activity. 903 * 904 * Calls {@link #onSaveInstanceState(android.os.Bundle)} and 905 * {@link #restoreManagedDialogs(android.os.Bundle)}. 906 * 907 * @param savedInstanceState contains the saved state 908 */ 909 final void performRestoreInstanceState(Bundle savedInstanceState) { 910 onRestoreInstanceState(savedInstanceState); 911 restoreManagedDialogs(savedInstanceState); 912 } 913 914 /** 915 * This method is called after {@link #onStart} when the activity is 916 * being re-initialized from a previously saved state, given here in 917 * <var>savedInstanceState</var>. Most implementations will simply use {@link #onCreate} 918 * to restore their state, but it is sometimes convenient to do it here 919 * after all of the initialization has been done or to allow subclasses to 920 * decide whether to use your default implementation. The default 921 * implementation of this method performs a restore of any view state that 922 * had previously been frozen by {@link #onSaveInstanceState}. 923 * 924 * <p>This method is called between {@link #onStart} and 925 * {@link #onPostCreate}. 926 * 927 * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}. 928 * 929 * @see #onCreate 930 * @see #onPostCreate 931 * @see #onResume 932 * @see #onSaveInstanceState 933 */ 934 protected void onRestoreInstanceState(Bundle savedInstanceState) { 935 if (mWindow != null) { 936 Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG); 937 if (windowState != null) { 938 mWindow.restoreHierarchyState(windowState); 939 } 940 } 941 } 942 943 /** 944 * Restore the state of any saved managed dialogs. 945 * 946 * @param savedInstanceState The bundle to restore from. 947 */ 948 private void restoreManagedDialogs(Bundle savedInstanceState) { 949 final Bundle b = savedInstanceState.getBundle(SAVED_DIALOGS_TAG); 950 if (b == null) { 951 return; 952 } 953 954 final int[] ids = b.getIntArray(SAVED_DIALOG_IDS_KEY); 955 final int numDialogs = ids.length; 956 mManagedDialogs = new SparseArray<ManagedDialog>(numDialogs); 957 for (int i = 0; i < numDialogs; i++) { 958 final Integer dialogId = ids[i]; 959 Bundle dialogState = b.getBundle(savedDialogKeyFor(dialogId)); 960 if (dialogState != null) { 961 // Calling onRestoreInstanceState() below will invoke dispatchOnCreate 962 // so tell createDialog() not to do it, otherwise we get an exception 963 final ManagedDialog md = new ManagedDialog(); 964 md.mArgs = b.getBundle(savedDialogArgsKeyFor(dialogId)); 965 md.mDialog = createDialog(dialogId, dialogState, md.mArgs); 966 if (md.mDialog != null) { 967 mManagedDialogs.put(dialogId, md); 968 onPrepareDialog(dialogId, md.mDialog, md.mArgs); 969 md.mDialog.onRestoreInstanceState(dialogState); 970 } 971 } 972 } 973 } 974 975 private Dialog createDialog(Integer dialogId, Bundle state, Bundle args) { 976 final Dialog dialog = onCreateDialog(dialogId, args); 977 if (dialog == null) { 978 return null; 979 } 980 dialog.dispatchOnCreate(state); 981 return dialog; 982 } 983 984 private static String savedDialogKeyFor(int key) { 985 return SAVED_DIALOG_KEY_PREFIX + key; 986 } 987 988 private static String savedDialogArgsKeyFor(int key) { 989 return SAVED_DIALOG_ARGS_KEY_PREFIX + key; 990 } 991 992 /** 993 * Called when activity start-up is complete (after {@link #onStart} 994 * and {@link #onRestoreInstanceState} have been called). Applications will 995 * generally not implement this method; it is intended for system 996 * classes to do final initialization after application code has run. 997 * 998 * <p><em>Derived classes must call through to the super class's 999 * implementation of this method. If they do not, an exception will be 1000 * thrown.</em></p> 1001 * 1002 * @param savedInstanceState If the activity is being re-initialized after 1003 * previously being shut down then this Bundle contains the data it most 1004 * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b> 1005 * @see #onCreate 1006 */ 1007 protected void onPostCreate(Bundle savedInstanceState) { 1008 if (!isChild()) { 1009 mTitleReady = true; 1010 onTitleChanged(getTitle(), getTitleColor()); 1011 } 1012 mCalled = true; 1013 } 1014 1015 /** 1016 * Called after {@link #onCreate} — or after {@link #onRestart} when 1017 * the activity had been stopped, but is now again being displayed to the 1018 * user. It will be followed by {@link #onResume}. 1019 * 1020 * <p><em>Derived classes must call through to the super class's 1021 * implementation of this method. If they do not, an exception will be 1022 * thrown.</em></p> 1023 * 1024 * @see #onCreate 1025 * @see #onStop 1026 * @see #onResume 1027 */ 1028 protected void onStart() { 1029 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this); 1030 mCalled = true; 1031 1032 if (!mLoadersStarted) { 1033 mLoadersStarted = true; 1034 if (mLoaderManager != null) { 1035 mLoaderManager.doStart(); 1036 } else if (!mCheckedForLoaderManager) { 1037 mLoaderManager = getLoaderManager(null, mLoadersStarted, false); 1038 } 1039 mCheckedForLoaderManager = true; 1040 } 1041 1042 getApplication().dispatchActivityStarted(this); 1043 } 1044 1045 /** 1046 * Called after {@link #onStop} when the current activity is being 1047 * re-displayed to the user (the user has navigated back to it). It will 1048 * be followed by {@link #onStart} and then {@link #onResume}. 1049 * 1050 * <p>For activities that are using raw {@link Cursor} objects (instead of 1051 * creating them through 1052 * {@link #managedQuery(android.net.Uri , String[], String, String[], String)}, 1053 * this is usually the place 1054 * where the cursor should be requeried (because you had deactivated it in 1055 * {@link #onStop}. 1056 * 1057 * <p><em>Derived classes must call through to the super class's 1058 * implementation of this method. If they do not, an exception will be 1059 * thrown.</em></p> 1060 * 1061 * @see #onStop 1062 * @see #onStart 1063 * @see #onResume 1064 */ 1065 protected void onRestart() { 1066 mCalled = true; 1067 } 1068 1069 /** 1070 * Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or 1071 * {@link #onPause}, for your activity to start interacting with the user. 1072 * This is a good place to begin animations, open exclusive-access devices 1073 * (such as the camera), etc. 1074 * 1075 * <p>Keep in mind that onResume is not the best indicator that your activity 1076 * is visible to the user; a system window such as the keyguard may be in 1077 * front. Use {@link #onWindowFocusChanged} to know for certain that your 1078 * activity is visible to the user (for example, to resume a game). 1079 * 1080 * <p><em>Derived classes must call through to the super class's 1081 * implementation of this method. If they do not, an exception will be 1082 * thrown.</em></p> 1083 * 1084 * @see #onRestoreInstanceState 1085 * @see #onRestart 1086 * @see #onPostResume 1087 * @see #onPause 1088 */ 1089 protected void onResume() { 1090 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this); 1091 getApplication().dispatchActivityResumed(this); 1092 mCalled = true; 1093 } 1094 1095 /** 1096 * Called when activity resume is complete (after {@link #onResume} has 1097 * been called). Applications will generally not implement this method; 1098 * it is intended for system classes to do final setup after application 1099 * resume code has run. 1100 * 1101 * <p><em>Derived classes must call through to the super class's 1102 * implementation of this method. If they do not, an exception will be 1103 * thrown.</em></p> 1104 * 1105 * @see #onResume 1106 */ 1107 protected void onPostResume() { 1108 final Window win = getWindow(); 1109 if (win != null) win.makeActive(); 1110 if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(true); 1111 mCalled = true; 1112 } 1113 1114 /** 1115 * This is called for activities that set launchMode to "singleTop" in 1116 * their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} 1117 * flag when calling {@link #startActivity}. In either case, when the 1118 * activity is re-launched while at the top of the activity stack instead 1119 * of a new instance of the activity being started, onNewIntent() will be 1120 * called on the existing instance with the Intent that was used to 1121 * re-launch it. 1122 * 1123 * <p>An activity will always be paused before receiving a new intent, so 1124 * you can count on {@link #onResume} being called after this method. 1125 * 1126 * <p>Note that {@link #getIntent} still returns the original Intent. You 1127 * can use {@link #setIntent} to update it to this new Intent. 1128 * 1129 * @param intent The new intent that was started for the activity. 1130 * 1131 * @see #getIntent 1132 * @see #setIntent 1133 * @see #onResume 1134 */ 1135 protected void onNewIntent(Intent intent) { 1136 } 1137 1138 /** 1139 * The hook for {@link ActivityThread} to save the state of this activity. 1140 * 1141 * Calls {@link #onSaveInstanceState(android.os.Bundle)} 1142 * and {@link #saveManagedDialogs(android.os.Bundle)}. 1143 * 1144 * @param outState The bundle to save the state to. 1145 */ 1146 final void performSaveInstanceState(Bundle outState) { 1147 onSaveInstanceState(outState); 1148 saveManagedDialogs(outState); 1149 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState); 1150 } 1151 1152 /** 1153 * Called to retrieve per-instance state from an activity before being killed 1154 * so that the state can be restored in {@link #onCreate} or 1155 * {@link #onRestoreInstanceState} (the {@link Bundle} populated by this method 1156 * will be passed to both). 1157 * 1158 * <p>This method is called before an activity may be killed so that when it 1159 * comes back some time in the future it can restore its state. For example, 1160 * if activity B is launched in front of activity A, and at some point activity 1161 * A is killed to reclaim resources, activity A will have a chance to save the 1162 * current state of its user interface via this method so that when the user 1163 * returns to activity A, the state of the user interface can be restored 1164 * via {@link #onCreate} or {@link #onRestoreInstanceState}. 1165 * 1166 * <p>Do not confuse this method with activity lifecycle callbacks such as 1167 * {@link #onPause}, which is always called when an activity is being placed 1168 * in the background or on its way to destruction, or {@link #onStop} which 1169 * is called before destruction. One example of when {@link #onPause} and 1170 * {@link #onStop} is called and not this method is when a user navigates back 1171 * from activity B to activity A: there is no need to call {@link #onSaveInstanceState} 1172 * on B because that particular instance will never be restored, so the 1173 * system avoids calling it. An example when {@link #onPause} is called and 1174 * not {@link #onSaveInstanceState} is when activity B is launched in front of activity A: 1175 * the system may avoid calling {@link #onSaveInstanceState} on activity A if it isn't 1176 * killed during the lifetime of B since the state of the user interface of 1177 * A will stay intact. 1178 * 1179 * <p>The default implementation takes care of most of the UI per-instance 1180 * state for you by calling {@link android.view.View#onSaveInstanceState()} on each 1181 * view in the hierarchy that has an id, and by saving the id of the currently 1182 * focused view (all of which is restored by the default implementation of 1183 * {@link #onRestoreInstanceState}). If you override this method to save additional 1184 * information not captured by each individual view, you will likely want to 1185 * call through to the default implementation, otherwise be prepared to save 1186 * all of the state of each view yourself. 1187 * 1188 * <p>If called, this method will occur before {@link #onStop}. There are 1189 * no guarantees about whether it will occur before or after {@link #onPause}. 1190 * 1191 * @param outState Bundle in which to place your saved state. 1192 * 1193 * @see #onCreate 1194 * @see #onRestoreInstanceState 1195 * @see #onPause 1196 */ 1197 protected void onSaveInstanceState(Bundle outState) { 1198 outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState()); 1199 Parcelable p = mFragments.saveAllState(); 1200 if (p != null) { 1201 outState.putParcelable(FRAGMENTS_TAG, p); 1202 } 1203 getApplication().dispatchActivitySaveInstanceState(this, outState); 1204 } 1205 1206 /** 1207 * Save the state of any managed dialogs. 1208 * 1209 * @param outState place to store the saved state. 1210 */ 1211 private void saveManagedDialogs(Bundle outState) { 1212 if (mManagedDialogs == null) { 1213 return; 1214 } 1215 1216 final int numDialogs = mManagedDialogs.size(); 1217 if (numDialogs == 0) { 1218 return; 1219 } 1220 1221 Bundle dialogState = new Bundle(); 1222 1223 int[] ids = new int[mManagedDialogs.size()]; 1224 1225 // save each dialog's bundle, gather the ids 1226 for (int i = 0; i < numDialogs; i++) { 1227 final int key = mManagedDialogs.keyAt(i); 1228 ids[i] = key; 1229 final ManagedDialog md = mManagedDialogs.valueAt(i); 1230 dialogState.putBundle(savedDialogKeyFor(key), md.mDialog.onSaveInstanceState()); 1231 if (md.mArgs != null) { 1232 dialogState.putBundle(savedDialogArgsKeyFor(key), md.mArgs); 1233 } 1234 } 1235 1236 dialogState.putIntArray(SAVED_DIALOG_IDS_KEY, ids); 1237 outState.putBundle(SAVED_DIALOGS_TAG, dialogState); 1238 } 1239 1240 1241 /** 1242 * Called as part of the activity lifecycle when an activity is going into 1243 * the background, but has not (yet) been killed. The counterpart to 1244 * {@link #onResume}. 1245 * 1246 * <p>When activity B is launched in front of activity A, this callback will 1247 * be invoked on A. B will not be created until A's {@link #onPause} returns, 1248 * so be sure to not do anything lengthy here. 1249 * 1250 * <p>This callback is mostly used for saving any persistent state the 1251 * activity is editing, to present a "edit in place" model to the user and 1252 * making sure nothing is lost if there are not enough resources to start 1253 * the new activity without first killing this one. This is also a good 1254 * place to do things like stop animations and other things that consume a 1255 * noticeable amount of CPU in order to make the switch to the next activity 1256 * as fast as possible, or to close resources that are exclusive access 1257 * such as the camera. 1258 * 1259 * <p>In situations where the system needs more memory it may kill paused 1260 * processes to reclaim resources. Because of this, you should be sure 1261 * that all of your state is saved by the time you return from 1262 * this function. In general {@link #onSaveInstanceState} is used to save 1263 * per-instance state in the activity and this method is used to store 1264 * global persistent data (in content providers, files, etc.) 1265 * 1266 * <p>After receiving this call you will usually receive a following call 1267 * to {@link #onStop} (after the next activity has been resumed and 1268 * displayed), however in some cases there will be a direct call back to 1269 * {@link #onResume} without going through the stopped state. 1270 * 1271 * <p><em>Derived classes must call through to the super class's 1272 * implementation of this method. If they do not, an exception will be 1273 * thrown.</em></p> 1274 * 1275 * @see #onResume 1276 * @see #onSaveInstanceState 1277 * @see #onStop 1278 */ 1279 protected void onPause() { 1280 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this); 1281 getApplication().dispatchActivityPaused(this); 1282 mCalled = true; 1283 } 1284 1285 /** 1286 * Called as part of the activity lifecycle when an activity is about to go 1287 * into the background as the result of user choice. For example, when the 1288 * user presses the Home key, {@link #onUserLeaveHint} will be called, but 1289 * when an incoming phone call causes the in-call Activity to be automatically 1290 * brought to the foreground, {@link #onUserLeaveHint} will not be called on 1291 * the activity being interrupted. In cases when it is invoked, this method 1292 * is called right before the activity's {@link #onPause} callback. 1293 * 1294 * <p>This callback and {@link #onUserInteraction} are intended to help 1295 * activities manage status bar notifications intelligently; specifically, 1296 * for helping activities determine the proper time to cancel a notfication. 1297 * 1298 * @see #onUserInteraction() 1299 */ 1300 protected void onUserLeaveHint() { 1301 } 1302 1303 /** 1304 * Generate a new thumbnail for this activity. This method is called before 1305 * pausing the activity, and should draw into <var>outBitmap</var> the 1306 * imagery for the desired thumbnail in the dimensions of that bitmap. It 1307 * can use the given <var>canvas</var>, which is configured to draw into the 1308 * bitmap, for rendering if desired. 1309 * 1310 * <p>The default implementation returns fails and does not draw a thumbnail; 1311 * this will result in the platform creating its own thumbnail if needed. 1312 * 1313 * @param outBitmap The bitmap to contain the thumbnail. 1314 * @param canvas Can be used to render into the bitmap. 1315 * 1316 * @return Return true if you have drawn into the bitmap; otherwise after 1317 * you return it will be filled with a default thumbnail. 1318 * 1319 * @see #onCreateDescription 1320 * @see #onSaveInstanceState 1321 * @see #onPause 1322 */ 1323 public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) { 1324 return false; 1325 } 1326 1327 /** 1328 * Generate a new description for this activity. This method is called 1329 * before pausing the activity and can, if desired, return some textual 1330 * description of its current state to be displayed to the user. 1331 * 1332 * <p>The default implementation returns null, which will cause you to 1333 * inherit the description from the previous activity. If all activities 1334 * return null, generally the label of the top activity will be used as the 1335 * description. 1336 * 1337 * @return A description of what the user is doing. It should be short and 1338 * sweet (only a few words). 1339 * 1340 * @see #onCreateThumbnail 1341 * @see #onSaveInstanceState 1342 * @see #onPause 1343 */ 1344 public CharSequence onCreateDescription() { 1345 return null; 1346 } 1347 1348 /** 1349 * This is called when the user is requesting an assist, to build a full 1350 * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current 1351 * application. You can override this method to place into the bundle anything 1352 * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part 1353 * of the assist Intent. The default implementation does nothing. 1354 * 1355 * <p>This function will be called after any global assist callbacks that had 1356 * been registered with {@link Application#registerOnProvideAssistDataListener 1357 * Application.registerOnProvideAssistDataListener}. 1358 */ 1359 public void onProvideAssistData(Bundle data) { 1360 } 1361 1362 /** 1363 * Called when you are no longer visible to the user. You will next 1364 * receive either {@link #onRestart}, {@link #onDestroy}, or nothing, 1365 * depending on later user activity. 1366 * 1367 * <p>Note that this method may never be called, in low memory situations 1368 * where the system does not have enough memory to keep your activity's 1369 * process running after its {@link #onPause} method is called. 1370 * 1371 * <p><em>Derived classes must call through to the super class's 1372 * implementation of this method. If they do not, an exception will be 1373 * thrown.</em></p> 1374 * 1375 * @see #onRestart 1376 * @see #onResume 1377 * @see #onSaveInstanceState 1378 * @see #onDestroy 1379 */ 1380 protected void onStop() { 1381 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this); 1382 if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false); 1383 getApplication().dispatchActivityStopped(this); 1384 mCalled = true; 1385 } 1386 1387 /** 1388 * Perform any final cleanup before an activity is destroyed. This can 1389 * happen either because the activity is finishing (someone called 1390 * {@link #finish} on it, or because the system is temporarily destroying 1391 * this instance of the activity to save space. You can distinguish 1392 * between these two scenarios with the {@link #isFinishing} method. 1393 * 1394 * <p><em>Note: do not count on this method being called as a place for 1395 * saving data! For example, if an activity is editing data in a content 1396 * provider, those edits should be committed in either {@link #onPause} or 1397 * {@link #onSaveInstanceState}, not here.</em> This method is usually implemented to 1398 * free resources like threads that are associated with an activity, so 1399 * that a destroyed activity does not leave such things around while the 1400 * rest of its application is still running. There are situations where 1401 * the system will simply kill the activity's hosting process without 1402 * calling this method (or any others) in it, so it should not be used to 1403 * do things that are intended to remain around after the process goes 1404 * away. 1405 * 1406 * <p><em>Derived classes must call through to the super class's 1407 * implementation of this method. If they do not, an exception will be 1408 * thrown.</em></p> 1409 * 1410 * @see #onPause 1411 * @see #onStop 1412 * @see #finish 1413 * @see #isFinishing 1414 */ 1415 protected void onDestroy() { 1416 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this); 1417 mCalled = true; 1418 1419 // dismiss any dialogs we are managing. 1420 if (mManagedDialogs != null) { 1421 final int numDialogs = mManagedDialogs.size(); 1422 for (int i = 0; i < numDialogs; i++) { 1423 final ManagedDialog md = mManagedDialogs.valueAt(i); 1424 if (md.mDialog.isShowing()) { 1425 md.mDialog.dismiss(); 1426 } 1427 } 1428 mManagedDialogs = null; 1429 } 1430 1431 // close any cursors we are managing. 1432 synchronized (mManagedCursors) { 1433 int numCursors = mManagedCursors.size(); 1434 for (int i = 0; i < numCursors; i++) { 1435 ManagedCursor c = mManagedCursors.get(i); 1436 if (c != null) { 1437 c.mCursor.close(); 1438 } 1439 } 1440 mManagedCursors.clear(); 1441 } 1442 1443 // Close any open search dialog 1444 if (mSearchManager != null) { 1445 mSearchManager.stopSearch(); 1446 } 1447 1448 getApplication().dispatchActivityDestroyed(this); 1449 } 1450 1451 /** 1452 * Called by the system when the device configuration changes while your 1453 * activity is running. Note that this will <em>only</em> be called if 1454 * you have selected configurations you would like to handle with the 1455 * {@link android.R.attr#configChanges} attribute in your manifest. If 1456 * any configuration change occurs that is not selected to be reported 1457 * by that attribute, then instead of reporting it the system will stop 1458 * and restart the activity (to have it launched with the new 1459 * configuration). 1460 * 1461 * <p>At the time that this function has been called, your Resources 1462 * object will have been updated to return resource values matching the 1463 * new configuration. 1464 * 1465 * @param newConfig The new device configuration. 1466 */ 1467 public void onConfigurationChanged(Configuration newConfig) { 1468 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onConfigurationChanged " + this + ": " + newConfig); 1469 mCalled = true; 1470 1471 mFragments.dispatchConfigurationChanged(newConfig); 1472 1473 if (mWindow != null) { 1474 // Pass the configuration changed event to the window 1475 mWindow.onConfigurationChanged(newConfig); 1476 } 1477 1478 if (mActionBar != null) { 1479 // Do this last; the action bar will need to access 1480 // view changes from above. 1481 mActionBar.onConfigurationChanged(newConfig); 1482 } 1483 } 1484 1485 /** 1486 * If this activity is being destroyed because it can not handle a 1487 * configuration parameter being changed (and thus its 1488 * {@link #onConfigurationChanged(Configuration)} method is 1489 * <em>not</em> being called), then you can use this method to discover 1490 * the set of changes that have occurred while in the process of being 1491 * destroyed. Note that there is no guarantee that these will be 1492 * accurate (other changes could have happened at any time), so you should 1493 * only use this as an optimization hint. 1494 * 1495 * @return Returns a bit field of the configuration parameters that are 1496 * changing, as defined by the {@link android.content.res.Configuration} 1497 * class. 1498 */ 1499 public int getChangingConfigurations() { 1500 return mConfigChangeFlags; 1501 } 1502 1503 /** 1504 * Retrieve the non-configuration instance data that was previously 1505 * returned by {@link #onRetainNonConfigurationInstance()}. This will 1506 * be available from the initial {@link #onCreate} and 1507 * {@link #onStart} calls to the new instance, allowing you to extract 1508 * any useful dynamic state from the previous instance. 1509 * 1510 * <p>Note that the data you retrieve here should <em>only</em> be used 1511 * as an optimization for handling configuration changes. You should always 1512 * be able to handle getting a null pointer back, and an activity must 1513 * still be able to restore itself to its previous state (through the 1514 * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this 1515 * function returns null. 1516 * 1517 * @return Returns the object previously returned by 1518 * {@link #onRetainNonConfigurationInstance()}. 1519 * 1520 * @deprecated Use the new {@link Fragment} API 1521 * {@link Fragment#setRetainInstance(boolean)} instead; this is also 1522 * available on older platforms through the Android compatibility package. 1523 */ 1524 @Deprecated 1525 public Object getLastNonConfigurationInstance() { 1526 return mLastNonConfigurationInstances != null 1527 ? mLastNonConfigurationInstances.activity : null; 1528 } 1529 1530 /** 1531 * Called by the system, as part of destroying an 1532 * activity due to a configuration change, when it is known that a new 1533 * instance will immediately be created for the new configuration. You 1534 * can return any object you like here, including the activity instance 1535 * itself, which can later be retrieved by calling 1536 * {@link #getLastNonConfigurationInstance()} in the new activity 1537 * instance. 1538 * 1539 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1540 * or later, consider instead using a {@link Fragment} with 1541 * {@link Fragment#setRetainInstance(boolean) 1542 * Fragment.setRetainInstance(boolean}.</em> 1543 * 1544 * <p>This function is called purely as an optimization, and you must 1545 * not rely on it being called. When it is called, a number of guarantees 1546 * will be made to help optimize configuration switching: 1547 * <ul> 1548 * <li> The function will be called between {@link #onStop} and 1549 * {@link #onDestroy}. 1550 * <li> A new instance of the activity will <em>always</em> be immediately 1551 * created after this one's {@link #onDestroy()} is called. In particular, 1552 * <em>no</em> messages will be dispatched during this time (when the returned 1553 * object does not have an activity to be associated with). 1554 * <li> The object you return here will <em>always</em> be available from 1555 * the {@link #getLastNonConfigurationInstance()} method of the following 1556 * activity instance as described there. 1557 * </ul> 1558 * 1559 * <p>These guarantees are designed so that an activity can use this API 1560 * to propagate extensive state from the old to new activity instance, from 1561 * loaded bitmaps, to network connections, to evenly actively running 1562 * threads. Note that you should <em>not</em> propagate any data that 1563 * may change based on the configuration, including any data loaded from 1564 * resources such as strings, layouts, or drawables. 1565 * 1566 * <p>The guarantee of no message handling during the switch to the next 1567 * activity simplifies use with active objects. For example if your retained 1568 * state is an {@link android.os.AsyncTask} you are guaranteed that its 1569 * call back functions (like {@link android.os.AsyncTask#onPostExecute}) will 1570 * not be called from the call here until you execute the next instance's 1571 * {@link #onCreate(Bundle)}. (Note however that there is of course no such 1572 * guarantee for {@link android.os.AsyncTask#doInBackground} since that is 1573 * running in a separate thread.) 1574 * 1575 * @return Return any Object holding the desired state to propagate to the 1576 * next activity instance. 1577 * 1578 * @deprecated Use the new {@link Fragment} API 1579 * {@link Fragment#setRetainInstance(boolean)} instead; this is also 1580 * available on older platforms through the Android compatibility package. 1581 */ 1582 public Object onRetainNonConfigurationInstance() { 1583 return null; 1584 } 1585 1586 /** 1587 * Retrieve the non-configuration instance data that was previously 1588 * returned by {@link #onRetainNonConfigurationChildInstances()}. This will 1589 * be available from the initial {@link #onCreate} and 1590 * {@link #onStart} calls to the new instance, allowing you to extract 1591 * any useful dynamic state from the previous instance. 1592 * 1593 * <p>Note that the data you retrieve here should <em>only</em> be used 1594 * as an optimization for handling configuration changes. You should always 1595 * be able to handle getting a null pointer back, and an activity must 1596 * still be able to restore itself to its previous state (through the 1597 * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this 1598 * function returns null. 1599 * 1600 * @return Returns the object previously returned by 1601 * {@link #onRetainNonConfigurationChildInstances()} 1602 */ 1603 HashMap<String, Object> getLastNonConfigurationChildInstances() { 1604 return mLastNonConfigurationInstances != null 1605 ? mLastNonConfigurationInstances.children : null; 1606 } 1607 1608 /** 1609 * This method is similar to {@link #onRetainNonConfigurationInstance()} except that 1610 * it should return either a mapping from child activity id strings to arbitrary objects, 1611 * or null. This method is intended to be used by Activity framework subclasses that control a 1612 * set of child activities, such as ActivityGroup. The same guarantees and restrictions apply 1613 * as for {@link #onRetainNonConfigurationInstance()}. The default implementation returns null. 1614 */ 1615 HashMap<String,Object> onRetainNonConfigurationChildInstances() { 1616 return null; 1617 } 1618 1619 NonConfigurationInstances retainNonConfigurationInstances() { 1620 Object activity = onRetainNonConfigurationInstance(); 1621 HashMap<String, Object> children = onRetainNonConfigurationChildInstances(); 1622 ArrayList<Fragment> fragments = mFragments.retainNonConfig(); 1623 boolean retainLoaders = false; 1624 if (mAllLoaderManagers != null) { 1625 // prune out any loader managers that were already stopped and so 1626 // have nothing useful to retain. 1627 LoaderManagerImpl loaders[] = new LoaderManagerImpl[mAllLoaderManagers.size()]; 1628 mAllLoaderManagers.values().toArray(loaders); 1629 if (loaders != null) { 1630 for (int i=0; i<loaders.length; i++) { 1631 LoaderManagerImpl lm = loaders[i]; 1632 if (lm.mRetaining) { 1633 retainLoaders = true; 1634 } else { 1635 lm.doDestroy(); 1636 mAllLoaderManagers.remove(lm.mWho); 1637 } 1638 } 1639 } 1640 } 1641 if (activity == null && children == null && fragments == null && !retainLoaders) { 1642 return null; 1643 } 1644 1645 NonConfigurationInstances nci = new NonConfigurationInstances(); 1646 nci.activity = activity; 1647 nci.children = children; 1648 nci.fragments = fragments; 1649 nci.loaders = mAllLoaderManagers; 1650 return nci; 1651 } 1652 1653 public void onLowMemory() { 1654 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onLowMemory " + this); 1655 mCalled = true; 1656 mFragments.dispatchLowMemory(); 1657 } 1658 1659 public void onTrimMemory(int level) { 1660 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onTrimMemory " + this + ": " + level); 1661 mCalled = true; 1662 mFragments.dispatchTrimMemory(level); 1663 } 1664 1665 /** 1666 * Return the FragmentManager for interacting with fragments associated 1667 * with this activity. 1668 */ 1669 public FragmentManager getFragmentManager() { 1670 return mFragments; 1671 } 1672 1673 void invalidateFragment(String who) { 1674 //Log.v(TAG, "invalidateFragmentIndex: index=" + index); 1675 if (mAllLoaderManagers != null) { 1676 LoaderManagerImpl lm = mAllLoaderManagers.get(who); 1677 if (lm != null && !lm.mRetaining) { 1678 lm.doDestroy(); 1679 mAllLoaderManagers.remove(who); 1680 } 1681 } 1682 } 1683 1684 /** 1685 * Called when a Fragment is being attached to this activity, immediately 1686 * after the call to its {@link Fragment#onAttach Fragment.onAttach()} 1687 * method and before {@link Fragment#onCreate Fragment.onCreate()}. 1688 */ 1689 public void onAttachFragment(Fragment fragment) { 1690 } 1691 1692 /** 1693 * Wrapper around 1694 * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)} 1695 * that gives the resulting {@link Cursor} to call 1696 * {@link #startManagingCursor} so that the activity will manage its 1697 * lifecycle for you. 1698 * 1699 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1700 * or later, consider instead using {@link LoaderManager} instead, available 1701 * via {@link #getLoaderManager()}.</em> 1702 * 1703 * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on a cursor obtained using 1704 * this method, because the activity will do that for you at the appropriate time. However, if 1705 * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will 1706 * not</em> automatically close the cursor and, in that case, you must call 1707 * {@link Cursor#close()}.</p> 1708 * 1709 * @param uri The URI of the content provider to query. 1710 * @param projection List of columns to return. 1711 * @param selection SQL WHERE clause. 1712 * @param sortOrder SQL ORDER BY clause. 1713 * 1714 * @return The Cursor that was returned by query(). 1715 * 1716 * @see ContentResolver#query(android.net.Uri , String[], String, String[], String) 1717 * @see #startManagingCursor 1718 * @hide 1719 * 1720 * @deprecated Use {@link CursorLoader} instead. 1721 */ 1722 @Deprecated 1723 public final Cursor managedQuery(Uri uri, String[] projection, String selection, 1724 String sortOrder) { 1725 Cursor c = getContentResolver().query(uri, projection, selection, null, sortOrder); 1726 if (c != null) { 1727 startManagingCursor(c); 1728 } 1729 return c; 1730 } 1731 1732 /** 1733 * Wrapper around 1734 * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)} 1735 * that gives the resulting {@link Cursor} to call 1736 * {@link #startManagingCursor} so that the activity will manage its 1737 * lifecycle for you. 1738 * 1739 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1740 * or later, consider instead using {@link LoaderManager} instead, available 1741 * via {@link #getLoaderManager()}.</em> 1742 * 1743 * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on a cursor obtained using 1744 * this method, because the activity will do that for you at the appropriate time. However, if 1745 * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will 1746 * not</em> automatically close the cursor and, in that case, you must call 1747 * {@link Cursor#close()}.</p> 1748 * 1749 * @param uri The URI of the content provider to query. 1750 * @param projection List of columns to return. 1751 * @param selection SQL WHERE clause. 1752 * @param selectionArgs The arguments to selection, if any ?s are pesent 1753 * @param sortOrder SQL ORDER BY clause. 1754 * 1755 * @return The Cursor that was returned by query(). 1756 * 1757 * @see ContentResolver#query(android.net.Uri , String[], String, String[], String) 1758 * @see #startManagingCursor 1759 * 1760 * @deprecated Use {@link CursorLoader} instead. 1761 */ 1762 @Deprecated 1763 public final Cursor managedQuery(Uri uri, String[] projection, String selection, 1764 String[] selectionArgs, String sortOrder) { 1765 Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); 1766 if (c != null) { 1767 startManagingCursor(c); 1768 } 1769 return c; 1770 } 1771 1772 /** 1773 * This method allows the activity to take care of managing the given 1774 * {@link Cursor}'s lifecycle for you based on the activity's lifecycle. 1775 * That is, when the activity is stopped it will automatically call 1776 * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted 1777 * it will call {@link Cursor#requery} for you. When the activity is 1778 * destroyed, all managed Cursors will be closed automatically. 1779 * 1780 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1781 * or later, consider instead using {@link LoaderManager} instead, available 1782 * via {@link #getLoaderManager()}.</em> 1783 * 1784 * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on cursor obtained from 1785 * {@link #managedQuery}, because the activity will do that for you at the appropriate time. 1786 * However, if you call {@link #stopManagingCursor} on a cursor from a managed query, the system 1787 * <em>will not</em> automatically close the cursor and, in that case, you must call 1788 * {@link Cursor#close()}.</p> 1789 * 1790 * @param c The Cursor to be managed. 1791 * 1792 * @see #managedQuery(android.net.Uri , String[], String, String[], String) 1793 * @see #stopManagingCursor 1794 * 1795 * @deprecated Use the new {@link android.content.CursorLoader} class with 1796 * {@link LoaderManager} instead; this is also 1797 * available on older platforms through the Android compatibility package. 1798 */ 1799 @Deprecated 1800 public void startManagingCursor(Cursor c) { 1801 synchronized (mManagedCursors) { 1802 mManagedCursors.add(new ManagedCursor(c)); 1803 } 1804 } 1805 1806 /** 1807 * Given a Cursor that was previously given to 1808 * {@link #startManagingCursor}, stop the activity's management of that 1809 * cursor. 1810 * 1811 * <p><strong>Warning:</strong> After calling this method on a cursor from a managed query, 1812 * the system <em>will not</em> automatically close the cursor and you must call 1813 * {@link Cursor#close()}.</p> 1814 * 1815 * @param c The Cursor that was being managed. 1816 * 1817 * @see #startManagingCursor 1818 * 1819 * @deprecated Use the new {@link android.content.CursorLoader} class with 1820 * {@link LoaderManager} instead; this is also 1821 * available on older platforms through the Android compatibility package. 1822 */ 1823 @Deprecated 1824 public void stopManagingCursor(Cursor c) { 1825 synchronized (mManagedCursors) { 1826 final int N = mManagedCursors.size(); 1827 for (int i=0; i<N; i++) { 1828 ManagedCursor mc = mManagedCursors.get(i); 1829 if (mc.mCursor == c) { 1830 mManagedCursors.remove(i); 1831 break; 1832 } 1833 } 1834 } 1835 } 1836 1837 /** 1838 * @deprecated As of {@link android.os.Build.VERSION_CODES#GINGERBREAD} 1839 * this is a no-op. 1840 * @hide 1841 */ 1842 @Deprecated 1843 public void setPersistent(boolean isPersistent) { 1844 } 1845 1846 /** 1847 * Finds a view that was identified by the id attribute from the XML that 1848 * was processed in {@link #onCreate}. 1849 * 1850 * @return The view if found or null otherwise. 1851 */ 1852 public View findViewById(int id) { 1853 return getWindow().findViewById(id); 1854 } 1855 1856 /** 1857 * Retrieve a reference to this activity's ActionBar. 1858 * 1859 * @return The Activity's ActionBar, or null if it does not have one. 1860 */ 1861 public ActionBar getActionBar() { 1862 initActionBar(); 1863 return mActionBar; 1864 } 1865 1866 /** 1867 * Creates a new ActionBar, locates the inflated ActionBarView, 1868 * initializes the ActionBar with the view, and sets mActionBar. 1869 */ 1870 private void initActionBar() { 1871 Window window = getWindow(); 1872 1873 // Initializing the window decor can change window feature flags. 1874 // Make sure that we have the correct set before performing the test below. 1875 window.getDecorView(); 1876 1877 if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) { 1878 return; 1879 } 1880 1881 mActionBar = new ActionBarImpl(this); 1882 mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp); 1883 1884 mWindow.setDefaultIcon(mActivityInfo.getIconResource()); 1885 mWindow.setDefaultLogo(mActivityInfo.getLogoResource()); 1886 } 1887 1888 /** 1889 * Set the activity content from a layout resource. The resource will be 1890 * inflated, adding all top-level views to the activity. 1891 * 1892 * @param layoutResID Resource ID to be inflated. 1893 * 1894 * @see #setContentView(android.view.View) 1895 * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) 1896 */ 1897 public void setContentView(int layoutResID) { 1898 getWindow().setContentView(layoutResID); 1899 initActionBar(); 1900 } 1901 1902 /** 1903 * Set the activity content to an explicit view. This view is placed 1904 * directly into the activity's view hierarchy. It can itself be a complex 1905 * view hierarchy. When calling this method, the layout parameters of the 1906 * specified view are ignored. Both the width and the height of the view are 1907 * set by default to {@link ViewGroup.LayoutParams#MATCH_PARENT}. To use 1908 * your own layout parameters, invoke 1909 * {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)} 1910 * instead. 1911 * 1912 * @param view The desired content to display. 1913 * 1914 * @see #setContentView(int) 1915 * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) 1916 */ 1917 public void setContentView(View view) { 1918 getWindow().setContentView(view); 1919 initActionBar(); 1920 } 1921 1922 /** 1923 * Set the activity content to an explicit view. This view is placed 1924 * directly into the activity's view hierarchy. It can itself be a complex 1925 * view hierarchy. 1926 * 1927 * @param view The desired content to display. 1928 * @param params Layout parameters for the view. 1929 * 1930 * @see #setContentView(android.view.View) 1931 * @see #setContentView(int) 1932 */ 1933 public void setContentView(View view, ViewGroup.LayoutParams params) { 1934 getWindow().setContentView(view, params); 1935 initActionBar(); 1936 } 1937 1938 /** 1939 * Add an additional content view to the activity. Added after any existing 1940 * ones in the activity -- existing views are NOT removed. 1941 * 1942 * @param view The desired content to display. 1943 * @param params Layout parameters for the view. 1944 */ 1945 public void addContentView(View view, ViewGroup.LayoutParams params) { 1946 getWindow().addContentView(view, params); 1947 initActionBar(); 1948 } 1949 1950 /** 1951 * Sets whether this activity is finished when touched outside its window's 1952 * bounds. 1953 */ 1954 public void setFinishOnTouchOutside(boolean finish) { 1955 mWindow.setCloseOnTouchOutside(finish); 1956 } 1957 1958 /** 1959 * Use with {@link #setDefaultKeyMode} to turn off default handling of 1960 * keys. 1961 * 1962 * @see #setDefaultKeyMode 1963 */ 1964 static public final int DEFAULT_KEYS_DISABLE = 0; 1965 /** 1966 * Use with {@link #setDefaultKeyMode} to launch the dialer during default 1967 * key handling. 1968 * 1969 * @see #setDefaultKeyMode 1970 */ 1971 static public final int DEFAULT_KEYS_DIALER = 1; 1972 /** 1973 * Use with {@link #setDefaultKeyMode} to execute a menu shortcut in 1974 * default key handling. 1975 * 1976 * <p>That is, the user does not need to hold down the menu key to execute menu shortcuts. 1977 * 1978 * @see #setDefaultKeyMode 1979 */ 1980 static public final int DEFAULT_KEYS_SHORTCUT = 2; 1981 /** 1982 * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes 1983 * will start an application-defined search. (If the application or activity does not 1984 * actually define a search, the the keys will be ignored.) 1985 * 1986 * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details. 1987 * 1988 * @see #setDefaultKeyMode 1989 */ 1990 static public final int DEFAULT_KEYS_SEARCH_LOCAL = 3; 1991 1992 /** 1993 * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes 1994 * will start a global search (typically web search, but some platforms may define alternate 1995 * methods for global search) 1996 * 1997 * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details. 1998 * 1999 * @see #setDefaultKeyMode 2000 */ 2001 static public final int DEFAULT_KEYS_SEARCH_GLOBAL = 4; 2002 2003 /** 2004 * Select the default key handling for this activity. This controls what 2005 * will happen to key events that are not otherwise handled. The default 2006 * mode ({@link #DEFAULT_KEYS_DISABLE}) will simply drop them on the 2007 * floor. Other modes allow you to launch the dialer 2008 * ({@link #DEFAULT_KEYS_DIALER}), execute a shortcut in your options 2009 * menu without requiring the menu key be held down 2010 * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL} 2011 * and {@link #DEFAULT_KEYS_SEARCH_GLOBAL}). 2012 * 2013 * <p>Note that the mode selected here does not impact the default 2014 * handling of system keys, such as the "back" and "menu" keys, and your 2015 * activity and its views always get a first chance to receive and handle 2016 * all application keys. 2017 * 2018 * @param mode The desired default key mode constant. 2019 * 2020 * @see #DEFAULT_KEYS_DISABLE 2021 * @see #DEFAULT_KEYS_DIALER 2022 * @see #DEFAULT_KEYS_SHORTCUT 2023 * @see #DEFAULT_KEYS_SEARCH_LOCAL 2024 * @see #DEFAULT_KEYS_SEARCH_GLOBAL 2025 * @see #onKeyDown 2026 */ 2027 public final void setDefaultKeyMode(int mode) { 2028 mDefaultKeyMode = mode; 2029 2030 // Some modes use a SpannableStringBuilder to track & dispatch input events 2031 // This list must remain in sync with the switch in onKeyDown() 2032 switch (mode) { 2033 case DEFAULT_KEYS_DISABLE: 2034 case DEFAULT_KEYS_SHORTCUT: 2035 mDefaultKeySsb = null; // not used in these modes 2036 break; 2037 case DEFAULT_KEYS_DIALER: 2038 case DEFAULT_KEYS_SEARCH_LOCAL: 2039 case DEFAULT_KEYS_SEARCH_GLOBAL: 2040 mDefaultKeySsb = new SpannableStringBuilder(); 2041 Selection.setSelection(mDefaultKeySsb,0); 2042 break; 2043 default: 2044 throw new IllegalArgumentException(); 2045 } 2046 } 2047 2048 /** 2049 * Called when a key was pressed down and not handled by any of the views 2050 * inside of the activity. So, for example, key presses while the cursor 2051 * is inside a TextView will not trigger the event (unless it is a navigation 2052 * to another object) because TextView handles its own key presses. 2053 * 2054 * <p>If the focused view didn't want this event, this method is called. 2055 * 2056 * <p>The default implementation takes care of {@link KeyEvent#KEYCODE_BACK} 2057 * by calling {@link #onBackPressed()}, though the behavior varies based 2058 * on the application compatibility mode: for 2059 * {@link android.os.Build.VERSION_CODES#ECLAIR} or later applications, 2060 * it will set up the dispatch to call {@link #onKeyUp} where the action 2061 * will be performed; for earlier applications, it will perform the 2062 * action immediately in on-down, as those versions of the platform 2063 * behaved. 2064 * 2065 * <p>Other additional default key handling may be performed 2066 * if configured with {@link #setDefaultKeyMode}. 2067 * 2068 * @return Return <code>true</code> to prevent this event from being propagated 2069 * further, or <code>false</code> to indicate that you have not handled 2070 * this event and it should continue to be propagated. 2071 * @see #onKeyUp 2072 * @see android.view.KeyEvent 2073 */ 2074 public boolean onKeyDown(int keyCode, KeyEvent event) { 2075 if (keyCode == KeyEvent.KEYCODE_BACK) { 2076 if (getApplicationInfo().targetSdkVersion 2077 >= Build.VERSION_CODES.ECLAIR) { 2078 event.startTracking(); 2079 } else { 2080 onBackPressed(); 2081 } 2082 return true; 2083 } 2084 2085 if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) { 2086 return false; 2087 } else if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) { 2088 if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL, 2089 keyCode, event, Menu.FLAG_ALWAYS_PERFORM_CLOSE)) { 2090 return true; 2091 } 2092 return false; 2093 } else { 2094 // Common code for DEFAULT_KEYS_DIALER & DEFAULT_KEYS_SEARCH_* 2095 boolean clearSpannable = false; 2096 boolean handled; 2097 if ((event.getRepeatCount() != 0) || event.isSystem()) { 2098 clearSpannable = true; 2099 handled = false; 2100 } else { 2101 handled = TextKeyListener.getInstance().onKeyDown( 2102 null, mDefaultKeySsb, keyCode, event); 2103 if (handled && mDefaultKeySsb.length() > 0) { 2104 // something useable has been typed - dispatch it now. 2105 2106 final String str = mDefaultKeySsb.toString(); 2107 clearSpannable = true; 2108 2109 switch (mDefaultKeyMode) { 2110 case DEFAULT_KEYS_DIALER: 2111 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + str)); 2112 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2113 startActivity(intent); 2114 break; 2115 case DEFAULT_KEYS_SEARCH_LOCAL: 2116 startSearch(str, false, null, false); 2117 break; 2118 case DEFAULT_KEYS_SEARCH_GLOBAL: 2119 startSearch(str, false, null, true); 2120 break; 2121 } 2122 } 2123 } 2124 if (clearSpannable) { 2125 mDefaultKeySsb.clear(); 2126 mDefaultKeySsb.clearSpans(); 2127 Selection.setSelection(mDefaultKeySsb,0); 2128 } 2129 return handled; 2130 } 2131 } 2132 2133 /** 2134 * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent) 2135 * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle 2136 * the event). 2137 */ 2138 public boolean onKeyLongPress(int keyCode, KeyEvent event) { 2139 return false; 2140 } 2141 2142 /** 2143 * Called when a key was released and not handled by any of the views 2144 * inside of the activity. So, for example, key presses while the cursor 2145 * is inside a TextView will not trigger the event (unless it is a navigation 2146 * to another object) because TextView handles its own key presses. 2147 * 2148 * <p>The default implementation handles KEYCODE_BACK to stop the activity 2149 * and go back. 2150 * 2151 * @return Return <code>true</code> to prevent this event from being propagated 2152 * further, or <code>false</code> to indicate that you have not handled 2153 * this event and it should continue to be propagated. 2154 * @see #onKeyDown 2155 * @see KeyEvent 2156 */ 2157 public boolean onKeyUp(int keyCode, KeyEvent event) { 2158 if (getApplicationInfo().targetSdkVersion 2159 >= Build.VERSION_CODES.ECLAIR) { 2160 if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() 2161 && !event.isCanceled()) { 2162 onBackPressed(); 2163 return true; 2164 } 2165 } 2166 return false; 2167 } 2168 2169 /** 2170 * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent) 2171 * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle 2172 * the event). 2173 */ 2174 public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { 2175 return false; 2176 } 2177 2178 /** 2179 * Called when the activity has detected the user's press of the back 2180 * key. The default implementation simply finishes the current activity, 2181 * but you can override this to do whatever you want. 2182 */ 2183 public void onBackPressed() { 2184 if (!mFragments.popBackStackImmediate()) { 2185 finish(); 2186 } 2187 } 2188 2189 /** 2190 * Called when a key shortcut event is not handled by any of the views in the Activity. 2191 * Override this method to implement global key shortcuts for the Activity. 2192 * Key shortcuts can also be implemented by setting the 2193 * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items. 2194 * 2195 * @param keyCode The value in event.getKeyCode(). 2196 * @param event Description of the key event. 2197 * @return True if the key shortcut was handled. 2198 */ 2199 public boolean onKeyShortcut(int keyCode, KeyEvent event) { 2200 return false; 2201 } 2202 2203 /** 2204 * Called when a touch screen event was not handled by any of the views 2205 * under it. This is most useful to process touch events that happen 2206 * outside of your window bounds, where there is no view to receive it. 2207 * 2208 * @param event The touch screen event being processed. 2209 * 2210 * @return Return true if you have consumed the event, false if you haven't. 2211 * The default implementation always returns false. 2212 */ 2213 public boolean onTouchEvent(MotionEvent event) { 2214 if (mWindow.shouldCloseOnTouch(this, event)) { 2215 finish(); 2216 return true; 2217 } 2218 2219 return false; 2220 } 2221 2222 /** 2223 * Called when the trackball was moved and not handled by any of the 2224 * views inside of the activity. So, for example, if the trackball moves 2225 * while focus is on a button, you will receive a call here because 2226 * buttons do not normally do anything with trackball events. The call 2227 * here happens <em>before</em> trackball movements are converted to 2228 * DPAD key events, which then get sent back to the view hierarchy, and 2229 * will be processed at the point for things like focus navigation. 2230 * 2231 * @param event The trackball event being processed. 2232 * 2233 * @return Return true if you have consumed the event, false if you haven't. 2234 * The default implementation always returns false. 2235 */ 2236 public boolean onTrackballEvent(MotionEvent event) { 2237 return false; 2238 } 2239 2240 /** 2241 * Called when a generic motion event was not handled by any of the 2242 * views inside of the activity. 2243 * <p> 2244 * Generic motion events describe joystick movements, mouse hovers, track pad 2245 * touches, scroll wheel movements and other input events. The 2246 * {@link MotionEvent#getSource() source} of the motion event specifies 2247 * the class of input that was received. Implementations of this method 2248 * must examine the bits in the source before processing the event. 2249 * The following code example shows how this is done. 2250 * </p><p> 2251 * Generic motion events with source class 2252 * {@link android.view.InputDevice#SOURCE_CLASS_POINTER} 2253 * are delivered to the view under the pointer. All other generic motion events are 2254 * delivered to the focused view. 2255 * </p><p> 2256 * See {@link View#onGenericMotionEvent(MotionEvent)} for an example of how to 2257 * handle this event. 2258 * </p> 2259 * 2260 * @param event The generic motion event being processed. 2261 * 2262 * @return Return true if you have consumed the event, false if you haven't. 2263 * The default implementation always returns false. 2264 */ 2265 public boolean onGenericMotionEvent(MotionEvent event) { 2266 return false; 2267 } 2268 2269 /** 2270 * Called whenever a key, touch, or trackball event is dispatched to the 2271 * activity. Implement this method if you wish to know that the user has 2272 * interacted with the device in some way while your activity is running. 2273 * This callback and {@link #onUserLeaveHint} are intended to help 2274 * activities manage status bar notifications intelligently; specifically, 2275 * for helping activities determine the proper time to cancel a notfication. 2276 * 2277 * <p>All calls to your activity's {@link #onUserLeaveHint} callback will 2278 * be accompanied by calls to {@link #onUserInteraction}. This 2279 * ensures that your activity will be told of relevant user activity such 2280 * as pulling down the notification pane and touching an item there. 2281 * 2282 * <p>Note that this callback will be invoked for the touch down action 2283 * that begins a touch gesture, but may not be invoked for the touch-moved 2284 * and touch-up actions that follow. 2285 * 2286 * @see #onUserLeaveHint() 2287 */ 2288 public void onUserInteraction() { 2289 } 2290 2291 public void onWindowAttributesChanged(WindowManager.LayoutParams params) { 2292 // Update window manager if: we have a view, that view is 2293 // attached to its parent (which will be a RootView), and 2294 // this activity is not embedded. 2295 if (mParent == null) { 2296 View decor = mDecor; 2297 if (decor != null && decor.getParent() != null) { 2298 getWindowManager().updateViewLayout(decor, params); 2299 } 2300 } 2301 } 2302 2303 public void onContentChanged() { 2304 } 2305 2306 /** 2307 * Called when the current {@link Window} of the activity gains or loses 2308 * focus. This is the best indicator of whether this activity is visible 2309 * to the user. The default implementation clears the key tracking 2310 * state, so should always be called. 2311 * 2312 * <p>Note that this provides information about global focus state, which 2313 * is managed independently of activity lifecycles. As such, while focus 2314 * changes will generally have some relation to lifecycle changes (an 2315 * activity that is stopped will not generally get window focus), you 2316 * should not rely on any particular order between the callbacks here and 2317 * those in the other lifecycle methods such as {@link #onResume}. 2318 * 2319 * <p>As a general rule, however, a resumed activity will have window 2320 * focus... unless it has displayed other dialogs or popups that take 2321 * input focus, in which case the activity itself will not have focus 2322 * when the other windows have it. Likewise, the system may display 2323 * system-level windows (such as the status bar notification panel or 2324 * a system alert) which will temporarily take window input focus without 2325 * pausing the foreground activity. 2326 * 2327 * @param hasFocus Whether the window of this activity has focus. 2328 * 2329 * @see #hasWindowFocus() 2330 * @see #onResume 2331 * @see View#onWindowFocusChanged(boolean) 2332 */ 2333 public void onWindowFocusChanged(boolean hasFocus) { 2334 } 2335 2336 /** 2337 * Called when the main window associated with the activity has been 2338 * attached to the window manager. 2339 * See {@link View#onAttachedToWindow() View.onAttachedToWindow()} 2340 * for more information. 2341 * @see View#onAttachedToWindow 2342 */ 2343 public void onAttachedToWindow() { 2344 } 2345 2346 /** 2347 * Called when the main window associated with the activity has been 2348 * detached from the window manager. 2349 * See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()} 2350 * for more information. 2351 * @see View#onDetachedFromWindow 2352 */ 2353 public void onDetachedFromWindow() { 2354 } 2355 2356 /** 2357 * Returns true if this activity's <em>main</em> window currently has window focus. 2358 * Note that this is not the same as the view itself having focus. 2359 * 2360 * @return True if this activity's main window currently has window focus. 2361 * 2362 * @see #onWindowAttributesChanged(android.view.WindowManager.LayoutParams) 2363 */ 2364 public boolean hasWindowFocus() { 2365 Window w = getWindow(); 2366 if (w != null) { 2367 View d = w.getDecorView(); 2368 if (d != null) { 2369 return d.hasWindowFocus(); 2370 } 2371 } 2372 return false; 2373 } 2374 2375 /** 2376 * Called to process key events. You can override this to intercept all 2377 * key events before they are dispatched to the window. Be sure to call 2378 * this implementation for key events that should be handled normally. 2379 * 2380 * @param event The key event. 2381 * 2382 * @return boolean Return true if this event was consumed. 2383 */ 2384 public boolean dispatchKeyEvent(KeyEvent event) { 2385 onUserInteraction(); 2386 Window win = getWindow(); 2387 if (win.superDispatchKeyEvent(event)) { 2388 return true; 2389 } 2390 View decor = mDecor; 2391 if (decor == null) decor = win.getDecorView(); 2392 return event.dispatch(this, decor != null 2393 ? decor.getKeyDispatcherState() : null, this); 2394 } 2395 2396 /** 2397 * Called to process a key shortcut event. 2398 * You can override this to intercept all key shortcut events before they are 2399 * dispatched to the window. Be sure to call this implementation for key shortcut 2400 * events that should be handled normally. 2401 * 2402 * @param event The key shortcut event. 2403 * @return True if this event was consumed. 2404 */ 2405 public boolean dispatchKeyShortcutEvent(KeyEvent event) { 2406 onUserInteraction(); 2407 if (getWindow().superDispatchKeyShortcutEvent(event)) { 2408 return true; 2409 } 2410 return onKeyShortcut(event.getKeyCode(), event); 2411 } 2412 2413 /** 2414 * Called to process touch screen events. You can override this to 2415 * intercept all touch screen events before they are dispatched to the 2416 * window. Be sure to call this implementation for touch screen events 2417 * that should be handled normally. 2418 * 2419 * @param ev The touch screen event. 2420 * 2421 * @return boolean Return true if this event was consumed. 2422 */ 2423 public boolean dispatchTouchEvent(MotionEvent ev) { 2424 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 2425 onUserInteraction(); 2426 } 2427 if (getWindow().superDispatchTouchEvent(ev)) { 2428 return true; 2429 } 2430 return onTouchEvent(ev); 2431 } 2432 2433 /** 2434 * Called to process trackball events. You can override this to 2435 * intercept all trackball events before they are dispatched to the 2436 * window. Be sure to call this implementation for trackball events 2437 * that should be handled normally. 2438 * 2439 * @param ev The trackball event. 2440 * 2441 * @return boolean Return true if this event was consumed. 2442 */ 2443 public boolean dispatchTrackballEvent(MotionEvent ev) { 2444 onUserInteraction(); 2445 if (getWindow().superDispatchTrackballEvent(ev)) { 2446 return true; 2447 } 2448 return onTrackballEvent(ev); 2449 } 2450 2451 /** 2452 * Called to process generic motion events. You can override this to 2453 * intercept all generic motion events before they are dispatched to the 2454 * window. Be sure to call this implementation for generic motion events 2455 * that should be handled normally. 2456 * 2457 * @param ev The generic motion event. 2458 * 2459 * @return boolean Return true if this event was consumed. 2460 */ 2461 public boolean dispatchGenericMotionEvent(MotionEvent ev) { 2462 onUserInteraction(); 2463 if (getWindow().superDispatchGenericMotionEvent(ev)) { 2464 return true; 2465 } 2466 return onGenericMotionEvent(ev); 2467 } 2468 2469 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 2470 event.setClassName(getClass().getName()); 2471 event.setPackageName(getPackageName()); 2472 2473 LayoutParams params = getWindow().getAttributes(); 2474 boolean isFullScreen = (params.width == LayoutParams.MATCH_PARENT) && 2475 (params.height == LayoutParams.MATCH_PARENT); 2476 event.setFullScreen(isFullScreen); 2477 2478 CharSequence title = getTitle(); 2479 if (!TextUtils.isEmpty(title)) { 2480 event.getText().add(title); 2481 } 2482 2483 return true; 2484 } 2485 2486 /** 2487 * Default implementation of 2488 * {@link android.view.Window.Callback#onCreatePanelView} 2489 * for activities. This 2490 * simply returns null so that all panel sub-windows will have the default 2491 * menu behavior. 2492 */ 2493 public View onCreatePanelView(int featureId) { 2494 return null; 2495 } 2496 2497 /** 2498 * Default implementation of 2499 * {@link android.view.Window.Callback#onCreatePanelMenu} 2500 * for activities. This calls through to the new 2501 * {@link #onCreateOptionsMenu} method for the 2502 * {@link android.view.Window#FEATURE_OPTIONS_PANEL} panel, 2503 * so that subclasses of Activity don't need to deal with feature codes. 2504 */ 2505 public boolean onCreatePanelMenu(int featureId, Menu menu) { 2506 if (featureId == Window.FEATURE_OPTIONS_PANEL) { 2507 boolean show = onCreateOptionsMenu(menu); 2508 show |= mFragments.dispatchCreateOptionsMenu(menu, getMenuInflater()); 2509 return show; 2510 } 2511 return false; 2512 } 2513 2514 /** 2515 * Default implementation of 2516 * {@link android.view.Window.Callback#onPreparePanel} 2517 * for activities. This 2518 * calls through to the new {@link #onPrepareOptionsMenu} method for the 2519 * {@link android.view.Window#FEATURE_OPTIONS_PANEL} 2520 * panel, so that subclasses of 2521 * Activity don't need to deal with feature codes. 2522 */ 2523 public boolean onPreparePanel(int featureId, View view, Menu menu) { 2524 if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) { 2525 boolean goforit = onPrepareOptionsMenu(menu); 2526 goforit |= mFragments.dispatchPrepareOptionsMenu(menu); 2527 return goforit; 2528 } 2529 return true; 2530 } 2531 2532 /** 2533 * {@inheritDoc} 2534 * 2535 * @return The default implementation returns true. 2536 */ 2537 public boolean onMenuOpened(int featureId, Menu menu) { 2538 if (featureId == Window.FEATURE_ACTION_BAR) { 2539 initActionBar(); 2540 if (mActionBar != null) { 2541 mActionBar.dispatchMenuVisibilityChanged(true); 2542 } else { 2543 Log.e(TAG, "Tried to open action bar menu with no action bar"); 2544 } 2545 } 2546 return true; 2547 } 2548 2549 /** 2550 * Default implementation of 2551 * {@link android.view.Window.Callback#onMenuItemSelected} 2552 * for activities. This calls through to the new 2553 * {@link #onOptionsItemSelected} method for the 2554 * {@link android.view.Window#FEATURE_OPTIONS_PANEL} 2555 * panel, so that subclasses of 2556 * Activity don't need to deal with feature codes. 2557 */ 2558 public boolean onMenuItemSelected(int featureId, MenuItem item) { 2559 CharSequence titleCondensed = item.getTitleCondensed(); 2560 2561 switch (featureId) { 2562 case Window.FEATURE_OPTIONS_PANEL: 2563 // Put event logging here so it gets called even if subclass 2564 // doesn't call through to superclass's implmeentation of each 2565 // of these methods below 2566 if(titleCondensed != null) { 2567 EventLog.writeEvent(50000, 0, titleCondensed.toString()); 2568 } 2569 if (onOptionsItemSelected(item)) { 2570 return true; 2571 } 2572 if (mFragments.dispatchOptionsItemSelected(item)) { 2573 return true; 2574 } 2575 if (item.getItemId() == android.R.id.home && mActionBar != null && 2576 (mActionBar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) { 2577 if (mParent == null) { 2578 return onNavigateUp(); 2579 } else { 2580 return mParent.onNavigateUpFromChild(this); 2581 } 2582 } 2583 return false; 2584 2585 case Window.FEATURE_CONTEXT_MENU: 2586 if(titleCondensed != null) { 2587 EventLog.writeEvent(50000, 1, titleCondensed.toString()); 2588 } 2589 if (onContextItemSelected(item)) { 2590 return true; 2591 } 2592 return mFragments.dispatchContextItemSelected(item); 2593 2594 default: 2595 return false; 2596 } 2597 } 2598 2599 /** 2600 * Default implementation of 2601 * {@link android.view.Window.Callback#onPanelClosed(int, Menu)} for 2602 * activities. This calls through to {@link #onOptionsMenuClosed(Menu)} 2603 * method for the {@link android.view.Window#FEATURE_OPTIONS_PANEL} panel, 2604 * so that subclasses of Activity don't need to deal with feature codes. 2605 * For context menus ({@link Window#FEATURE_CONTEXT_MENU}), the 2606 * {@link #onContextMenuClosed(Menu)} will be called. 2607 */ 2608 public void onPanelClosed(int featureId, Menu menu) { 2609 switch (featureId) { 2610 case Window.FEATURE_OPTIONS_PANEL: 2611 mFragments.dispatchOptionsMenuClosed(menu); 2612 onOptionsMenuClosed(menu); 2613 break; 2614 2615 case Window.FEATURE_CONTEXT_MENU: 2616 onContextMenuClosed(menu); 2617 break; 2618 2619 case Window.FEATURE_ACTION_BAR: 2620 initActionBar(); 2621 mActionBar.dispatchMenuVisibilityChanged(false); 2622 break; 2623 } 2624 } 2625 2626 /** 2627 * Declare that the options menu has changed, so should be recreated. 2628 * The {@link #onCreateOptionsMenu(Menu)} method will be called the next 2629 * time it needs to be displayed. 2630 */ 2631 public void invalidateOptionsMenu() { 2632 mWindow.invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL); 2633 } 2634 2635 /** 2636 * Initialize the contents of the Activity's standard options menu. You 2637 * should place your menu items in to <var>menu</var>. 2638 * 2639 * <p>This is only called once, the first time the options menu is 2640 * displayed. To update the menu every time it is displayed, see 2641 * {@link #onPrepareOptionsMenu}. 2642 * 2643 * <p>The default implementation populates the menu with standard system 2644 * menu items. These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that 2645 * they will be correctly ordered with application-defined menu items. 2646 * Deriving classes should always call through to the base implementation. 2647 * 2648 * <p>You can safely hold on to <var>menu</var> (and any items created 2649 * from it), making modifications to it as desired, until the next 2650 * time onCreateOptionsMenu() is called. 2651 * 2652 * <p>When you add items to the menu, you can implement the Activity's 2653 * {@link #onOptionsItemSelected} method to handle them there. 2654 * 2655 * @param menu The options menu in which you place your items. 2656 * 2657 * @return You must return true for the menu to be displayed; 2658 * if you return false it will not be shown. 2659 * 2660 * @see #onPrepareOptionsMenu 2661 * @see #onOptionsItemSelected 2662 */ 2663 public boolean onCreateOptionsMenu(Menu menu) { 2664 if (mParent != null) { 2665 return mParent.onCreateOptionsMenu(menu); 2666 } 2667 return true; 2668 } 2669 2670 /** 2671 * Prepare the Screen's standard options menu to be displayed. This is 2672 * called right before the menu is shown, every time it is shown. You can 2673 * use this method to efficiently enable/disable items or otherwise 2674 * dynamically modify the contents. 2675 * 2676 * <p>The default implementation updates the system menu items based on the 2677 * activity's state. Deriving classes should always call through to the 2678 * base class implementation. 2679 * 2680 * @param menu The options menu as last shown or first initialized by 2681 * onCreateOptionsMenu(). 2682 * 2683 * @return You must return true for the menu to be displayed; 2684 * if you return false it will not be shown. 2685 * 2686 * @see #onCreateOptionsMenu 2687 */ 2688 public boolean onPrepareOptionsMenu(Menu menu) { 2689 if (mParent != null) { 2690 return mParent.onPrepareOptionsMenu(menu); 2691 } 2692 return true; 2693 } 2694 2695 /** 2696 * This hook is called whenever an item in your options menu is selected. 2697 * The default implementation simply returns false to have the normal 2698 * processing happen (calling the item's Runnable or sending a message to 2699 * its Handler as appropriate). You can use this method for any items 2700 * for which you would like to do processing without those other 2701 * facilities. 2702 * 2703 * <p>Derived classes should call through to the base class for it to 2704 * perform the default menu handling.</p> 2705 * 2706 * @param item The menu item that was selected. 2707 * 2708 * @return boolean Return false to allow normal menu processing to 2709 * proceed, true to consume it here. 2710 * 2711 * @see #onCreateOptionsMenu 2712 */ 2713 public boolean onOptionsItemSelected(MenuItem item) { 2714 if (mParent != null) { 2715 return mParent.onOptionsItemSelected(item); 2716 } 2717 return false; 2718 } 2719 2720 /** 2721 * This method is called whenever the user chooses to navigate Up within your application's 2722 * activity hierarchy from the action bar. 2723 * 2724 * <p>If the attribute {@link android.R.attr#parentActivityName parentActivityName} 2725 * was specified in the manifest for this activity or an activity-alias to it, 2726 * default Up navigation will be handled automatically. If any activity 2727 * along the parent chain requires extra Intent arguments, the Activity subclass 2728 * should override the method {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)} 2729 * to supply those arguments.</p> 2730 * 2731 * <p>See <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a> 2732 * from the developer guide and <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> 2733 * from the design guide for more information about navigating within your app.</p> 2734 * 2735 * <p>See the {@link TaskStackBuilder} class and the Activity methods 2736 * {@link #getParentActivityIntent()}, {@link #shouldUpRecreateTask(Intent)}, and 2737 * {@link #navigateUpTo(Intent)} for help implementing custom Up navigation. 2738 * The AppNavigation sample application in the Android SDK is also available for reference.</p> 2739 * 2740 * @return true if Up navigation completed successfully and this Activity was finished, 2741 * false otherwise. 2742 */ 2743 public boolean onNavigateUp() { 2744 // Automatically handle hierarchical Up navigation if the proper 2745 // metadata is available. 2746 Intent upIntent = getParentActivityIntent(); 2747 if (upIntent != null) { 2748 if (mActivityInfo.taskAffinity == null) { 2749 // Activities with a null affinity are special; they really shouldn't 2750 // specify a parent activity intent in the first place. Just finish 2751 // the current activity and call it a day. 2752 finish(); 2753 } else if (shouldUpRecreateTask(upIntent)) { 2754 TaskStackBuilder b = TaskStackBuilder.create(this); 2755 onCreateNavigateUpTaskStack(b); 2756 onPrepareNavigateUpTaskStack(b); 2757 b.startActivities(); 2758 2759 // We can't finishAffinity if we have a result. 2760 // Fall back and simply finish the current activity instead. 2761 if (mResultCode != RESULT_CANCELED || mResultData != null) { 2762 // Tell the developer what's going on to avoid hair-pulling. 2763 Log.i(TAG, "onNavigateUp only finishing topmost activity to return a result"); 2764 finish(); 2765 } else { 2766 finishAffinity(); 2767 } 2768 } else { 2769 navigateUpTo(upIntent); 2770 } 2771 return true; 2772 } 2773 return false; 2774 } 2775 2776 /** 2777 * This is called when a child activity of this one attempts to navigate up. 2778 * The default implementation simply calls onNavigateUp() on this activity (the parent). 2779 * 2780 * @param child The activity making the call. 2781 */ 2782 public boolean onNavigateUpFromChild(Activity child) { 2783 return onNavigateUp(); 2784 } 2785 2786 /** 2787 * Define the synthetic task stack that will be generated during Up navigation from 2788 * a different task. 2789 * 2790 * <p>The default implementation of this method adds the parent chain of this activity 2791 * as specified in the manifest to the supplied {@link TaskStackBuilder}. Applications 2792 * may choose to override this method to construct the desired task stack in a different 2793 * way.</p> 2794 * 2795 * <p>This method will be invoked by the default implementation of {@link #onNavigateUp()} 2796 * if {@link #shouldUpRecreateTask(Intent)} returns true when supplied with the intent 2797 * returned by {@link #getParentActivityIntent()}.</p> 2798 * 2799 * <p>Applications that wish to supply extra Intent parameters to the parent stack defined 2800 * by the manifest should override {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)}.</p> 2801 * 2802 * @param builder An empty TaskStackBuilder - the application should add intents representing 2803 * the desired task stack 2804 */ 2805 public void onCreateNavigateUpTaskStack(TaskStackBuilder builder) { 2806 builder.addParentStack(this); 2807 } 2808 2809 /** 2810 * Prepare the synthetic task stack that will be generated during Up navigation 2811 * from a different task. 2812 * 2813 * <p>This method receives the {@link TaskStackBuilder} with the constructed series of 2814 * Intents as generated by {@link #onCreateNavigateUpTaskStack(TaskStackBuilder)}. 2815 * If any extra data should be added to these intents before launching the new task, 2816 * the application should override this method and add that data here.</p> 2817 * 2818 * @param builder A TaskStackBuilder that has been populated with Intents by 2819 * onCreateNavigateUpTaskStack. 2820 */ 2821 public void onPrepareNavigateUpTaskStack(TaskStackBuilder builder) { 2822 } 2823 2824 /** 2825 * This hook is called whenever the options menu is being closed (either by the user canceling 2826 * the menu with the back/menu button, or when an item is selected). 2827 * 2828 * @param menu The options menu as last shown or first initialized by 2829 * onCreateOptionsMenu(). 2830 */ 2831 public void onOptionsMenuClosed(Menu menu) { 2832 if (mParent != null) { 2833 mParent.onOptionsMenuClosed(menu); 2834 } 2835 } 2836 2837 /** 2838 * Programmatically opens the options menu. If the options menu is already 2839 * open, this method does nothing. 2840 */ 2841 public void openOptionsMenu() { 2842 mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null); 2843 } 2844 2845 /** 2846 * Progammatically closes the options menu. If the options menu is already 2847 * closed, this method does nothing. 2848 */ 2849 public void closeOptionsMenu() { 2850 mWindow.closePanel(Window.FEATURE_OPTIONS_PANEL); 2851 } 2852 2853 /** 2854 * Called when a context menu for the {@code view} is about to be shown. 2855 * Unlike {@link #onCreateOptionsMenu(Menu)}, this will be called every 2856 * time the context menu is about to be shown and should be populated for 2857 * the view (or item inside the view for {@link AdapterView} subclasses, 2858 * this can be found in the {@code menuInfo})). 2859 * <p> 2860 * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an 2861 * item has been selected. 2862 * <p> 2863 * It is not safe to hold onto the context menu after this method returns. 2864 * 2865 */ 2866 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 2867 } 2868 2869 /** 2870 * Registers a context menu to be shown for the given view (multiple views 2871 * can show the context menu). This method will set the 2872 * {@link OnCreateContextMenuListener} on the view to this activity, so 2873 * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be 2874 * called when it is time to show the context menu. 2875 * 2876 * @see #unregisterForContextMenu(View) 2877 * @param view The view that should show a context menu. 2878 */ 2879 public void registerForContextMenu(View view) { 2880 view.setOnCreateContextMenuListener(this); 2881 } 2882 2883 /** 2884 * Prevents a context menu to be shown for the given view. This method will remove the 2885 * {@link OnCreateContextMenuListener} on the view. 2886 * 2887 * @see #registerForContextMenu(View) 2888 * @param view The view that should stop showing a context menu. 2889 */ 2890 public void unregisterForContextMenu(View view) { 2891 view.setOnCreateContextMenuListener(null); 2892 } 2893 2894 /** 2895 * Programmatically opens the context menu for a particular {@code view}. 2896 * The {@code view} should have been added via 2897 * {@link #registerForContextMenu(View)}. 2898 * 2899 * @param view The view to show the context menu for. 2900 */ 2901 public void openContextMenu(View view) { 2902 view.showContextMenu(); 2903 } 2904 2905 /** 2906 * Programmatically closes the most recently opened context menu, if showing. 2907 */ 2908 public void closeContextMenu() { 2909 mWindow.closePanel(Window.FEATURE_CONTEXT_MENU); 2910 } 2911 2912 /** 2913 * This hook is called whenever an item in a context menu is selected. The 2914 * default implementation simply returns false to have the normal processing 2915 * happen (calling the item's Runnable or sending a message to its Handler 2916 * as appropriate). You can use this method for any items for which you 2917 * would like to do processing without those other facilities. 2918 * <p> 2919 * Use {@link MenuItem#getMenuInfo()} to get extra information set by the 2920 * View that added this menu item. 2921 * <p> 2922 * Derived classes should call through to the base class for it to perform 2923 * the default menu handling. 2924 * 2925 * @param item The context menu item that was selected. 2926 * @return boolean Return false to allow normal context menu processing to 2927 * proceed, true to consume it here. 2928 */ 2929 public boolean onContextItemSelected(MenuItem item) { 2930 if (mParent != null) { 2931 return mParent.onContextItemSelected(item); 2932 } 2933 return false; 2934 } 2935 2936 /** 2937 * This hook is called whenever the context menu is being closed (either by 2938 * the user canceling the menu with the back/menu button, or when an item is 2939 * selected). 2940 * 2941 * @param menu The context menu that is being closed. 2942 */ 2943 public void onContextMenuClosed(Menu menu) { 2944 if (mParent != null) { 2945 mParent.onContextMenuClosed(menu); 2946 } 2947 } 2948 2949 /** 2950 * @deprecated Old no-arguments version of {@link #onCreateDialog(int, Bundle)}. 2951 */ 2952 @Deprecated 2953 protected Dialog onCreateDialog(int id) { 2954 return null; 2955 } 2956 2957 /** 2958 * Callback for creating dialogs that are managed (saved and restored) for you 2959 * by the activity. The default implementation calls through to 2960 * {@link #onCreateDialog(int)} for compatibility. 2961 * 2962 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 2963 * or later, consider instead using a {@link DialogFragment} instead.</em> 2964 * 2965 * <p>If you use {@link #showDialog(int)}, the activity will call through to 2966 * this method the first time, and hang onto it thereafter. Any dialog 2967 * that is created by this method will automatically be saved and restored 2968 * for you, including whether it is showing. 2969 * 2970 * <p>If you would like the activity to manage saving and restoring dialogs 2971 * for you, you should override this method and handle any ids that are 2972 * passed to {@link #showDialog}. 2973 * 2974 * <p>If you would like an opportunity to prepare your dialog before it is shown, 2975 * override {@link #onPrepareDialog(int, Dialog, Bundle)}. 2976 * 2977 * @param id The id of the dialog. 2978 * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}. 2979 * @return The dialog. If you return null, the dialog will not be created. 2980 * 2981 * @see #onPrepareDialog(int, Dialog, Bundle) 2982 * @see #showDialog(int, Bundle) 2983 * @see #dismissDialog(int) 2984 * @see #removeDialog(int) 2985 * 2986 * @deprecated Use the new {@link DialogFragment} class with 2987 * {@link FragmentManager} instead; this is also 2988 * available on older platforms through the Android compatibility package. 2989 */ 2990 @Deprecated 2991 protected Dialog onCreateDialog(int id, Bundle args) { 2992 return onCreateDialog(id); 2993 } 2994 2995 /** 2996 * @deprecated Old no-arguments version of 2997 * {@link #onPrepareDialog(int, Dialog, Bundle)}. 2998 */ 2999 @Deprecated 3000 protected void onPrepareDialog(int id, Dialog dialog) { 3001 dialog.setOwnerActivity(this); 3002 } 3003 3004 /** 3005 * Provides an opportunity to prepare a managed dialog before it is being 3006 * shown. The default implementation calls through to 3007 * {@link #onPrepareDialog(int, Dialog)} for compatibility. 3008 * 3009 * <p> 3010 * Override this if you need to update a managed dialog based on the state 3011 * of the application each time it is shown. For example, a time picker 3012 * dialog might want to be updated with the current time. You should call 3013 * through to the superclass's implementation. The default implementation 3014 * will set this Activity as the owner activity on the Dialog. 3015 * 3016 * @param id The id of the managed dialog. 3017 * @param dialog The dialog. 3018 * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}. 3019 * @see #onCreateDialog(int, Bundle) 3020 * @see #showDialog(int) 3021 * @see #dismissDialog(int) 3022 * @see #removeDialog(int) 3023 * 3024 * @deprecated Use the new {@link DialogFragment} class with 3025 * {@link FragmentManager} instead; this is also 3026 * available on older platforms through the Android compatibility package. 3027 */ 3028 @Deprecated 3029 protected void onPrepareDialog(int id, Dialog dialog, Bundle args) { 3030 onPrepareDialog(id, dialog); 3031 } 3032 3033 /** 3034 * Simple version of {@link #showDialog(int, Bundle)} that does not 3035 * take any arguments. Simply calls {@link #showDialog(int, Bundle)} 3036 * with null arguments. 3037 * 3038 * @deprecated Use the new {@link DialogFragment} class with 3039 * {@link FragmentManager} instead; this is also 3040 * available on older platforms through the Android compatibility package. 3041 */ 3042 @Deprecated 3043 public final void showDialog(int id) { 3044 showDialog(id, null); 3045 } 3046 3047 /** 3048 * Show a dialog managed by this activity. A call to {@link #onCreateDialog(int, Bundle)} 3049 * will be made with the same id the first time this is called for a given 3050 * id. From thereafter, the dialog will be automatically saved and restored. 3051 * 3052 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 3053 * or later, consider instead using a {@link DialogFragment} instead.</em> 3054 * 3055 * <p>Each time a dialog is shown, {@link #onPrepareDialog(int, Dialog, Bundle)} will 3056 * be made to provide an opportunity to do any timely preparation. 3057 * 3058 * @param id The id of the managed dialog. 3059 * @param args Arguments to pass through to the dialog. These will be saved 3060 * and restored for you. Note that if the dialog is already created, 3061 * {@link #onCreateDialog(int, Bundle)} will not be called with the new 3062 * arguments but {@link #onPrepareDialog(int, Dialog, Bundle)} will be. 3063 * If you need to rebuild the dialog, call {@link #removeDialog(int)} first. 3064 * @return Returns true if the Dialog was created; false is returned if 3065 * it is not created because {@link #onCreateDialog(int, Bundle)} returns false. 3066 * 3067 * @see Dialog 3068 * @see #onCreateDialog(int, Bundle) 3069 * @see #onPrepareDialog(int, Dialog, Bundle) 3070 * @see #dismissDialog(int) 3071 * @see #removeDialog(int) 3072 * 3073 * @deprecated Use the new {@link DialogFragment} class with 3074 * {@link FragmentManager} instead; this is also 3075 * available on older platforms through the Android compatibility package. 3076 */ 3077 @Deprecated 3078 public final boolean showDialog(int id, Bundle args) { 3079 if (mManagedDialogs == null) { 3080 mManagedDialogs = new SparseArray<ManagedDialog>(); 3081 } 3082 ManagedDialog md = mManagedDialogs.get(id); 3083 if (md == null) { 3084 md = new ManagedDialog(); 3085 md.mDialog = createDialog(id, null, args); 3086 if (md.mDialog == null) { 3087 return false; 3088 } 3089 mManagedDialogs.put(id, md); 3090 } 3091 3092 md.mArgs = args; 3093 onPrepareDialog(id, md.mDialog, args); 3094 md.mDialog.show(); 3095 return true; 3096 } 3097 3098 /** 3099 * Dismiss a dialog that was previously shown via {@link #showDialog(int)}. 3100 * 3101 * @param id The id of the managed dialog. 3102 * 3103 * @throws IllegalArgumentException if the id was not previously shown via 3104 * {@link #showDialog(int)}. 3105 * 3106 * @see #onCreateDialog(int, Bundle) 3107 * @see #onPrepareDialog(int, Dialog, Bundle) 3108 * @see #showDialog(int) 3109 * @see #removeDialog(int) 3110 * 3111 * @deprecated Use the new {@link DialogFragment} class with 3112 * {@link FragmentManager} instead; this is also 3113 * available on older platforms through the Android compatibility package. 3114 */ 3115 @Deprecated 3116 public final void dismissDialog(int id) { 3117 if (mManagedDialogs == null) { 3118 throw missingDialog(id); 3119 } 3120 3121 final ManagedDialog md = mManagedDialogs.get(id); 3122 if (md == null) { 3123 throw missingDialog(id); 3124 } 3125 md.mDialog.dismiss(); 3126 } 3127 3128 /** 3129 * Creates an exception to throw if a user passed in a dialog id that is 3130 * unexpected. 3131 */ 3132 private IllegalArgumentException missingDialog(int id) { 3133 return new IllegalArgumentException("no dialog with id " + id + " was ever " 3134 + "shown via Activity#showDialog"); 3135 } 3136 3137 /** 3138 * Removes any internal references to a dialog managed by this Activity. 3139 * If the dialog is showing, it will dismiss it as part of the clean up. 3140 * 3141 * <p>This can be useful if you know that you will never show a dialog again and 3142 * want to avoid the overhead of saving and restoring it in the future. 3143 * 3144 * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, this function 3145 * will not throw an exception if you try to remove an ID that does not 3146 * currently have an associated dialog.</p> 3147 * 3148 * @param id The id of the managed dialog. 3149 * 3150 * @see #onCreateDialog(int, Bundle) 3151 * @see #onPrepareDialog(int, Dialog, Bundle) 3152 * @see #showDialog(int) 3153 * @see #dismissDialog(int) 3154 * 3155 * @deprecated Use the new {@link DialogFragment} class with 3156 * {@link FragmentManager} instead; this is also 3157 * available on older platforms through the Android compatibility package. 3158 */ 3159 @Deprecated 3160 public final void removeDialog(int id) { 3161 if (mManagedDialogs != null) { 3162 final ManagedDialog md = mManagedDialogs.get(id); 3163 if (md != null) { 3164 md.mDialog.dismiss(); 3165 mManagedDialogs.remove(id); 3166 } 3167 } 3168 } 3169 3170 /** 3171 * This hook is called when the user signals the desire to start a search. 3172 * 3173 * <p>You can use this function as a simple way to launch the search UI, in response to a 3174 * menu item, search button, or other widgets within your activity. Unless overidden, 3175 * calling this function is the same as calling 3176 * {@link #startSearch startSearch(null, false, null, false)}, which launches 3177 * search for the current activity as specified in its manifest, see {@link SearchManager}. 3178 * 3179 * <p>You can override this function to force global search, e.g. in response to a dedicated 3180 * search key, or to block search entirely (by simply returning false). 3181 * 3182 * @return Returns {@code true} if search launched, and {@code false} if activity blocks it. 3183 * The default implementation always returns {@code true}. 3184 * 3185 * @see android.app.SearchManager 3186 */ 3187 public boolean onSearchRequested() { 3188 startSearch(null, false, null, false); 3189 return true; 3190 } 3191 3192 /** 3193 * This hook is called to launch the search UI. 3194 * 3195 * <p>It is typically called from onSearchRequested(), either directly from 3196 * Activity.onSearchRequested() or from an overridden version in any given 3197 * Activity. If your goal is simply to activate search, it is preferred to call 3198 * onSearchRequested(), which may have been overriden elsewhere in your Activity. If your goal 3199 * is to inject specific data such as context data, it is preferred to <i>override</i> 3200 * onSearchRequested(), so that any callers to it will benefit from the override. 3201 * 3202 * @param initialQuery Any non-null non-empty string will be inserted as 3203 * pre-entered text in the search query box. 3204 * @param selectInitialQuery If true, the intial query will be preselected, which means that 3205 * any further typing will replace it. This is useful for cases where an entire pre-formed 3206 * query is being inserted. If false, the selection point will be placed at the end of the 3207 * inserted query. This is useful when the inserted query is text that the user entered, 3208 * and the user would expect to be able to keep typing. <i>This parameter is only meaningful 3209 * if initialQuery is a non-empty string.</i> 3210 * @param appSearchData An application can insert application-specific 3211 * context here, in order to improve quality or specificity of its own 3212 * searches. This data will be returned with SEARCH intent(s). Null if 3213 * no extra data is required. 3214 * @param globalSearch If false, this will only launch the search that has been specifically 3215 * defined by the application (which is usually defined as a local search). If no default 3216 * search is defined in the current application or activity, global search will be launched. 3217 * If true, this will always launch a platform-global (e.g. web-based) search instead. 3218 * 3219 * @see android.app.SearchManager 3220 * @see #onSearchRequested 3221 */ 3222 public void startSearch(String initialQuery, boolean selectInitialQuery, 3223 Bundle appSearchData, boolean globalSearch) { 3224 ensureSearchManager(); 3225 mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(), 3226 appSearchData, globalSearch); 3227 } 3228 3229 /** 3230 * Similar to {@link #startSearch}, but actually fires off the search query after invoking 3231 * the search dialog. Made available for testing purposes. 3232 * 3233 * @param query The query to trigger. If empty, the request will be ignored. 3234 * @param appSearchData An application can insert application-specific 3235 * context here, in order to improve quality or specificity of its own 3236 * searches. This data will be returned with SEARCH intent(s). Null if 3237 * no extra data is required. 3238 */ 3239 public void triggerSearch(String query, Bundle appSearchData) { 3240 ensureSearchManager(); 3241 mSearchManager.triggerSearch(query, getComponentName(), appSearchData); 3242 } 3243 3244 /** 3245 * Request that key events come to this activity. Use this if your 3246 * activity has no views with focus, but the activity still wants 3247 * a chance to process key events. 3248 * 3249 * @see android.view.Window#takeKeyEvents 3250 */ 3251 public void takeKeyEvents(boolean get) { 3252 getWindow().takeKeyEvents(get); 3253 } 3254 3255 /** 3256 * Enable extended window features. This is a convenience for calling 3257 * {@link android.view.Window#requestFeature getWindow().requestFeature()}. 3258 * 3259 * @param featureId The desired feature as defined in 3260 * {@link android.view.Window}. 3261 * @return Returns true if the requested feature is supported and now 3262 * enabled. 3263 * 3264 * @see android.view.Window#requestFeature 3265 */ 3266 public final boolean requestWindowFeature(int featureId) { 3267 return getWindow().requestFeature(featureId); 3268 } 3269 3270 /** 3271 * Convenience for calling 3272 * {@link android.view.Window#setFeatureDrawableResource}. 3273 */ 3274 public final void setFeatureDrawableResource(int featureId, int resId) { 3275 getWindow().setFeatureDrawableResource(featureId, resId); 3276 } 3277 3278 /** 3279 * Convenience for calling 3280 * {@link android.view.Window#setFeatureDrawableUri}. 3281 */ 3282 public final void setFeatureDrawableUri(int featureId, Uri uri) { 3283 getWindow().setFeatureDrawableUri(featureId, uri); 3284 } 3285 3286 /** 3287 * Convenience for calling 3288 * {@link android.view.Window#setFeatureDrawable(int, Drawable)}. 3289 */ 3290 public final void setFeatureDrawable(int featureId, Drawable drawable) { 3291 getWindow().setFeatureDrawable(featureId, drawable); 3292 } 3293 3294 /** 3295 * Convenience for calling 3296 * {@link android.view.Window#setFeatureDrawableAlpha}. 3297 */ 3298 public final void setFeatureDrawableAlpha(int featureId, int alpha) { 3299 getWindow().setFeatureDrawableAlpha(featureId, alpha); 3300 } 3301 3302 /** 3303 * Convenience for calling 3304 * {@link android.view.Window#getLayoutInflater}. 3305 */ 3306 public LayoutInflater getLayoutInflater() { 3307 return getWindow().getLayoutInflater(); 3308 } 3309 3310 /** 3311 * Returns a {@link MenuInflater} with this context. 3312 */ 3313 public MenuInflater getMenuInflater() { 3314 // Make sure that action views can get an appropriate theme. 3315 if (mMenuInflater == null) { 3316 initActionBar(); 3317 if (mActionBar != null) { 3318 mMenuInflater = new MenuInflater(mActionBar.getThemedContext(), this); 3319 } else { 3320 mMenuInflater = new MenuInflater(this); 3321 } 3322 } 3323 return mMenuInflater; 3324 } 3325 3326 @Override 3327 protected void onApplyThemeResource(Resources.Theme theme, int resid, 3328 boolean first) { 3329 if (mParent == null) { 3330 super.onApplyThemeResource(theme, resid, first); 3331 } else { 3332 try { 3333 theme.setTo(mParent.getTheme()); 3334 } catch (Exception e) { 3335 // Empty 3336 } 3337 theme.applyStyle(resid, false); 3338 } 3339 } 3340 3341 /** 3342 * Same as calling {@link #startActivityForResult(Intent, int, Bundle)} 3343 * with no options. 3344 * 3345 * @param intent The intent to start. 3346 * @param requestCode If >= 0, this code will be returned in 3347 * onActivityResult() when the activity exits. 3348 * 3349 * @throws android.content.ActivityNotFoundException 3350 * 3351 * @see #startActivity 3352 */ 3353 public void startActivityForResult(Intent intent, int requestCode) { 3354 startActivityForResult(intent, requestCode, null); 3355 } 3356 3357 /** 3358 * Launch an activity for which you would like a result when it finished. 3359 * When this activity exits, your 3360 * onActivityResult() method will be called with the given requestCode. 3361 * Using a negative requestCode is the same as calling 3362 * {@link #startActivity} (the activity is not launched as a sub-activity). 3363 * 3364 * <p>Note that this method should only be used with Intent protocols 3365 * that are defined to return a result. In other protocols (such as 3366 * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may 3367 * not get the result when you expect. For example, if the activity you 3368 * are launching uses the singleTask launch mode, it will not run in your 3369 * task and thus you will immediately receive a cancel result. 3370 * 3371 * <p>As a special case, if you call startActivityForResult() with a requestCode 3372 * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your 3373 * activity, then your window will not be displayed until a result is 3374 * returned back from the started activity. This is to avoid visible 3375 * flickering when redirecting to another activity. 3376 * 3377 * <p>This method throws {@link android.content.ActivityNotFoundException} 3378 * if there was no Activity found to run the given Intent. 3379 * 3380 * @param intent The intent to start. 3381 * @param requestCode If >= 0, this code will be returned in 3382 * onActivityResult() when the activity exits. 3383 * @param options Additional options for how the Activity should be started. 3384 * See {@link android.content.Context#startActivity(Intent, Bundle) 3385 * Context.startActivity(Intent, Bundle)} for more details. 3386 * 3387 * @throws android.content.ActivityNotFoundException 3388 * 3389 * @see #startActivity 3390 */ 3391 public void startActivityForResult(Intent intent, int requestCode, Bundle options) { 3392 if (mParent == null) { 3393 Instrumentation.ActivityResult ar = 3394 mInstrumentation.execStartActivity( 3395 this, mMainThread.getApplicationThread(), mToken, this, 3396 intent, requestCode, options); 3397 if (ar != null) { 3398 mMainThread.sendActivityResult( 3399 mToken, mEmbeddedID, requestCode, ar.getResultCode(), 3400 ar.getResultData()); 3401 } 3402 if (requestCode >= 0) { 3403 // If this start is requesting a result, we can avoid making 3404 // the activity visible until the result is received. Setting 3405 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 3406 // activity hidden during this time, to avoid flickering. 3407 // This can only be done when a result is requested because 3408 // that guarantees we will get information back when the 3409 // activity is finished, no matter what happens to it. 3410 mStartedActivity = true; 3411 } 3412 } else { 3413 if (options != null) { 3414 mParent.startActivityFromChild(this, intent, requestCode, options); 3415 } else { 3416 // Note we want to go through this method for compatibility with 3417 // existing applications that may have overridden it. 3418 mParent.startActivityFromChild(this, intent, requestCode); 3419 } 3420 } 3421 } 3422 3423 /** 3424 * @hide Implement to provide correct calling token. 3425 */ 3426 public void startActivityAsUser(Intent intent, UserHandle user) { 3427 startActivityAsUser(intent, null, user); 3428 } 3429 3430 /** 3431 * @hide Implement to provide correct calling token. 3432 */ 3433 public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) { 3434 if (mParent != null) { 3435 throw new RuntimeException("Called be called from a child"); 3436 } 3437 Instrumentation.ActivityResult ar = 3438 mInstrumentation.execStartActivity( 3439 this, mMainThread.getApplicationThread(), mToken, this, 3440 intent, -1, options, user); 3441 if (ar != null) { 3442 mMainThread.sendActivityResult( 3443 mToken, mEmbeddedID, -1, ar.getResultCode(), 3444 ar.getResultData()); 3445 } 3446 } 3447 3448 /** 3449 * Same as calling {@link #startIntentSenderForResult(IntentSender, int, 3450 * Intent, int, int, int, Bundle)} with no options. 3451 * 3452 * @param intent The IntentSender to launch. 3453 * @param requestCode If >= 0, this code will be returned in 3454 * onActivityResult() when the activity exits. 3455 * @param fillInIntent If non-null, this will be provided as the 3456 * intent parameter to {@link IntentSender#sendIntent}. 3457 * @param flagsMask Intent flags in the original IntentSender that you 3458 * would like to change. 3459 * @param flagsValues Desired values for any bits set in 3460 * <var>flagsMask</var> 3461 * @param extraFlags Always set to 0. 3462 */ 3463 public void startIntentSenderForResult(IntentSender intent, int requestCode, 3464 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 3465 throws IntentSender.SendIntentException { 3466 startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask, 3467 flagsValues, extraFlags, null); 3468 } 3469 3470 /** 3471 * Like {@link #startActivityForResult(Intent, int)}, but allowing you 3472 * to use a IntentSender to describe the activity to be started. If 3473 * the IntentSender is for an activity, that activity will be started 3474 * as if you had called the regular {@link #startActivityForResult(Intent, int)} 3475 * here; otherwise, its associated action will be executed (such as 3476 * sending a broadcast) as if you had called 3477 * {@link IntentSender#sendIntent IntentSender.sendIntent} on it. 3478 * 3479 * @param intent The IntentSender to launch. 3480 * @param requestCode If >= 0, this code will be returned in 3481 * onActivityResult() when the activity exits. 3482 * @param fillInIntent If non-null, this will be provided as the 3483 * intent parameter to {@link IntentSender#sendIntent}. 3484 * @param flagsMask Intent flags in the original IntentSender that you 3485 * would like to change. 3486 * @param flagsValues Desired values for any bits set in 3487 * <var>flagsMask</var> 3488 * @param extraFlags Always set to 0. 3489 * @param options Additional options for how the Activity should be started. 3490 * See {@link android.content.Context#startActivity(Intent, Bundle) 3491 * Context.startActivity(Intent, Bundle)} for more details. If options 3492 * have also been supplied by the IntentSender, options given here will 3493 * override any that conflict with those given by the IntentSender. 3494 */ 3495 public void startIntentSenderForResult(IntentSender intent, int requestCode, 3496 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, 3497 Bundle options) throws IntentSender.SendIntentException { 3498 if (mParent == null) { 3499 startIntentSenderForResultInner(intent, requestCode, fillInIntent, 3500 flagsMask, flagsValues, this, options); 3501 } else if (options != null) { 3502 mParent.startIntentSenderFromChild(this, intent, requestCode, 3503 fillInIntent, flagsMask, flagsValues, extraFlags, options); 3504 } else { 3505 // Note we want to go through this call for compatibility with 3506 // existing applications that may have overridden the method. 3507 mParent.startIntentSenderFromChild(this, intent, requestCode, 3508 fillInIntent, flagsMask, flagsValues, extraFlags); 3509 } 3510 } 3511 3512 private void startIntentSenderForResultInner(IntentSender intent, int requestCode, 3513 Intent fillInIntent, int flagsMask, int flagsValues, Activity activity, 3514 Bundle options) 3515 throws IntentSender.SendIntentException { 3516 try { 3517 String resolvedType = null; 3518 if (fillInIntent != null) { 3519 fillInIntent.migrateExtraStreamToClipData(); 3520 fillInIntent.prepareToLeaveProcess(); 3521 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); 3522 } 3523 int result = ActivityManagerNative.getDefault() 3524 .startActivityIntentSender(mMainThread.getApplicationThread(), intent, 3525 fillInIntent, resolvedType, mToken, activity.mEmbeddedID, 3526 requestCode, flagsMask, flagsValues, options); 3527 if (result == ActivityManager.START_CANCELED) { 3528 throw new IntentSender.SendIntentException(); 3529 } 3530 Instrumentation.checkStartActivityResult(result, null); 3531 } catch (RemoteException e) { 3532 } 3533 if (requestCode >= 0) { 3534 // If this start is requesting a result, we can avoid making 3535 // the activity visible until the result is received. Setting 3536 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 3537 // activity hidden during this time, to avoid flickering. 3538 // This can only be done when a result is requested because 3539 // that guarantees we will get information back when the 3540 // activity is finished, no matter what happens to it. 3541 mStartedActivity = true; 3542 } 3543 } 3544 3545 /** 3546 * Same as {@link #startActivity(Intent, Bundle)} with no options 3547 * specified. 3548 * 3549 * @param intent The intent to start. 3550 * 3551 * @throws android.content.ActivityNotFoundException 3552 * 3553 * @see {@link #startActivity(Intent, Bundle)} 3554 * @see #startActivityForResult 3555 */ 3556 @Override 3557 public void startActivity(Intent intent) { 3558 startActivity(intent, null); 3559 } 3560 3561 /** 3562 * Launch a new activity. You will not receive any information about when 3563 * the activity exits. This implementation overrides the base version, 3564 * providing information about 3565 * the activity performing the launch. Because of this additional 3566 * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not 3567 * required; if not specified, the new activity will be added to the 3568 * task of the caller. 3569 * 3570 * <p>This method throws {@link android.content.ActivityNotFoundException} 3571 * if there was no Activity found to run the given Intent. 3572 * 3573 * @param intent The intent to start. 3574 * @param options Additional options for how the Activity should be started. 3575 * See {@link android.content.Context#startActivity(Intent, Bundle) 3576 * Context.startActivity(Intent, Bundle)} for more details. 3577 * 3578 * @throws android.content.ActivityNotFoundException 3579 * 3580 * @see {@link #startActivity(Intent)} 3581 * @see #startActivityForResult 3582 */ 3583 @Override 3584 public void startActivity(Intent intent, Bundle options) { 3585 if (options != null) { 3586 startActivityForResult(intent, -1, options); 3587 } else { 3588 // Note we want to go through this call for compatibility with 3589 // applications that may have overridden the method. 3590 startActivityForResult(intent, -1); 3591 } 3592 } 3593 3594 /** 3595 * Same as {@link #startActivities(Intent[], Bundle)} with no options 3596 * specified. 3597 * 3598 * @param intents The intents to start. 3599 * 3600 * @throws android.content.ActivityNotFoundException 3601 * 3602 * @see {@link #startActivities(Intent[], Bundle)} 3603 * @see #startActivityForResult 3604 */ 3605 @Override 3606 public void startActivities(Intent[] intents) { 3607 startActivities(intents, null); 3608 } 3609 3610 /** 3611 * Launch a new activity. You will not receive any information about when 3612 * the activity exits. This implementation overrides the base version, 3613 * providing information about 3614 * the activity performing the launch. Because of this additional 3615 * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not 3616 * required; if not specified, the new activity will be added to the 3617 * task of the caller. 3618 * 3619 * <p>This method throws {@link android.content.ActivityNotFoundException} 3620 * if there was no Activity found to run the given Intent. 3621 * 3622 * @param intents The intents to start. 3623 * @param options Additional options for how the Activity should be started. 3624 * See {@link android.content.Context#startActivity(Intent, Bundle) 3625 * Context.startActivity(Intent, Bundle)} for more details. 3626 * 3627 * @throws android.content.ActivityNotFoundException 3628 * 3629 * @see {@link #startActivities(Intent[])} 3630 * @see #startActivityForResult 3631 */ 3632 @Override 3633 public void startActivities(Intent[] intents, Bundle options) { 3634 mInstrumentation.execStartActivities(this, mMainThread.getApplicationThread(), 3635 mToken, this, intents, options); 3636 } 3637 3638 /** 3639 * Same as calling {@link #startIntentSender(IntentSender, Intent, int, int, int, Bundle)} 3640 * with no options. 3641 * 3642 * @param intent The IntentSender to launch. 3643 * @param fillInIntent If non-null, this will be provided as the 3644 * intent parameter to {@link IntentSender#sendIntent}. 3645 * @param flagsMask Intent flags in the original IntentSender that you 3646 * would like to change. 3647 * @param flagsValues Desired values for any bits set in 3648 * <var>flagsMask</var> 3649 * @param extraFlags Always set to 0. 3650 */ 3651 public void startIntentSender(IntentSender intent, 3652 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 3653 throws IntentSender.SendIntentException { 3654 startIntentSender(intent, fillInIntent, flagsMask, flagsValues, 3655 extraFlags, null); 3656 } 3657 3658 /** 3659 * Like {@link #startActivity(Intent, Bundle)}, but taking a IntentSender 3660 * to start; see 3661 * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int, Bundle)} 3662 * for more information. 3663 * 3664 * @param intent The IntentSender to launch. 3665 * @param fillInIntent If non-null, this will be provided as the 3666 * intent parameter to {@link IntentSender#sendIntent}. 3667 * @param flagsMask Intent flags in the original IntentSender that you 3668 * would like to change. 3669 * @param flagsValues Desired values for any bits set in 3670 * <var>flagsMask</var> 3671 * @param extraFlags Always set to 0. 3672 * @param options Additional options for how the Activity should be started. 3673 * See {@link android.content.Context#startActivity(Intent, Bundle) 3674 * Context.startActivity(Intent, Bundle)} for more details. If options 3675 * have also been supplied by the IntentSender, options given here will 3676 * override any that conflict with those given by the IntentSender. 3677 */ 3678 public void startIntentSender(IntentSender intent, 3679 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, 3680 Bundle options) throws IntentSender.SendIntentException { 3681 if (options != null) { 3682 startIntentSenderForResult(intent, -1, fillInIntent, flagsMask, 3683 flagsValues, extraFlags, options); 3684 } else { 3685 // Note we want to go through this call for compatibility with 3686 // applications that may have overridden the method. 3687 startIntentSenderForResult(intent, -1, fillInIntent, flagsMask, 3688 flagsValues, extraFlags); 3689 } 3690 } 3691 3692 /** 3693 * Same as calling {@link #startActivityIfNeeded(Intent, int, Bundle)} 3694 * with no options. 3695 * 3696 * @param intent The intent to start. 3697 * @param requestCode If >= 0, this code will be returned in 3698 * onActivityResult() when the activity exits, as described in 3699 * {@link #startActivityForResult}. 3700 * 3701 * @return If a new activity was launched then true is returned; otherwise 3702 * false is returned and you must handle the Intent yourself. 3703 * 3704 * @see #startActivity 3705 * @see #startActivityForResult 3706 */ 3707 public boolean startActivityIfNeeded(Intent intent, int requestCode) { 3708 return startActivityIfNeeded(intent, requestCode, null); 3709 } 3710 3711 /** 3712 * A special variation to launch an activity only if a new activity 3713 * instance is needed to handle the given Intent. In other words, this is 3714 * just like {@link #startActivityForResult(Intent, int)} except: if you are 3715 * using the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag, or 3716 * singleTask or singleTop 3717 * {@link android.R.styleable#AndroidManifestActivity_launchMode launchMode}, 3718 * and the activity 3719 * that handles <var>intent</var> is the same as your currently running 3720 * activity, then a new instance is not needed. In this case, instead of 3721 * the normal behavior of calling {@link #onNewIntent} this function will 3722 * return and you can handle the Intent yourself. 3723 * 3724 * <p>This function can only be called from a top-level activity; if it is 3725 * called from a child activity, a runtime exception will be thrown. 3726 * 3727 * @param intent The intent to start. 3728 * @param requestCode If >= 0, this code will be returned in 3729 * onActivityResult() when the activity exits, as described in 3730 * {@link #startActivityForResult}. 3731 * @param options Additional options for how the Activity should be started. 3732 * See {@link android.content.Context#startActivity(Intent, Bundle) 3733 * Context.startActivity(Intent, Bundle)} for more details. 3734 * 3735 * @return If a new activity was launched then true is returned; otherwise 3736 * false is returned and you must handle the Intent yourself. 3737 * 3738 * @see #startActivity 3739 * @see #startActivityForResult 3740 */ 3741 public boolean startActivityIfNeeded(Intent intent, int requestCode, Bundle options) { 3742 if (mParent == null) { 3743 int result = ActivityManager.START_RETURN_INTENT_TO_CALLER; 3744 try { 3745 intent.migrateExtraStreamToClipData(); 3746 intent.prepareToLeaveProcess(); 3747 result = ActivityManagerNative.getDefault() 3748 .startActivity(mMainThread.getApplicationThread(), getBasePackageName(), 3749 intent, intent.resolveTypeIfNeeded(getContentResolver()), 3750 mToken, mEmbeddedID, requestCode, 3751 ActivityManager.START_FLAG_ONLY_IF_NEEDED, null, null, 3752 options); 3753 } catch (RemoteException e) { 3754 // Empty 3755 } 3756 3757 Instrumentation.checkStartActivityResult(result, intent); 3758 3759 if (requestCode >= 0) { 3760 // If this start is requesting a result, we can avoid making 3761 // the activity visible until the result is received. Setting 3762 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 3763 // activity hidden during this time, to avoid flickering. 3764 // This can only be done when a result is requested because 3765 // that guarantees we will get information back when the 3766 // activity is finished, no matter what happens to it. 3767 mStartedActivity = true; 3768 } 3769 return result != ActivityManager.START_RETURN_INTENT_TO_CALLER; 3770 } 3771 3772 throw new UnsupportedOperationException( 3773 "startActivityIfNeeded can only be called from a top-level activity"); 3774 } 3775 3776 /** 3777 * Same as calling {@link #startNextMatchingActivity(Intent, Bundle)} with 3778 * no options. 3779 * 3780 * @param intent The intent to dispatch to the next activity. For 3781 * correct behavior, this must be the same as the Intent that started 3782 * your own activity; the only changes you can make are to the extras 3783 * inside of it. 3784 * 3785 * @return Returns a boolean indicating whether there was another Activity 3786 * to start: true if there was a next activity to start, false if there 3787 * wasn't. In general, if true is returned you will then want to call 3788 * finish() on yourself. 3789 */ 3790 public boolean startNextMatchingActivity(Intent intent) { 3791 return startNextMatchingActivity(intent, null); 3792 } 3793 3794 /** 3795 * Special version of starting an activity, for use when you are replacing 3796 * other activity components. You can use this to hand the Intent off 3797 * to the next Activity that can handle it. You typically call this in 3798 * {@link #onCreate} with the Intent returned by {@link #getIntent}. 3799 * 3800 * @param intent The intent to dispatch to the next activity. For 3801 * correct behavior, this must be the same as the Intent that started 3802 * your own activity; the only changes you can make are to the extras 3803 * inside of it. 3804 * @param options Additional options for how the Activity should be started. 3805 * See {@link android.content.Context#startActivity(Intent, Bundle) 3806 * Context.startActivity(Intent, Bundle)} for more details. 3807 * 3808 * @return Returns a boolean indicating whether there was another Activity 3809 * to start: true if there was a next activity to start, false if there 3810 * wasn't. In general, if true is returned you will then want to call 3811 * finish() on yourself. 3812 */ 3813 public boolean startNextMatchingActivity(Intent intent, Bundle options) { 3814 if (mParent == null) { 3815 try { 3816 intent.migrateExtraStreamToClipData(); 3817 intent.prepareToLeaveProcess(); 3818 return ActivityManagerNative.getDefault() 3819 .startNextMatchingActivity(mToken, intent, options); 3820 } catch (RemoteException e) { 3821 // Empty 3822 } 3823 return false; 3824 } 3825 3826 throw new UnsupportedOperationException( 3827 "startNextMatchingActivity can only be called from a top-level activity"); 3828 } 3829 3830 /** 3831 * Same as calling {@link #startActivityFromChild(Activity, Intent, int, Bundle)} 3832 * with no options. 3833 * 3834 * @param child The activity making the call. 3835 * @param intent The intent to start. 3836 * @param requestCode Reply request code. < 0 if reply is not requested. 3837 * 3838 * @throws android.content.ActivityNotFoundException 3839 * 3840 * @see #startActivity 3841 * @see #startActivityForResult 3842 */ 3843 public void startActivityFromChild(Activity child, Intent intent, 3844 int requestCode) { 3845 startActivityFromChild(child, intent, requestCode, null); 3846 } 3847 3848 /** 3849 * This is called when a child activity of this one calls its 3850 * {@link #startActivity} or {@link #startActivityForResult} method. 3851 * 3852 * <p>This method throws {@link android.content.ActivityNotFoundException} 3853 * if there was no Activity found to run the given Intent. 3854 * 3855 * @param child The activity making the call. 3856 * @param intent The intent to start. 3857 * @param requestCode Reply request code. < 0 if reply is not requested. 3858 * @param options Additional options for how the Activity should be started. 3859 * See {@link android.content.Context#startActivity(Intent, Bundle) 3860 * Context.startActivity(Intent, Bundle)} for more details. 3861 * 3862 * @throws android.content.ActivityNotFoundException 3863 * 3864 * @see #startActivity 3865 * @see #startActivityForResult 3866 */ 3867 public void startActivityFromChild(Activity child, Intent intent, 3868 int requestCode, Bundle options) { 3869 Instrumentation.ActivityResult ar = 3870 mInstrumentation.execStartActivity( 3871 this, mMainThread.getApplicationThread(), mToken, child, 3872 intent, requestCode, options); 3873 if (ar != null) { 3874 mMainThread.sendActivityResult( 3875 mToken, child.mEmbeddedID, requestCode, 3876 ar.getResultCode(), ar.getResultData()); 3877 } 3878 } 3879 3880 /** 3881 * Same as calling {@link #startActivityFromFragment(Fragment, Intent, int, Bundle)} 3882 * with no options. 3883 * 3884 * @param fragment The fragment making the call. 3885 * @param intent The intent to start. 3886 * @param requestCode Reply request code. < 0 if reply is not requested. 3887 * 3888 * @throws android.content.ActivityNotFoundException 3889 * 3890 * @see Fragment#startActivity 3891 * @see Fragment#startActivityForResult 3892 */ 3893 public void startActivityFromFragment(Fragment fragment, Intent intent, 3894 int requestCode) { 3895 startActivityFromFragment(fragment, intent, requestCode, null); 3896 } 3897 3898 /** 3899 * This is called when a Fragment in this activity calls its 3900 * {@link Fragment#startActivity} or {@link Fragment#startActivityForResult} 3901 * method. 3902 * 3903 * <p>This method throws {@link android.content.ActivityNotFoundException} 3904 * if there was no Activity found to run the given Intent. 3905 * 3906 * @param fragment The fragment making the call. 3907 * @param intent The intent to start. 3908 * @param requestCode Reply request code. < 0 if reply is not requested. 3909 * @param options Additional options for how the Activity should be started. 3910 * See {@link android.content.Context#startActivity(Intent, Bundle) 3911 * Context.startActivity(Intent, Bundle)} for more details. 3912 * 3913 * @throws android.content.ActivityNotFoundException 3914 * 3915 * @see Fragment#startActivity 3916 * @see Fragment#startActivityForResult 3917 */ 3918 public void startActivityFromFragment(Fragment fragment, Intent intent, 3919 int requestCode, Bundle options) { 3920 Instrumentation.ActivityResult ar = 3921 mInstrumentation.execStartActivity( 3922 this, mMainThread.getApplicationThread(), mToken, fragment, 3923 intent, requestCode, options); 3924 if (ar != null) { 3925 mMainThread.sendActivityResult( 3926 mToken, fragment.mWho, requestCode, 3927 ar.getResultCode(), ar.getResultData()); 3928 } 3929 } 3930 3931 /** 3932 * Same as calling {@link #startIntentSenderFromChild(Activity, IntentSender, 3933 * int, Intent, int, int, int, Bundle)} with no options. 3934 */ 3935 public void startIntentSenderFromChild(Activity child, IntentSender intent, 3936 int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, 3937 int extraFlags) 3938 throws IntentSender.SendIntentException { 3939 startIntentSenderFromChild(child, intent, requestCode, fillInIntent, 3940 flagsMask, flagsValues, extraFlags, null); 3941 } 3942 3943 /** 3944 * Like {@link #startActivityFromChild(Activity, Intent, int)}, but 3945 * taking a IntentSender; see 3946 * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int)} 3947 * for more information. 3948 */ 3949 public void startIntentSenderFromChild(Activity child, IntentSender intent, 3950 int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, 3951 int extraFlags, Bundle options) 3952 throws IntentSender.SendIntentException { 3953 startIntentSenderForResultInner(intent, requestCode, fillInIntent, 3954 flagsMask, flagsValues, child, options); 3955 } 3956 3957 /** 3958 * Call immediately after one of the flavors of {@link #startActivity(Intent)} 3959 * or {@link #finish} to specify an explicit transition animation to 3960 * perform next. 3961 * 3962 * <p>As of {@link android.os.Build.VERSION_CODES#JELLY_BEAN} an alternative 3963 * to using this with starting activities is to supply the desired animation 3964 * information through a {@link ActivityOptions} bundle to 3965 * {@link #startActivity(Intent, Bundle) or a related function. This allows 3966 * you to specify a custom animation even when starting an activity from 3967 * outside the context of the current top activity. 3968 * 3969 * @param enterAnim A resource ID of the animation resource to use for 3970 * the incoming activity. Use 0 for no animation. 3971 * @param exitAnim A resource ID of the animation resource to use for 3972 * the outgoing activity. Use 0 for no animation. 3973 */ 3974 public void overridePendingTransition(int enterAnim, int exitAnim) { 3975 try { 3976 ActivityManagerNative.getDefault().overridePendingTransition( 3977 mToken, getPackageName(), enterAnim, exitAnim); 3978 } catch (RemoteException e) { 3979 } 3980 } 3981 3982 /** 3983 * Call this to set the result that your activity will return to its 3984 * caller. 3985 * 3986 * @param resultCode The result code to propagate back to the originating 3987 * activity, often RESULT_CANCELED or RESULT_OK 3988 * 3989 * @see #RESULT_CANCELED 3990 * @see #RESULT_OK 3991 * @see #RESULT_FIRST_USER 3992 * @see #setResult(int, Intent) 3993 */ 3994 public final void setResult(int resultCode) { 3995 synchronized (this) { 3996 mResultCode = resultCode; 3997 mResultData = null; 3998 } 3999 } 4000 4001 /** 4002 * Call this to set the result that your activity will return to its 4003 * caller. 4004 * 4005 * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, the Intent 4006 * you supply here can have {@link Intent#FLAG_GRANT_READ_URI_PERMISSION 4007 * Intent.FLAG_GRANT_READ_URI_PERMISSION} and/or {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION 4008 * Intent.FLAG_GRANT_WRITE_URI_PERMISSION} set. This will grant the 4009 * Activity receiving the result access to the specific URIs in the Intent. 4010 * Access will remain until the Activity has finished (it will remain across the hosting 4011 * process being killed and other temporary destruction) and will be added 4012 * to any existing set of URI permissions it already holds. 4013 * 4014 * @param resultCode The result code to propagate back to the originating 4015 * activity, often RESULT_CANCELED or RESULT_OK 4016 * @param data The data to propagate back to the originating activity. 4017 * 4018 * @see #RESULT_CANCELED 4019 * @see #RESULT_OK 4020 * @see #RESULT_FIRST_USER 4021 * @see #setResult(int) 4022 */ 4023 public final void setResult(int resultCode, Intent data) { 4024 synchronized (this) { 4025 mResultCode = resultCode; 4026 mResultData = data; 4027 } 4028 } 4029 4030 /** 4031 * Return the name of the package that invoked this activity. This is who 4032 * the data in {@link #setResult setResult()} will be sent to. You can 4033 * use this information to validate that the recipient is allowed to 4034 * receive the data. 4035 * 4036 * <p class="note">Note: if the calling activity is not expecting a result (that is it 4037 * did not use the {@link #startActivityForResult} 4038 * form that includes a request code), then the calling package will be 4039 * null.</p> 4040 * 4041 * <p class="note">Note: prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 4042 * the result from this method was unstable. If the process hosting the calling 4043 * package was no longer running, it would return null instead of the proper package 4044 * name. You can use {@link #getCallingActivity()} and retrieve the package name 4045 * from that instead.</p> 4046 * 4047 * @return The package of the activity that will receive your 4048 * reply, or null if none. 4049 */ 4050 public String getCallingPackage() { 4051 try { 4052 return ActivityManagerNative.getDefault().getCallingPackage(mToken); 4053 } catch (RemoteException e) { 4054 return null; 4055 } 4056 } 4057 4058 /** 4059 * Return the name of the activity that invoked this activity. This is 4060 * who the data in {@link #setResult setResult()} will be sent to. You 4061 * can use this information to validate that the recipient is allowed to 4062 * receive the data. 4063 * 4064 * <p class="note">Note: if the calling activity is not expecting a result (that is it 4065 * did not use the {@link #startActivityForResult} 4066 * form that includes a request code), then the calling package will be 4067 * null. 4068 * 4069 * @return The ComponentName of the activity that will receive your 4070 * reply, or null if none. 4071 */ 4072 public ComponentName getCallingActivity() { 4073 try { 4074 return ActivityManagerNative.getDefault().getCallingActivity(mToken); 4075 } catch (RemoteException e) { 4076 return null; 4077 } 4078 } 4079 4080 /** 4081 * Control whether this activity's main window is visible. This is intended 4082 * only for the special case of an activity that is not going to show a 4083 * UI itself, but can't just finish prior to onResume() because it needs 4084 * to wait for a service binding or such. Setting this to false allows 4085 * you to prevent your UI from being shown during that time. 4086 * 4087 * <p>The default value for this is taken from the 4088 * {@link android.R.attr#windowNoDisplay} attribute of the activity's theme. 4089 */ 4090 public void setVisible(boolean visible) { 4091 if (mVisibleFromClient != visible) { 4092 mVisibleFromClient = visible; 4093 if (mVisibleFromServer) { 4094 if (visible) makeVisible(); 4095 else mDecor.setVisibility(View.INVISIBLE); 4096 } 4097 } 4098 } 4099 4100 void makeVisible() { 4101 if (!mWindowAdded) { 4102 ViewManager wm = getWindowManager(); 4103 wm.addView(mDecor, getWindow().getAttributes()); 4104 mWindowAdded = true; 4105 } 4106 mDecor.setVisibility(View.VISIBLE); 4107 } 4108 4109 /** 4110 * Check to see whether this activity is in the process of finishing, 4111 * either because you called {@link #finish} on it or someone else 4112 * has requested that it finished. This is often used in 4113 * {@link #onPause} to determine whether the activity is simply pausing or 4114 * completely finishing. 4115 * 4116 * @return If the activity is finishing, returns true; else returns false. 4117 * 4118 * @see #finish 4119 */ 4120 public boolean isFinishing() { 4121 return mFinished; 4122 } 4123 4124 /** 4125 * Returns true if the final {@link #onDestroy()} call has been made 4126 * on the Activity, so this instance is now dead. 4127 */ 4128 public boolean isDestroyed() { 4129 return mDestroyed; 4130 } 4131 4132 /** 4133 * Check to see whether this activity is in the process of being destroyed in order to be 4134 * recreated with a new configuration. This is often used in 4135 * {@link #onStop} to determine whether the state needs to be cleaned up or will be passed 4136 * on to the next instance of the activity via {@link #onRetainNonConfigurationInstance()}. 4137 * 4138 * @return If the activity is being torn down in order to be recreated with a new configuration, 4139 * returns true; else returns false. 4140 */ 4141 public boolean isChangingConfigurations() { 4142 return mChangingConfigurations; 4143 } 4144 4145 /** 4146 * Cause this Activity to be recreated with a new instance. This results 4147 * in essentially the same flow as when the Activity is created due to 4148 * a configuration change -- the current instance will go through its 4149 * lifecycle to {@link #onDestroy} and a new instance then created after it. 4150 */ 4151 public void recreate() { 4152 if (mParent != null) { 4153 throw new IllegalStateException("Can only be called on top-level activity"); 4154 } 4155 if (Looper.myLooper() != mMainThread.getLooper()) { 4156 throw new IllegalStateException("Must be called from main thread"); 4157 } 4158 mMainThread.requestRelaunchActivity(mToken, null, null, 0, false, null, false); 4159 } 4160 4161 /** 4162 * Call this when your activity is done and should be closed. The 4163 * ActivityResult is propagated back to whoever launched you via 4164 * onActivityResult(). 4165 */ 4166 public void finish() { 4167 if (mParent == null) { 4168 int resultCode; 4169 Intent resultData; 4170 synchronized (this) { 4171 resultCode = mResultCode; 4172 resultData = mResultData; 4173 } 4174 if (false) Log.v(TAG, "Finishing self: token=" + mToken); 4175 try { 4176 if (resultData != null) { 4177 resultData.prepareToLeaveProcess(); 4178 } 4179 if (ActivityManagerNative.getDefault() 4180 .finishActivity(mToken, resultCode, resultData)) { 4181 mFinished = true; 4182 } 4183 } catch (RemoteException e) { 4184 // Empty 4185 } 4186 } else { 4187 mParent.finishFromChild(this); 4188 } 4189 } 4190 4191 /** 4192 * Finish this activity as well as all activities immediately below it 4193 * in the current task that have the same affinity. This is typically 4194 * used when an application can be launched on to another task (such as 4195 * from an ACTION_VIEW of a content type it understands) and the user 4196 * has used the up navigation to switch out of the current task and in 4197 * to its own task. In this case, if the user has navigated down into 4198 * any other activities of the second application, all of those should 4199 * be removed from the original task as part of the task switch. 4200 * 4201 * <p>Note that this finish does <em>not</em> allow you to deliver results 4202 * to the previous activity, and an exception will be thrown if you are trying 4203 * to do so.</p> 4204 */ 4205 public void finishAffinity() { 4206 if (mParent != null) { 4207 throw new IllegalStateException("Can not be called from an embedded activity"); 4208 } 4209 if (mResultCode != RESULT_CANCELED || mResultData != null) { 4210 throw new IllegalStateException("Can not be called to deliver a result"); 4211 } 4212 try { 4213 if (ActivityManagerNative.getDefault().finishActivityAffinity(mToken)) { 4214 mFinished = true; 4215 } 4216 } catch (RemoteException e) { 4217 // Empty 4218 } 4219 } 4220 4221 /** 4222 * This is called when a child activity of this one calls its 4223 * {@link #finish} method. The default implementation simply calls 4224 * finish() on this activity (the parent), finishing the entire group. 4225 * 4226 * @param child The activity making the call. 4227 * 4228 * @see #finish 4229 */ 4230 public void finishFromChild(Activity child) { 4231 finish(); 4232 } 4233 4234 /** 4235 * Force finish another activity that you had previously started with 4236 * {@link #startActivityForResult}. 4237 * 4238 * @param requestCode The request code of the activity that you had 4239 * given to startActivityForResult(). If there are multiple 4240 * activities started with this request code, they 4241 * will all be finished. 4242 */ 4243 public void finishActivity(int requestCode) { 4244 if (mParent == null) { 4245 try { 4246 ActivityManagerNative.getDefault() 4247 .finishSubActivity(mToken, mEmbeddedID, requestCode); 4248 } catch (RemoteException e) { 4249 // Empty 4250 } 4251 } else { 4252 mParent.finishActivityFromChild(this, requestCode); 4253 } 4254 } 4255 4256 /** 4257 * This is called when a child activity of this one calls its 4258 * finishActivity(). 4259 * 4260 * @param child The activity making the call. 4261 * @param requestCode Request code that had been used to start the 4262 * activity. 4263 */ 4264 public void finishActivityFromChild(Activity child, int requestCode) { 4265 try { 4266 ActivityManagerNative.getDefault() 4267 .finishSubActivity(mToken, child.mEmbeddedID, requestCode); 4268 } catch (RemoteException e) { 4269 // Empty 4270 } 4271 } 4272 4273 /** 4274 * Called when an activity you launched exits, giving you the requestCode 4275 * you started it with, the resultCode it returned, and any additional 4276 * data from it. The <var>resultCode</var> will be 4277 * {@link #RESULT_CANCELED} if the activity explicitly returned that, 4278 * didn't return any result, or crashed during its operation. 4279 * 4280 * <p>You will receive this call immediately before onResume() when your 4281 * activity is re-starting. 4282 * 4283 * @param requestCode The integer request code originally supplied to 4284 * startActivityForResult(), allowing you to identify who this 4285 * result came from. 4286 * @param resultCode The integer result code returned by the child activity 4287 * through its setResult(). 4288 * @param data An Intent, which can return result data to the caller 4289 * (various data can be attached to Intent "extras"). 4290 * 4291 * @see #startActivityForResult 4292 * @see #createPendingResult 4293 * @see #setResult(int) 4294 */ 4295 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 4296 } 4297 4298 /** 4299 * Create a new PendingIntent object which you can hand to others 4300 * for them to use to send result data back to your 4301 * {@link #onActivityResult} callback. The created object will be either 4302 * one-shot (becoming invalid after a result is sent back) or multiple 4303 * (allowing any number of results to be sent through it). 4304 * 4305 * @param requestCode Private request code for the sender that will be 4306 * associated with the result data when it is returned. The sender can not 4307 * modify this value, allowing you to identify incoming results. 4308 * @param data Default data to supply in the result, which may be modified 4309 * by the sender. 4310 * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT PendingIntent.FLAG_ONE_SHOT}, 4311 * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE}, 4312 * {@link PendingIntent#FLAG_CANCEL_CURRENT PendingIntent.FLAG_CANCEL_CURRENT}, 4313 * {@link PendingIntent#FLAG_UPDATE_CURRENT PendingIntent.FLAG_UPDATE_CURRENT}, 4314 * or any of the flags as supported by 4315 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 4316 * of the intent that can be supplied when the actual send happens. 4317 * 4318 * @return Returns an existing or new PendingIntent matching the given 4319 * parameters. May return null only if 4320 * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE} has been 4321 * supplied. 4322 * 4323 * @see PendingIntent 4324 */ 4325 public PendingIntent createPendingResult(int requestCode, Intent data, 4326 int flags) { 4327 String packageName = getPackageName(); 4328 try { 4329 data.prepareToLeaveProcess(); 4330 IIntentSender target = 4331 ActivityManagerNative.getDefault().getIntentSender( 4332 ActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName, 4333 mParent == null ? mToken : mParent.mToken, 4334 mEmbeddedID, requestCode, new Intent[] { data }, null, flags, null, 4335 UserHandle.myUserId()); 4336 return target != null ? new PendingIntent(target) : null; 4337 } catch (RemoteException e) { 4338 // Empty 4339 } 4340 return null; 4341 } 4342 4343 /** 4344 * Change the desired orientation of this activity. If the activity 4345 * is currently in the foreground or otherwise impacting the screen 4346 * orientation, the screen will immediately be changed (possibly causing 4347 * the activity to be restarted). Otherwise, this will be used the next 4348 * time the activity is visible. 4349 * 4350 * @param requestedOrientation An orientation constant as used in 4351 * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}. 4352 */ 4353 public void setRequestedOrientation(int requestedOrientation) { 4354 if (mParent == null) { 4355 try { 4356 ActivityManagerNative.getDefault().setRequestedOrientation( 4357 mToken, requestedOrientation); 4358 } catch (RemoteException e) { 4359 // Empty 4360 } 4361 } else { 4362 mParent.setRequestedOrientation(requestedOrientation); 4363 } 4364 } 4365 4366 /** 4367 * Return the current requested orientation of the activity. This will 4368 * either be the orientation requested in its component's manifest, or 4369 * the last requested orientation given to 4370 * {@link #setRequestedOrientation(int)}. 4371 * 4372 * @return Returns an orientation constant as used in 4373 * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}. 4374 */ 4375 public int getRequestedOrientation() { 4376 if (mParent == null) { 4377 try { 4378 return ActivityManagerNative.getDefault() 4379 .getRequestedOrientation(mToken); 4380 } catch (RemoteException e) { 4381 // Empty 4382 } 4383 } else { 4384 return mParent.getRequestedOrientation(); 4385 } 4386 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4387 } 4388 4389 /** 4390 * Return the identifier of the task this activity is in. This identifier 4391 * will remain the same for the lifetime of the activity. 4392 * 4393 * @return Task identifier, an opaque integer. 4394 */ 4395 public int getTaskId() { 4396 try { 4397 return ActivityManagerNative.getDefault() 4398 .getTaskForActivity(mToken, false); 4399 } catch (RemoteException e) { 4400 return -1; 4401 } 4402 } 4403 4404 /** 4405 * Return whether this activity is the root of a task. The root is the 4406 * first activity in a task. 4407 * 4408 * @return True if this is the root activity, else false. 4409 */ 4410 public boolean isTaskRoot() { 4411 try { 4412 return ActivityManagerNative.getDefault() 4413 .getTaskForActivity(mToken, true) >= 0; 4414 } catch (RemoteException e) { 4415 return false; 4416 } 4417 } 4418 4419 /** 4420 * Move the task containing this activity to the back of the activity 4421 * stack. The activity's order within the task is unchanged. 4422 * 4423 * @param nonRoot If false then this only works if the activity is the root 4424 * of a task; if true it will work for any activity in 4425 * a task. 4426 * 4427 * @return If the task was moved (or it was already at the 4428 * back) true is returned, else false. 4429 */ 4430 public boolean moveTaskToBack(boolean nonRoot) { 4431 try { 4432 return ActivityManagerNative.getDefault().moveActivityTaskToBack( 4433 mToken, nonRoot); 4434 } catch (RemoteException e) { 4435 // Empty 4436 } 4437 return false; 4438 } 4439 4440 /** 4441 * Returns class name for this activity with the package prefix removed. 4442 * This is the default name used to read and write settings. 4443 * 4444 * @return The local class name. 4445 */ 4446 public String getLocalClassName() { 4447 final String pkg = getPackageName(); 4448 final String cls = mComponent.getClassName(); 4449 int packageLen = pkg.length(); 4450 if (!cls.startsWith(pkg) || cls.length() <= packageLen 4451 || cls.charAt(packageLen) != '.') { 4452 return cls; 4453 } 4454 return cls.substring(packageLen+1); 4455 } 4456 4457 /** 4458 * Returns complete component name of this activity. 4459 * 4460 * @return Returns the complete component name for this activity 4461 */ 4462 public ComponentName getComponentName() 4463 { 4464 return mComponent; 4465 } 4466 4467 /** 4468 * Retrieve a {@link SharedPreferences} object for accessing preferences 4469 * that are private to this activity. This simply calls the underlying 4470 * {@link #getSharedPreferences(String, int)} method by passing in this activity's 4471 * class name as the preferences name. 4472 * 4473 * @param mode Operating mode. Use {@link #MODE_PRIVATE} for the default 4474 * operation, {@link #MODE_WORLD_READABLE} and 4475 * {@link #MODE_WORLD_WRITEABLE} to control permissions. 4476 * 4477 * @return Returns the single SharedPreferences instance that can be used 4478 * to retrieve and modify the preference values. 4479 */ 4480 public SharedPreferences getPreferences(int mode) { 4481 return getSharedPreferences(getLocalClassName(), mode); 4482 } 4483 4484 private void ensureSearchManager() { 4485 if (mSearchManager != null) { 4486 return; 4487 } 4488 4489 mSearchManager = new SearchManager(this, null); 4490 } 4491 4492 @Override 4493 public Object getSystemService(String name) { 4494 if (getBaseContext() == null) { 4495 throw new IllegalStateException( 4496 "System services not available to Activities before onCreate()"); 4497 } 4498 4499 if (WINDOW_SERVICE.equals(name)) { 4500 return mWindowManager; 4501 } else if (SEARCH_SERVICE.equals(name)) { 4502 ensureSearchManager(); 4503 return mSearchManager; 4504 } 4505 return super.getSystemService(name); 4506 } 4507 4508 /** 4509 * Change the title associated with this activity. If this is a 4510 * top-level activity, the title for its window will change. If it 4511 * is an embedded activity, the parent can do whatever it wants 4512 * with it. 4513 */ 4514 public void setTitle(CharSequence title) { 4515 mTitle = title; 4516 onTitleChanged(title, mTitleColor); 4517 4518 if (mParent != null) { 4519 mParent.onChildTitleChanged(this, title); 4520 } 4521 } 4522 4523 /** 4524 * Change the title associated with this activity. If this is a 4525 * top-level activity, the title for its window will change. If it 4526 * is an embedded activity, the parent can do whatever it wants 4527 * with it. 4528 */ 4529 public void setTitle(int titleId) { 4530 setTitle(getText(titleId)); 4531 } 4532 4533 public void setTitleColor(int textColor) { 4534 mTitleColor = textColor; 4535 onTitleChanged(mTitle, textColor); 4536 } 4537 4538 public final CharSequence getTitle() { 4539 return mTitle; 4540 } 4541 4542 public final int getTitleColor() { 4543 return mTitleColor; 4544 } 4545 4546 protected void onTitleChanged(CharSequence title, int color) { 4547 if (mTitleReady) { 4548 final Window win = getWindow(); 4549 if (win != null) { 4550 win.setTitle(title); 4551 if (color != 0) { 4552 win.setTitleColor(color); 4553 } 4554 } 4555 } 4556 } 4557 4558 protected void onChildTitleChanged(Activity childActivity, CharSequence title) { 4559 } 4560 4561 /** 4562 * Sets the visibility of the progress bar in the title. 4563 * <p> 4564 * In order for the progress bar to be shown, the feature must be requested 4565 * via {@link #requestWindowFeature(int)}. 4566 * 4567 * @param visible Whether to show the progress bars in the title. 4568 */ 4569 public final void setProgressBarVisibility(boolean visible) { 4570 getWindow().setFeatureInt(Window.FEATURE_PROGRESS, visible ? Window.PROGRESS_VISIBILITY_ON : 4571 Window.PROGRESS_VISIBILITY_OFF); 4572 } 4573 4574 /** 4575 * Sets the visibility of the indeterminate progress bar in the title. 4576 * <p> 4577 * In order for the progress bar to be shown, the feature must be requested 4578 * via {@link #requestWindowFeature(int)}. 4579 * 4580 * @param visible Whether to show the progress bars in the title. 4581 */ 4582 public final void setProgressBarIndeterminateVisibility(boolean visible) { 4583 getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, 4584 visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF); 4585 } 4586 4587 /** 4588 * Sets whether the horizontal progress bar in the title should be indeterminate (the circular 4589 * is always indeterminate). 4590 * <p> 4591 * In order for the progress bar to be shown, the feature must be requested 4592 * via {@link #requestWindowFeature(int)}. 4593 * 4594 * @param indeterminate Whether the horizontal progress bar should be indeterminate. 4595 */ 4596 public final void setProgressBarIndeterminate(boolean indeterminate) { 4597 getWindow().setFeatureInt(Window.FEATURE_PROGRESS, 4598 indeterminate ? Window.PROGRESS_INDETERMINATE_ON : Window.PROGRESS_INDETERMINATE_OFF); 4599 } 4600 4601 /** 4602 * Sets the progress for the progress bars in the title. 4603 * <p> 4604 * In order for the progress bar to be shown, the feature must be requested 4605 * via {@link #requestWindowFeature(int)}. 4606 * 4607 * @param progress The progress for the progress bar. Valid ranges are from 4608 * 0 to 10000 (both inclusive). If 10000 is given, the progress 4609 * bar will be completely filled and will fade out. 4610 */ 4611 public final void setProgress(int progress) { 4612 getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START); 4613 } 4614 4615 /** 4616 * Sets the secondary progress for the progress bar in the title. This 4617 * progress is drawn between the primary progress (set via 4618 * {@link #setProgress(int)} and the background. It can be ideal for media 4619 * scenarios such as showing the buffering progress while the default 4620 * progress shows the play progress. 4621 * <p> 4622 * In order for the progress bar to be shown, the feature must be requested 4623 * via {@link #requestWindowFeature(int)}. 4624 * 4625 * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from 4626 * 0 to 10000 (both inclusive). 4627 */ 4628 public final void setSecondaryProgress(int secondaryProgress) { 4629 getWindow().setFeatureInt(Window.FEATURE_PROGRESS, 4630 secondaryProgress + Window.PROGRESS_SECONDARY_START); 4631 } 4632 4633 /** 4634 * Suggests an audio stream whose volume should be changed by the hardware 4635 * volume controls. 4636 * <p> 4637 * The suggested audio stream will be tied to the window of this Activity. 4638 * If the Activity is switched, the stream set here is no longer the 4639 * suggested stream. The client does not need to save and restore the old 4640 * suggested stream value in onPause and onResume. 4641 * 4642 * @param streamType The type of the audio stream whose volume should be 4643 * changed by the hardware volume controls. It is not guaranteed that 4644 * the hardware volume controls will always change this stream's 4645 * volume (for example, if a call is in progress, its stream's volume 4646 * may be changed instead). To reset back to the default, use 4647 * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}. 4648 */ 4649 public final void setVolumeControlStream(int streamType) { 4650 getWindow().setVolumeControlStream(streamType); 4651 } 4652 4653 /** 4654 * Gets the suggested audio stream whose volume should be changed by the 4655 * harwdare volume controls. 4656 * 4657 * @return The suggested audio stream type whose volume should be changed by 4658 * the hardware volume controls. 4659 * @see #setVolumeControlStream(int) 4660 */ 4661 public final int getVolumeControlStream() { 4662 return getWindow().getVolumeControlStream(); 4663 } 4664 4665 /** 4666 * Runs the specified action on the UI thread. If the current thread is the UI 4667 * thread, then the action is executed immediately. If the current thread is 4668 * not the UI thread, the action is posted to the event queue of the UI thread. 4669 * 4670 * @param action the action to run on the UI thread 4671 */ 4672 public final void runOnUiThread(Runnable action) { 4673 if (Thread.currentThread() != mUiThread) { 4674 mHandler.post(action); 4675 } else { 4676 action.run(); 4677 } 4678 } 4679 4680 /** 4681 * Standard implementation of 4682 * {@link android.view.LayoutInflater.Factory#onCreateView} used when 4683 * inflating with the LayoutInflater returned by {@link #getSystemService}. 4684 * This implementation does nothing and is for 4685 * pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} apps. Newer apps 4686 * should use {@link #onCreateView(View, String, Context, AttributeSet)}. 4687 * 4688 * @see android.view.LayoutInflater#createView 4689 * @see android.view.Window#getLayoutInflater 4690 */ 4691 public View onCreateView(String name, Context context, AttributeSet attrs) { 4692 return null; 4693 } 4694 4695 /** 4696 * Standard implementation of 4697 * {@link android.view.LayoutInflater.Factory2#onCreateView(View, String, Context, AttributeSet)} 4698 * used when inflating with the LayoutInflater returned by {@link #getSystemService}. 4699 * This implementation handles <fragment> tags to embed fragments inside 4700 * of the activity. 4701 * 4702 * @see android.view.LayoutInflater#createView 4703 * @see android.view.Window#getLayoutInflater 4704 */ 4705 public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { 4706 if (!"fragment".equals(name)) { 4707 return onCreateView(name, context, attrs); 4708 } 4709 4710 String fname = attrs.getAttributeValue(null, "class"); 4711 TypedArray a = 4712 context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Fragment); 4713 if (fname == null) { 4714 fname = a.getString(com.android.internal.R.styleable.Fragment_name); 4715 } 4716 int id = a.getResourceId(com.android.internal.R.styleable.Fragment_id, View.NO_ID); 4717 String tag = a.getString(com.android.internal.R.styleable.Fragment_tag); 4718 a.recycle(); 4719 4720 int containerId = parent != null ? parent.getId() : 0; 4721 if (containerId == View.NO_ID && id == View.NO_ID && tag == null) { 4722 throw new IllegalArgumentException(attrs.getPositionDescription() 4723 + ": Must specify unique android:id, android:tag, or have a parent with an id for " + fname); 4724 } 4725 4726 // If we restored from a previous state, we may already have 4727 // instantiated this fragment from the state and should use 4728 // that instance instead of making a new one. 4729 Fragment fragment = id != View.NO_ID ? mFragments.findFragmentById(id) : null; 4730 if (fragment == null && tag != null) { 4731 fragment = mFragments.findFragmentByTag(tag); 4732 } 4733 if (fragment == null && containerId != View.NO_ID) { 4734 fragment = mFragments.findFragmentById(containerId); 4735 } 4736 4737 if (FragmentManagerImpl.DEBUG) Log.v(TAG, "onCreateView: id=0x" 4738 + Integer.toHexString(id) + " fname=" + fname 4739 + " existing=" + fragment); 4740 if (fragment == null) { 4741 fragment = Fragment.instantiate(this, fname); 4742 fragment.mFromLayout = true; 4743 fragment.mFragmentId = id != 0 ? id : containerId; 4744 fragment.mContainerId = containerId; 4745 fragment.mTag = tag; 4746 fragment.mInLayout = true; 4747 fragment.mFragmentManager = mFragments; 4748 fragment.onInflate(this, attrs, fragment.mSavedFragmentState); 4749 mFragments.addFragment(fragment, true); 4750 4751 } else if (fragment.mInLayout) { 4752 // A fragment already exists and it is not one we restored from 4753 // previous state. 4754 throw new IllegalArgumentException(attrs.getPositionDescription() 4755 + ": Duplicate id 0x" + Integer.toHexString(id) 4756 + ", tag " + tag + ", or parent id 0x" + Integer.toHexString(containerId) 4757 + " with another fragment for " + fname); 4758 } else { 4759 // This fragment was retained from a previous instance; get it 4760 // going now. 4761 fragment.mInLayout = true; 4762 // If this fragment is newly instantiated (either right now, or 4763 // from last saved state), then give it the attributes to 4764 // initialize itself. 4765 if (!fragment.mRetaining) { 4766 fragment.onInflate(this, attrs, fragment.mSavedFragmentState); 4767 } 4768 mFragments.moveToState(fragment); 4769 } 4770 4771 if (fragment.mView == null) { 4772 throw new IllegalStateException("Fragment " + fname 4773 + " did not create a view."); 4774 } 4775 if (id != 0) { 4776 fragment.mView.setId(id); 4777 } 4778 if (fragment.mView.getTag() == null) { 4779 fragment.mView.setTag(tag); 4780 } 4781 return fragment.mView; 4782 } 4783 4784 /** 4785 * Print the Activity's state into the given stream. This gets invoked if 4786 * you run "adb shell dumpsys activity <activity_component_name>". 4787 * 4788 * @param prefix Desired prefix to prepend at each line of output. 4789 * @param fd The raw file descriptor that the dump is being sent to. 4790 * @param writer The PrintWriter to which you should dump your state. This will be 4791 * closed for you after you return. 4792 * @param args additional arguments to the dump request. 4793 */ 4794 public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 4795 dumpInner(prefix, fd, writer, args); 4796 } 4797 4798 void dumpInner(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 4799 writer.print(prefix); writer.print("Local Activity "); 4800 writer.print(Integer.toHexString(System.identityHashCode(this))); 4801 writer.println(" State:"); 4802 String innerPrefix = prefix + " "; 4803 writer.print(innerPrefix); writer.print("mResumed="); 4804 writer.print(mResumed); writer.print(" mStopped="); 4805 writer.print(mStopped); writer.print(" mFinished="); 4806 writer.println(mFinished); 4807 writer.print(innerPrefix); writer.print("mLoadersStarted="); 4808 writer.println(mLoadersStarted); 4809 writer.print(innerPrefix); writer.print("mChangingConfigurations="); 4810 writer.println(mChangingConfigurations); 4811 writer.print(innerPrefix); writer.print("mCurrentConfig="); 4812 writer.println(mCurrentConfig); 4813 if (mLoaderManager != null) { 4814 writer.print(prefix); writer.print("Loader Manager "); 4815 writer.print(Integer.toHexString(System.identityHashCode(mLoaderManager))); 4816 writer.println(":"); 4817 mLoaderManager.dump(prefix + " ", fd, writer, args); 4818 } 4819 mFragments.dump(prefix, fd, writer, args); 4820 writer.print(prefix); writer.println("View Hierarchy:"); 4821 dumpViewHierarchy(prefix + " ", writer, getWindow().getDecorView()); 4822 } 4823 4824 private void dumpViewHierarchy(String prefix, PrintWriter writer, View view) { 4825 writer.print(prefix); 4826 if (view == null) { 4827 writer.println("null"); 4828 return; 4829 } 4830 writer.println(view.toString()); 4831 if (!(view instanceof ViewGroup)) { 4832 return; 4833 } 4834 ViewGroup grp = (ViewGroup)view; 4835 final int N = grp.getChildCount(); 4836 if (N <= 0) { 4837 return; 4838 } 4839 prefix = prefix + " "; 4840 for (int i=0; i<N; i++) { 4841 dumpViewHierarchy(prefix, writer, grp.getChildAt(i)); 4842 } 4843 } 4844 4845 /** 4846 * Bit indicating that this activity is "immersive" and should not be 4847 * interrupted by notifications if possible. 4848 * 4849 * This value is initially set by the manifest property 4850 * <code>android:immersive</code> but may be changed at runtime by 4851 * {@link #setImmersive}. 4852 * 4853 * @see #setImmersive(boolean) 4854 * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE 4855 */ 4856 public boolean isImmersive() { 4857 try { 4858 return ActivityManagerNative.getDefault().isImmersive(mToken); 4859 } catch (RemoteException e) { 4860 return false; 4861 } 4862 } 4863 4864 /** 4865 * Adjust the current immersive mode setting. 4866 * 4867 * Note that changing this value will have no effect on the activity's 4868 * {@link android.content.pm.ActivityInfo} structure; that is, if 4869 * <code>android:immersive</code> is set to <code>true</code> 4870 * in the application's manifest entry for this activity, the {@link 4871 * android.content.pm.ActivityInfo#flags ActivityInfo.flags} member will 4872 * always have its {@link android.content.pm.ActivityInfo#FLAG_IMMERSIVE 4873 * FLAG_IMMERSIVE} bit set. 4874 * 4875 * @see #isImmersive() 4876 * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE 4877 */ 4878 public void setImmersive(boolean i) { 4879 try { 4880 ActivityManagerNative.getDefault().setImmersive(mToken, i); 4881 } catch (RemoteException e) { 4882 // pass 4883 } 4884 } 4885 4886 /** 4887 * Start an action mode. 4888 * 4889 * @param callback Callback that will manage lifecycle events for this context mode 4890 * @return The ContextMode that was started, or null if it was canceled 4891 * 4892 * @see ActionMode 4893 */ 4894 public ActionMode startActionMode(ActionMode.Callback callback) { 4895 return mWindow.getDecorView().startActionMode(callback); 4896 } 4897 4898 /** 4899 * Give the Activity a chance to control the UI for an action mode requested 4900 * by the system. 4901 * 4902 * <p>Note: If you are looking for a notification callback that an action mode 4903 * has been started for this activity, see {@link #onActionModeStarted(ActionMode)}.</p> 4904 * 4905 * @param callback The callback that should control the new action mode 4906 * @return The new action mode, or <code>null</code> if the activity does not want to 4907 * provide special handling for this action mode. (It will be handled by the system.) 4908 */ 4909 public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) { 4910 initActionBar(); 4911 if (mActionBar != null) { 4912 return mActionBar.startActionMode(callback); 4913 } 4914 return null; 4915 } 4916 4917 /** 4918 * Notifies the Activity that an action mode has been started. 4919 * Activity subclasses overriding this method should call the superclass implementation. 4920 * 4921 * @param mode The new action mode. 4922 */ 4923 public void onActionModeStarted(ActionMode mode) { 4924 } 4925 4926 /** 4927 * Notifies the activity that an action mode has finished. 4928 * Activity subclasses overriding this method should call the superclass implementation. 4929 * 4930 * @param mode The action mode that just finished. 4931 */ 4932 public void onActionModeFinished(ActionMode mode) { 4933 } 4934 4935 /** 4936 * Returns true if the app should recreate the task when navigating 'up' from this activity 4937 * by using targetIntent. 4938 * 4939 * <p>If this method returns false the app can trivially call 4940 * {@link #navigateUpTo(Intent)} using the same parameters to correctly perform 4941 * up navigation. If this method returns false, the app should synthesize a new task stack 4942 * by using {@link TaskStackBuilder} or another similar mechanism to perform up navigation.</p> 4943 * 4944 * @param targetIntent An intent representing the target destination for up navigation 4945 * @return true if navigating up should recreate a new task stack, false if the same task 4946 * should be used for the destination 4947 */ 4948 public boolean shouldUpRecreateTask(Intent targetIntent) { 4949 try { 4950 PackageManager pm = getPackageManager(); 4951 ComponentName cn = targetIntent.getComponent(); 4952 if (cn == null) { 4953 cn = targetIntent.resolveActivity(pm); 4954 } 4955 ActivityInfo info = pm.getActivityInfo(cn, 0); 4956 if (info.taskAffinity == null) { 4957 return false; 4958 } 4959 return !ActivityManagerNative.getDefault() 4960 .targetTaskAffinityMatchesActivity(mToken, info.taskAffinity); 4961 } catch (RemoteException e) { 4962 return false; 4963 } catch (NameNotFoundException e) { 4964 return false; 4965 } 4966 } 4967 4968 /** 4969 * Navigate from this activity to the activity specified by upIntent, finishing this activity 4970 * in the process. If the activity indicated by upIntent already exists in the task's history, 4971 * this activity and all others before the indicated activity in the history stack will be 4972 * finished. 4973 * 4974 * <p>If the indicated activity does not appear in the history stack, this will finish 4975 * each activity in this task until the root activity of the task is reached, resulting in 4976 * an "in-app home" behavior. This can be useful in apps with a complex navigation hierarchy 4977 * when an activity may be reached by a path not passing through a canonical parent 4978 * activity.</p> 4979 * 4980 * <p>This method should be used when performing up navigation from within the same task 4981 * as the destination. If up navigation should cross tasks in some cases, see 4982 * {@link #shouldUpRecreateTask(Intent)}.</p> 4983 * 4984 * @param upIntent An intent representing the target destination for up navigation 4985 * 4986 * @return true if up navigation successfully reached the activity indicated by upIntent and 4987 * upIntent was delivered to it. false if an instance of the indicated activity could 4988 * not be found and this activity was simply finished normally. 4989 */ 4990 public boolean navigateUpTo(Intent upIntent) { 4991 if (mParent == null) { 4992 ComponentName destInfo = upIntent.getComponent(); 4993 if (destInfo == null) { 4994 destInfo = upIntent.resolveActivity(getPackageManager()); 4995 if (destInfo == null) { 4996 return false; 4997 } 4998 upIntent = new Intent(upIntent); 4999 upIntent.setComponent(destInfo); 5000 } 5001 int resultCode; 5002 Intent resultData; 5003 synchronized (this) { 5004 resultCode = mResultCode; 5005 resultData = mResultData; 5006 } 5007 if (resultData != null) { 5008 resultData.prepareToLeaveProcess(); 5009 } 5010 try { 5011 upIntent.prepareToLeaveProcess(); 5012 return ActivityManagerNative.getDefault().navigateUpTo(mToken, upIntent, 5013 resultCode, resultData); 5014 } catch (RemoteException e) { 5015 return false; 5016 } 5017 } else { 5018 return mParent.navigateUpToFromChild(this, upIntent); 5019 } 5020 } 5021 5022 /** 5023 * This is called when a child activity of this one calls its 5024 * {@link #navigateUpTo} method. The default implementation simply calls 5025 * navigateUpTo(upIntent) on this activity (the parent). 5026 * 5027 * @param child The activity making the call. 5028 * @param upIntent An intent representing the target destination for up navigation 5029 * 5030 * @return true if up navigation successfully reached the activity indicated by upIntent and 5031 * upIntent was delivered to it. false if an instance of the indicated activity could 5032 * not be found and this activity was simply finished normally. 5033 */ 5034 public boolean navigateUpToFromChild(Activity child, Intent upIntent) { 5035 return navigateUpTo(upIntent); 5036 } 5037 5038 /** 5039 * Obtain an {@link Intent} that will launch an explicit target activity specified by 5040 * this activity's logical parent. The logical parent is named in the application's manifest 5041 * by the {@link android.R.attr#parentActivityName parentActivityName} attribute. 5042 * Activity subclasses may override this method to modify the Intent returned by 5043 * super.getParentActivityIntent() or to implement a different mechanism of retrieving 5044 * the parent intent entirely. 5045 * 5046 * @return a new Intent targeting the defined parent of this activity or null if 5047 * there is no valid parent. 5048 */ 5049 public Intent getParentActivityIntent() { 5050 final String parentName = mActivityInfo.parentActivityName; 5051 if (TextUtils.isEmpty(parentName)) { 5052 return null; 5053 } 5054 5055 // If the parent itself has no parent, generate a main activity intent. 5056 final ComponentName target = new ComponentName(this, parentName); 5057 try { 5058 final ActivityInfo parentInfo = getPackageManager().getActivityInfo(target, 0); 5059 final String parentActivity = parentInfo.parentActivityName; 5060 final Intent parentIntent = parentActivity == null 5061 ? Intent.makeMainActivity(target) 5062 : new Intent().setComponent(target); 5063 return parentIntent; 5064 } catch (NameNotFoundException e) { 5065 Log.e(TAG, "getParentActivityIntent: bad parentActivityName '" + parentName + 5066 "' in manifest"); 5067 return null; 5068 } 5069 } 5070 5071 // ------------------ Internal API ------------------ 5072 5073 final void setParent(Activity parent) { 5074 mParent = parent; 5075 } 5076 5077 final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, 5078 Application application, Intent intent, ActivityInfo info, CharSequence title, 5079 Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, 5080 Configuration config) { 5081 attach(context, aThread, instr, token, 0, application, intent, info, title, parent, id, 5082 lastNonConfigurationInstances, config); 5083 } 5084 5085 final void attach(Context context, ActivityThread aThread, 5086 Instrumentation instr, IBinder token, int ident, 5087 Application application, Intent intent, ActivityInfo info, 5088 CharSequence title, Activity parent, String id, 5089 NonConfigurationInstances lastNonConfigurationInstances, 5090 Configuration config) { 5091 attachBaseContext(context); 5092 5093 mFragments.attachActivity(this, mContainer, null); 5094 5095 mWindow = PolicyManager.makeNewWindow(this); 5096 mWindow.setCallback(this); 5097 mWindow.getLayoutInflater().setPrivateFactory(this); 5098 if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { 5099 mWindow.setSoftInputMode(info.softInputMode); 5100 } 5101 if (info.uiOptions != 0) { 5102 mWindow.setUiOptions(info.uiOptions); 5103 } 5104 mUiThread = Thread.currentThread(); 5105 5106 mMainThread = aThread; 5107 mInstrumentation = instr; 5108 mToken = token; 5109 mIdent = ident; 5110 mApplication = application; 5111 mIntent = intent; 5112 mComponent = intent.getComponent(); 5113 mActivityInfo = info; 5114 mTitle = title; 5115 mParent = parent; 5116 mEmbeddedID = id; 5117 mLastNonConfigurationInstances = lastNonConfigurationInstances; 5118 5119 mWindow.setWindowManager( 5120 (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), 5121 mToken, mComponent.flattenToString(), 5122 (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); 5123 if (mParent != null) { 5124 mWindow.setContainer(mParent.getWindow()); 5125 } 5126 mWindowManager = mWindow.getWindowManager(); 5127 mCurrentConfig = config; 5128 } 5129 5130 /** @hide */ 5131 public final IBinder getActivityToken() { 5132 return mParent != null ? mParent.getActivityToken() : mToken; 5133 } 5134 5135 final void performCreate(Bundle icicle) { 5136 onCreate(icicle); 5137 mVisibleFromClient = !mWindow.getWindowStyle().getBoolean( 5138 com.android.internal.R.styleable.Window_windowNoDisplay, false); 5139 mFragments.dispatchActivityCreated(); 5140 } 5141 5142 final void performStart() { 5143 mFragments.noteStateNotSaved(); 5144 mCalled = false; 5145 mFragments.execPendingActions(); 5146 mInstrumentation.callActivityOnStart(this); 5147 if (!mCalled) { 5148 throw new SuperNotCalledException( 5149 "Activity " + mComponent.toShortString() + 5150 " did not call through to super.onStart()"); 5151 } 5152 mFragments.dispatchStart(); 5153 if (mAllLoaderManagers != null) { 5154 LoaderManagerImpl loaders[] = new LoaderManagerImpl[mAllLoaderManagers.size()]; 5155 mAllLoaderManagers.values().toArray(loaders); 5156 if (loaders != null) { 5157 for (int i=0; i<loaders.length; i++) { 5158 LoaderManagerImpl lm = loaders[i]; 5159 lm.finishRetain(); 5160 lm.doReportStart(); 5161 } 5162 } 5163 } 5164 } 5165 5166 final void performRestart() { 5167 mFragments.noteStateNotSaved(); 5168 5169 if (mStopped) { 5170 mStopped = false; 5171 if (mToken != null && mParent == null) { 5172 WindowManagerGlobal.getInstance().setStoppedState(mToken, false); 5173 } 5174 5175 synchronized (mManagedCursors) { 5176 final int N = mManagedCursors.size(); 5177 for (int i=0; i<N; i++) { 5178 ManagedCursor mc = mManagedCursors.get(i); 5179 if (mc.mReleased || mc.mUpdated) { 5180 if (!mc.mCursor.requery()) { 5181 if (getApplicationInfo().targetSdkVersion 5182 >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 5183 throw new IllegalStateException( 5184 "trying to requery an already closed cursor " 5185 + mc.mCursor); 5186 } 5187 } 5188 mc.mReleased = false; 5189 mc.mUpdated = false; 5190 } 5191 } 5192 } 5193 5194 mCalled = false; 5195 mInstrumentation.callActivityOnRestart(this); 5196 if (!mCalled) { 5197 throw new SuperNotCalledException( 5198 "Activity " + mComponent.toShortString() + 5199 " did not call through to super.onRestart()"); 5200 } 5201 performStart(); 5202 } 5203 } 5204 5205 final void performResume() { 5206 performRestart(); 5207 5208 mFragments.execPendingActions(); 5209 5210 mLastNonConfigurationInstances = null; 5211 5212 mCalled = false; 5213 // mResumed is set by the instrumentation 5214 mInstrumentation.callActivityOnResume(this); 5215 if (!mCalled) { 5216 throw new SuperNotCalledException( 5217 "Activity " + mComponent.toShortString() + 5218 " did not call through to super.onResume()"); 5219 } 5220 5221 // Now really resume, and install the current status bar and menu. 5222 mCalled = false; 5223 5224 mFragments.dispatchResume(); 5225 mFragments.execPendingActions(); 5226 5227 onPostResume(); 5228 if (!mCalled) { 5229 throw new SuperNotCalledException( 5230 "Activity " + mComponent.toShortString() + 5231 " did not call through to super.onPostResume()"); 5232 } 5233 } 5234 5235 final void performPause() { 5236 mFragments.dispatchPause(); 5237 mCalled = false; 5238 onPause(); 5239 mResumed = false; 5240 if (!mCalled && getApplicationInfo().targetSdkVersion 5241 >= android.os.Build.VERSION_CODES.GINGERBREAD) { 5242 throw new SuperNotCalledException( 5243 "Activity " + mComponent.toShortString() + 5244 " did not call through to super.onPause()"); 5245 } 5246 mResumed = false; 5247 } 5248 5249 final void performUserLeaving() { 5250 onUserInteraction(); 5251 onUserLeaveHint(); 5252 } 5253 5254 final void performStop() { 5255 if (mLoadersStarted) { 5256 mLoadersStarted = false; 5257 if (mLoaderManager != null) { 5258 if (!mChangingConfigurations) { 5259 mLoaderManager.doStop(); 5260 } else { 5261 mLoaderManager.doRetain(); 5262 } 5263 } 5264 } 5265 5266 if (!mStopped) { 5267 if (mWindow != null) { 5268 mWindow.closeAllPanels(); 5269 } 5270 5271 if (mToken != null && mParent == null) { 5272 WindowManagerGlobal.getInstance().setStoppedState(mToken, true); 5273 } 5274 5275 mFragments.dispatchStop(); 5276 5277 mCalled = false; 5278 mInstrumentation.callActivityOnStop(this); 5279 if (!mCalled) { 5280 throw new SuperNotCalledException( 5281 "Activity " + mComponent.toShortString() + 5282 " did not call through to super.onStop()"); 5283 } 5284 5285 synchronized (mManagedCursors) { 5286 final int N = mManagedCursors.size(); 5287 for (int i=0; i<N; i++) { 5288 ManagedCursor mc = mManagedCursors.get(i); 5289 if (!mc.mReleased) { 5290 mc.mCursor.deactivate(); 5291 mc.mReleased = true; 5292 } 5293 } 5294 } 5295 5296 mStopped = true; 5297 } 5298 mResumed = false; 5299 } 5300 5301 final void performDestroy() { 5302 mDestroyed = true; 5303 mWindow.destroy(); 5304 mFragments.dispatchDestroy(); 5305 onDestroy(); 5306 if (mLoaderManager != null) { 5307 mLoaderManager.doDestroy(); 5308 } 5309 } 5310 5311 /** 5312 * @hide 5313 */ 5314 public final boolean isResumed() { 5315 return mResumed; 5316 } 5317 5318 void dispatchActivityResult(String who, int requestCode, 5319 int resultCode, Intent data) { 5320 if (false) Log.v( 5321 TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode 5322 + ", resCode=" + resultCode + ", data=" + data); 5323 mFragments.noteStateNotSaved(); 5324 if (who == null) { 5325 onActivityResult(requestCode, resultCode, data); 5326 } else { 5327 Fragment frag = mFragments.findFragmentByWho(who); 5328 if (frag != null) { 5329 frag.onActivityResult(requestCode, resultCode, data); 5330 } 5331 } 5332 } 5333} 5334