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 17 package android.app; 18 19 import com.android.internal.app.ActionBarImpl; 20 import com.android.internal.policy.PolicyManager; 21 22 import android.content.ComponentCallbacks2; 23 import android.content.ComponentName; 24 import android.content.ContentResolver; 25 import android.content.Context; 26 import android.content.CursorLoader; 27 import android.content.IIntentSender; 28 import android.content.Intent; 29 import android.content.IntentSender; 30 import android.content.SharedPreferences; 31 import android.content.pm.ActivityInfo; 32 import android.content.res.Configuration; 33 import android.content.res.Resources; 34 import android.content.res.TypedArray; 35 import android.content.res.Resources.Theme; 36 import android.database.Cursor; 37 import android.graphics.Bitmap; 38 import android.graphics.Canvas; 39 import android.graphics.drawable.Drawable; 40 import android.media.AudioManager; 41 import android.net.Uri; 42 import android.os.Build; 43 import android.os.Bundle; 44 import android.os.Handler; 45 import android.os.IBinder; 46 import android.os.Looper; 47 import android.os.Parcelable; 48 import android.os.RemoteException; 49 import android.os.StrictMode; 50 import android.text.Selection; 51 import android.text.SpannableStringBuilder; 52 import android.text.TextUtils; 53 import android.text.method.TextKeyListener; 54 import android.util.AttributeSet; 55 import android.util.EventLog; 56 import android.util.Log; 57 import android.util.SparseArray; 58 import android.util.TypedValue; 59 import android.view.ActionMode; 60 import android.view.ContextMenu; 61 import android.view.ContextMenu.ContextMenuInfo; 62 import android.view.ContextThemeWrapper; 63 import android.view.KeyEvent; 64 import android.view.LayoutInflater; 65 import android.view.Menu; 66 import android.view.MenuInflater; 67 import android.view.MenuItem; 68 import android.view.MotionEvent; 69 import android.view.View; 70 import android.view.WindowManagerImpl; 71 import android.view.View.OnCreateContextMenuListener; 72 import android.view.ViewGroup; 73 import android.view.ViewGroup.LayoutParams; 74 import android.view.ViewManager; 75 import android.view.Window; 76 import android.view.WindowManager; 77 import android.view.accessibility.AccessibilityEvent; 78 import android.widget.AdapterView; 79 80 import java.io.FileDescriptor; 81 import java.io.PrintWriter; 82 import java.util.ArrayList; 83 import java.util.HashMap; 84 85 /** 86 * An activity is a single, focused thing that the user can do. Almost all 87 * activities interact with the user, so the Activity class takes care of 88 * creating a window for you in which you can place your UI with 89 * {@link #setContentView}. While activities are often presented to the user 90 * as full-screen windows, they can also be used in other ways: as floating 91 * windows (via a theme with {@link android.R.attr#windowIsFloating} set) 92 * or embedded inside of another activity (using {@link ActivityGroup}). 93 * 94 * There are two methods almost all subclasses of Activity will implement: 95 * 96 * <ul> 97 * <li> {@link #onCreate} is where you initialize your activity. Most 98 * importantly, here you will usually call {@link #setContentView(int)} 99 * with a layout resource defining your UI, and using {@link #findViewById} 100 * to retrieve the widgets in that UI that you need to interact with 101 * programmatically. 102 * 103 * <li> {@link #onPause} is where you deal with the user leaving your 104 * activity. Most importantly, any changes made by the user should at this 105 * point be committed (usually to the 106 * {@link android.content.ContentProvider} holding the data). 107 * </ul> 108 * 109 * <p>To be of use with {@link android.content.Context#startActivity Context.startActivity()}, all 110 * activity classes must have a corresponding 111 * {@link android.R.styleable#AndroidManifestActivity <activity>} 112 * declaration in their package's <code>AndroidManifest.xml</code>.</p> 113 * 114 * <p>Topics covered here: 115 * <ol> 116 * <li><a href="#Fragments">Fragments</a> 117 * <li><a href="#ActivityLifecycle">Activity Lifecycle</a> 118 * <li><a href="#ConfigurationChanges">Configuration Changes</a> 119 * <li><a href="#StartingActivities">Starting Activities and Getting Results</a> 120 * <li><a href="#SavingPersistentState">Saving Persistent State</a> 121 * <li><a href="#Permissions">Permissions</a> 122 * <li><a href="#ProcessLifecycle">Process Lifecycle</a> 123 * </ol> 124 * 125 * <div class="special reference"> 126 * <h3>Developer Guides</h3> 127 * <p>The Activity class is an important part of an application's overall lifecycle, 128 * and the way activities are launched and put together is a fundamental 129 * part of the platform's application model. For a detailed perspective on the structure of an 130 * Android application and how activities behave, please read the 131 * <a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> and 132 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a> 133 * developer guides.</p> 134 * 135 * <p>You can also find a detailed discussion about how to create activities in the 136 * <a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a> 137 * developer guide.</p> 138 * </div> 139 * 140 * <a name="Fragments"></a> 141 * <h3>Fragments</h3> 142 * 143 * <p>Starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB}, Activity 144 * implementations can make use of the {@link Fragment} class to better 145 * modularize their code, build more sophisticated user interfaces for larger 146 * screens, and help scale their application between small and large screens. 147 * 148 * <a name="ActivityLifecycle"></a> 149 * <h3>Activity Lifecycle</h3> 150 * 151 * <p>Activities in the system are managed as an <em>activity stack</em>. 152 * When a new activity is started, it is placed on the top of the stack 153 * and becomes the running activity -- the previous activity always remains 154 * below it in the stack, and will not come to the foreground again until 155 * the new activity exits.</p> 156 * 157 * <p>An activity has essentially four states:</p> 158 * <ul> 159 * <li> If an activity in the foreground of the screen (at the top of 160 * the stack), 161 * it is <em>active</em> or <em>running</em>. </li> 162 * <li>If an activity has lost focus but is still visible (that is, a new non-full-sized 163 * or transparent activity has focus on top of your activity), it 164 * is <em>paused</em>. A paused activity is completely alive (it 165 * maintains all state and member information and remains attached to 166 * the window manager), but can be killed by the system in extreme 167 * low memory situations. 168 * <li>If an activity is completely obscured by another activity, 169 * it is <em>stopped</em>. It still retains all state and member information, 170 * however, it is no longer visible to the user so its window is hidden 171 * and it will often be killed by the system when memory is needed 172 * elsewhere.</li> 173 * <li>If an activity is paused or stopped, the system can drop the activity 174 * from memory by either asking it to finish, or simply killing its 175 * process. When it is displayed again to the user, it must be 176 * completely restarted and restored to its previous state.</li> 177 * </ul> 178 * 179 * <p>The following diagram shows the important state paths of an Activity. 180 * The square rectangles represent callback methods you can implement to 181 * perform operations when the Activity moves between states. The colored 182 * ovals are major states the Activity can be in.</p> 183 * 184 * <p><img src="../../../images/activity_lifecycle.png" 185 * alt="State diagram for an Android Activity Lifecycle." border="0" /></p> 186 * 187 * <p>There are three key loops you may be interested in monitoring within your 188 * activity: 189 * 190 * <ul> 191 * <li>The <b>entire lifetime</b> of an activity happens between the first call 192 * to {@link android.app.Activity#onCreate} through to a single final call 193 * to {@link android.app.Activity#onDestroy}. An activity will do all setup 194 * of "global" state in onCreate(), and release all remaining resources in 195 * onDestroy(). For example, if it has a thread running in the background 196 * to download data from the network, it may create that thread in onCreate() 197 * and then stop the thread in onDestroy(). 198 * 199 * <li>The <b>visible lifetime</b> of an activity happens between a call to 200 * {@link android.app.Activity#onStart} until a corresponding call to 201 * {@link android.app.Activity#onStop}. During this time the user can see the 202 * activity on-screen, though it may not be in the foreground and interacting 203 * with the user. Between these two methods you can maintain resources that 204 * are needed to show the activity to the user. For example, you can register 205 * a {@link android.content.BroadcastReceiver} in onStart() to monitor for changes 206 * that impact your UI, and unregister it in onStop() when the user an no 207 * longer see what you are displaying. The onStart() and onStop() methods 208 * can be called multiple times, as the activity becomes visible and hidden 209 * to the user. 210 * 211 * <li>The <b>foreground lifetime</b> of an activity happens between a call to 212 * {@link android.app.Activity#onResume} until a corresponding call to 213 * {@link android.app.Activity#onPause}. During this time the activity is 214 * in front of all other activities and interacting with the user. An activity 215 * can frequently go between the resumed and paused states -- for example when 216 * the device goes to sleep, when an activity result is delivered, when a new 217 * intent is delivered -- so the code in these methods should be fairly 218 * lightweight. 219 * </ul> 220 * 221 * <p>The entire lifecycle of an activity is defined by the following 222 * Activity methods. All of these are hooks that you can override 223 * to do appropriate work when the activity changes state. All 224 * activities will implement {@link android.app.Activity#onCreate} 225 * to do their initial setup; many will also implement 226 * {@link android.app.Activity#onPause} to commit changes to data and 227 * otherwise prepare to stop interacting with the user. You should always 228 * call up to your superclass when implementing these methods.</p> 229 * 230 * </p> 231 * <pre class="prettyprint"> 232 * public class Activity extends ApplicationContext { 233 * protected void onCreate(Bundle savedInstanceState); 234 * 235 * protected void onStart(); 236 * 237 * protected void onRestart(); 238 * 239 * protected void onResume(); 240 * 241 * protected void onPause(); 242 * 243 * protected void onStop(); 244 * 245 * protected void onDestroy(); 246 * } 247 * </pre> 248 * 249 * <p>In general the movement through an activity's lifecycle looks like 250 * this:</p> 251 * 252 * <table border="2" width="85%" align="center" frame="hsides" rules="rows"> 253 * <colgroup align="left" span="3" /> 254 * <colgroup align="left" /> 255 * <colgroup align="center" /> 256 * <colgroup align="center" /> 257 * 258 * <thead> 259 * <tr><th colspan="3">Method</th> <th>Description</th> <th>Killable?</th> <th>Next</th></tr> 260 * </thead> 261 * 262 * <tbody> 263 * <tr><th colspan="3" align="left" border="0">{@link android.app.Activity#onCreate onCreate()}</th> 264 * <td>Called when the activity is first created. 265 * This is where you should do all of your normal static set up: 266 * create views, bind data to lists, etc. This method also 267 * provides you with a Bundle containing the activity's previously 268 * frozen state, if there was one. 269 * <p>Always followed by <code>onStart()</code>.</td> 270 * <td align="center">No</td> 271 * <td align="center"><code>onStart()</code></td> 272 * </tr> 273 * 274 * <tr><td rowspan="5" style="border-left: none; border-right: none;"> </td> 275 * <th colspan="2" align="left" border="0">{@link android.app.Activity#onRestart onRestart()}</th> 276 * <td>Called after your activity has been stopped, prior to it being 277 * started again. 278 * <p>Always followed by <code>onStart()</code></td> 279 * <td align="center">No</td> 280 * <td align="center"><code>onStart()</code></td> 281 * </tr> 282 * 283 * <tr><th colspan="2" align="left" border="0">{@link android.app.Activity#onStart onStart()}</th> 284 * <td>Called when the activity is becoming visible to the user. 285 * <p>Followed by <code>onResume()</code> if the activity comes 286 * to the foreground, or <code>onStop()</code> if it becomes hidden.</td> 287 * <td align="center">No</td> 288 * <td align="center"><code>onResume()</code> or <code>onStop()</code></td> 289 * </tr> 290 * 291 * <tr><td rowspan="2" style="border-left: none;"> </td> 292 * <th align="left" border="0">{@link android.app.Activity#onResume onResume()}</th> 293 * <td>Called when the activity will start 294 * interacting with the user. At this point your activity is at 295 * the top of the activity stack, with user input going to it. 296 * <p>Always followed by <code>onPause()</code>.</td> 297 * <td align="center">No</td> 298 * <td align="center"><code>onPause()</code></td> 299 * </tr> 300 * 301 * <tr><th align="left" border="0">{@link android.app.Activity#onPause onPause()}</th> 302 * <td>Called when the system is about to start resuming a previous 303 * activity. This is typically used to commit unsaved changes to 304 * persistent data, stop animations and other things that may be consuming 305 * CPU, etc. Implementations of this method must be very quick because 306 * the next activity will not be resumed until this method returns. 307 * <p>Followed by either <code>onResume()</code> if the activity 308 * returns back to the front, or <code>onStop()</code> if it becomes 309 * invisible to the user.</td> 310 * <td align="center"><font color="#800000"><strong>Pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB}</strong></font></td> 311 * <td align="center"><code>onResume()</code> or<br> 312 * <code>onStop()</code></td> 313 * </tr> 314 * 315 * <tr><th colspan="2" align="left" border="0">{@link android.app.Activity#onStop onStop()}</th> 316 * <td>Called when the activity is no longer visible to the user, because 317 * another activity has been resumed and is covering this one. This 318 * may happen either because a new activity is being started, an existing 319 * one is being brought in front of this one, or this one is being 320 * destroyed. 321 * <p>Followed by either <code>onRestart()</code> if 322 * this activity is coming back to interact with the user, or 323 * <code>onDestroy()</code> if this activity is going away.</td> 324 * <td align="center"><font color="#800000"><strong>Yes</strong></font></td> 325 * <td align="center"><code>onRestart()</code> or<br> 326 * <code>onDestroy()</code></td> 327 * </tr> 328 * 329 * <tr><th colspan="3" align="left" border="0">{@link android.app.Activity#onDestroy onDestroy()}</th> 330 * <td>The final call you receive before your 331 * activity is destroyed. This can happen either because the 332 * activity is finishing (someone called {@link Activity#finish} on 333 * it, or because the system is temporarily destroying this 334 * instance of the activity to save space. You can distinguish 335 * between these two scenarios with the {@link 336 * Activity#isFinishing} method.</td> 337 * <td align="center"><font color="#800000"><strong>Yes</strong></font></td> 338 * <td align="center"><em>nothing</em></td> 339 * </tr> 340 * </tbody> 341 * </table> 342 * 343 * <p>Note the "Killable" column in the above table -- for those methods that 344 * are marked as being killable, after that method returns the process hosting the 345 * activity may killed by the system <em>at any time</em> without another line 346 * of its code being executed. Because of this, you should use the 347 * {@link #onPause} method to write any persistent data (such as user edits) 348 * to storage. In addition, the method 349 * {@link #onSaveInstanceState(Bundle)} is called before placing the activity 350 * in such a background state, allowing you to save away any dynamic instance 351 * state in your activity into the given Bundle, to be later received in 352 * {@link #onCreate} if the activity needs to be re-created. 353 * See the <a href="#ProcessLifecycle">Process Lifecycle</a> 354 * section for more information on how the lifecycle of a process is tied 355 * to the activities it is hosting. Note that it is important to save 356 * persistent data in {@link #onPause} instead of {@link #onSaveInstanceState} 357 * because the latter is not part of the lifecycle callbacks, so will not 358 * be called in every situation as described in its documentation.</p> 359 * 360 * <p class="note">Be aware that these semantics will change slightly between 361 * applications targeting platforms starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB} 362 * vs. those targeting prior platforms. Starting with Honeycomb, an application 363 * is not in the killable state until its {@link #onStop} has returned. This 364 * impacts when {@link #onSaveInstanceState(Bundle)} may be called (it may be 365 * safely called after {@link #onPause()} and allows and application to safely 366 * wait until {@link #onStop()} to save persistent state.</p> 367 * 368 * <p>For those methods that are not marked as being killable, the activity's 369 * process will not be killed by the system starting from the time the method 370 * is called and continuing after it returns. Thus an activity is in the killable 371 * state, for example, between after <code>onPause()</code> to the start of 372 * <code>onResume()</code>.</p> 373 * 374 * <a name="ConfigurationChanges"></a> 375 * <h3>Configuration Changes</h3> 376 * 377 * <p>If the configuration of the device (as defined by the 378 * {@link Configuration Resources.Configuration} class) changes, 379 * then anything displaying a user interface will need to update to match that 380 * configuration. Because Activity is the primary mechanism for interacting 381 * with the user, it includes special support for handling configuration 382 * changes.</p> 383 * 384 * <p>Unless you specify otherwise, a configuration change (such as a change 385 * in screen orientation, language, input devices, etc) will cause your 386 * current activity to be <em>destroyed</em>, going through the normal activity 387 * lifecycle process of {@link #onPause}, 388 * {@link #onStop}, and {@link #onDestroy} as appropriate. If the activity 389 * had been in the foreground or visible to the user, once {@link #onDestroy} is 390 * called in that instance then a new instance of the activity will be 391 * created, with whatever savedInstanceState the previous instance had generated 392 * from {@link #onSaveInstanceState}.</p> 393 * 394 * <p>This is done because any application resource, 395 * including layout files, can change based on any configuration value. Thus 396 * the only safe way to handle a configuration change is to re-retrieve all 397 * resources, including layouts, drawables, and strings. Because activities 398 * must already know how to save their state and re-create themselves from 399 * that state, this is a convenient way to have an activity restart itself 400 * with a new configuration.</p> 401 * 402 * <p>In some special cases, you may want to bypass restarting of your 403 * activity based on one or more types of configuration changes. This is 404 * done with the {@link android.R.attr#configChanges android:configChanges} 405 * attribute in its manifest. For any types of configuration changes you say 406 * that you handle there, you will receive a call to your current activity's 407 * {@link #onConfigurationChanged} method instead of being restarted. If 408 * a configuration change involves any that you do not handle, however, the 409 * activity will still be restarted and {@link #onConfigurationChanged} 410 * will not be called.</p> 411 * 412 * <a name="StartingActivities"></a> 413 * <h3>Starting Activities and Getting Results</h3> 414 * 415 * <p>The {@link android.app.Activity#startActivity} 416 * method is used to start a 417 * new activity, which will be placed at the top of the activity stack. It 418 * takes a single argument, an {@link android.content.Intent Intent}, 419 * which describes the activity 420 * to be executed.</p> 421 * 422 * <p>Sometimes you want to get a result back from an activity when it 423 * ends. For example, you may start an activity that lets the user pick 424 * a person in a list of contacts; when it ends, it returns the person 425 * that was selected. To do this, you call the 426 * {@link android.app.Activity#startActivityForResult(Intent, int)} 427 * version with a second integer parameter identifying the call. The result 428 * will come back through your {@link android.app.Activity#onActivityResult} 429 * method.</p> 430 * 431 * <p>When an activity exits, it can call 432 * {@link android.app.Activity#setResult(int)} 433 * to return data back to its parent. It must always supply a result code, 434 * which can be the standard results RESULT_CANCELED, RESULT_OK, or any 435 * custom values starting at RESULT_FIRST_USER. In addition, it can optionally 436 * return back an Intent containing any additional data it wants. All of this 437 * information appears back on the 438 * parent's <code>Activity.onActivityResult()</code>, along with the integer 439 * identifier it originally supplied.</p> 440 * 441 * <p>If a child activity fails for any reason (such as crashing), the parent 442 * activity will receive a result with the code RESULT_CANCELED.</p> 443 * 444 * <pre class="prettyprint"> 445 * public class MyActivity extends Activity { 446 * ... 447 * 448 * static final int PICK_CONTACT_REQUEST = 0; 449 * 450 * protected boolean onKeyDown(int keyCode, KeyEvent event) { 451 * if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 452 * // When the user center presses, let them pick a contact. 453 * startActivityForResult( 454 * new Intent(Intent.ACTION_PICK, 455 * new Uri("content://contacts")), 456 * PICK_CONTACT_REQUEST); 457 * return true; 458 * } 459 * return false; 460 * } 461 * 462 * protected void onActivityResult(int requestCode, int resultCode, 463 * Intent data) { 464 * if (requestCode == PICK_CONTACT_REQUEST) { 465 * if (resultCode == RESULT_OK) { 466 * // A contact was picked. Here we will just display it 467 * // to the user. 468 * startActivity(new Intent(Intent.ACTION_VIEW, data)); 469 * } 470 * } 471 * } 472 * } 473 * </pre> 474 * 475 * <a name="SavingPersistentState"></a> 476 * <h3>Saving Persistent State</h3> 477 * 478 * <p>There are generally two kinds of persistent state than an activity 479 * will deal with: shared document-like data (typically stored in a SQLite 480 * database using a {@linkplain android.content.ContentProvider content provider}) 481 * and internal state such as user preferences.</p> 482 * 483 * <p>For content provider data, we suggest that activities use a 484 * "edit in place" user model. That is, any edits a user makes are effectively 485 * made immediately without requiring an additional confirmation step. 486 * Supporting this model is generally a simple matter of following two rules:</p> 487 * 488 * <ul> 489 * <li> <p>When creating a new document, the backing database entry or file for 490 * it is created immediately. For example, if the user chooses to write 491 * a new e-mail, a new entry for that e-mail is created as soon as they 492 * start entering data, so that if they go to any other activity after 493 * that point this e-mail will now appear in the list of drafts.</p> 494 * <li> <p>When an activity's <code>onPause()</code> method is called, it should 495 * commit to the backing content provider or file any changes the user 496 * has made. This ensures that those changes will be seen by any other 497 * activity that is about to run. You will probably want to commit 498 * your data even more aggressively at key times during your 499 * activity's lifecycle: for example before starting a new 500 * activity, before finishing your own activity, when the user 501 * switches between input fields, etc.</p> 502 * </ul> 503 * 504 * <p>This model is designed to prevent data loss when a user is navigating 505 * between activities, and allows the system to safely kill an activity (because 506 * system resources are needed somewhere else) at any time after it has been 507 * paused. Note this implies 508 * that the user pressing BACK from your activity does <em>not</em> 509 * mean "cancel" -- it means to leave the activity with its current contents 510 * saved away. Canceling edits in an activity must be provided through 511 * some other mechanism, such as an explicit "revert" or "undo" option.</p> 512 * 513 * <p>See the {@linkplain android.content.ContentProvider content package} for 514 * more information about content providers. These are a key aspect of how 515 * different activities invoke and propagate data between themselves.</p> 516 * 517 * <p>The Activity class also provides an API for managing internal persistent state 518 * associated with an activity. This can be used, for example, to remember 519 * the user's preferred initial display in a calendar (day view or week view) 520 * or the user's default home page in a web browser.</p> 521 * 522 * <p>Activity persistent state is managed 523 * with the method {@link #getPreferences}, 524 * allowing you to retrieve and 525 * modify a set of name/value pairs associated with the activity. To use 526 * preferences that are shared across multiple application components 527 * (activities, receivers, services, providers), you can use the underlying 528 * {@link Context#getSharedPreferences Context.getSharedPreferences()} method 529 * to retrieve a preferences 530 * object stored under a specific name. 531 * (Note that it is not possible to share settings data across application 532 * packages -- for that you will need a content provider.)</p> 533 * 534 * <p>Here is an excerpt from a calendar activity that stores the user's 535 * preferred view mode in its persistent settings:</p> 536 * 537 * <pre class="prettyprint"> 538 * public class CalendarActivity extends Activity { 539 * ... 540 * 541 * static final int DAY_VIEW_MODE = 0; 542 * static final int WEEK_VIEW_MODE = 1; 543 * 544 * private SharedPreferences mPrefs; 545 * private int mCurViewMode; 546 * 547 * protected void onCreate(Bundle savedInstanceState) { 548 * super.onCreate(savedInstanceState); 549 * 550 * SharedPreferences mPrefs = getSharedPreferences(); 551 * mCurViewMode = mPrefs.getInt("view_mode" DAY_VIEW_MODE); 552 * } 553 * 554 * protected void onPause() { 555 * super.onPause(); 556 * 557 * SharedPreferences.Editor ed = mPrefs.edit(); 558 * ed.putInt("view_mode", mCurViewMode); 559 * ed.commit(); 560 * } 561 * } 562 * </pre> 563 * 564 * <a name="Permissions"></a> 565 * <h3>Permissions</h3> 566 * 567 * <p>The ability to start a particular Activity can be enforced when it is 568 * declared in its 569 * manifest's {@link android.R.styleable#AndroidManifestActivity <activity>} 570 * tag. By doing so, other applications will need to declare a corresponding 571 * {@link android.R.styleable#AndroidManifestUsesPermission <uses-permission>} 572 * element in their own manifest to be able to start that activity. 573 * 574 * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> 575 * document for more information on permissions and security in general. 576 * 577 * <a name="ProcessLifecycle"></a> 578 * <h3>Process Lifecycle</h3> 579 * 580 * <p>The Android system attempts to keep application process around for as 581 * long as possible, but eventually will need to remove old processes when 582 * memory runs low. As described in <a href="#ActivityLifecycle">Activity 583 * Lifecycle</a>, the decision about which process to remove is intimately 584 * tied to the state of the user's interaction with it. In general, there 585 * are four states a process can be in based on the activities running in it, 586 * listed here in order of importance. The system will kill less important 587 * processes (the last ones) before it resorts to killing more important 588 * processes (the first ones). 589 * 590 * <ol> 591 * <li> <p>The <b>foreground activity</b> (the activity at the top of the screen 592 * that the user is currently interacting with) is considered the most important. 593 * Its process will only be killed as a last resort, if it uses more memory 594 * than is available on the device. Generally at this point the device has 595 * reached a memory paging state, so this is required in order to keep the user 596 * interface responsive. 597 * <li> <p>A <b>visible activity</b> (an activity that is visible to the user 598 * but not in the foreground, such as one sitting behind a foreground dialog) 599 * is considered extremely important and will not be killed unless that is 600 * required to keep the foreground activity running. 601 * <li> <p>A <b>background activity</b> (an activity that is not visible to 602 * the user and has been paused) is no longer critical, so the system may 603 * safely kill its process to reclaim memory for other foreground or 604 * visible processes. If its process needs to be killed, when the user navigates 605 * back to the activity (making it visible on the screen again), its 606 * {@link #onCreate} method will be called with the savedInstanceState it had previously 607 * supplied in {@link #onSaveInstanceState} so that it can restart itself in the same 608 * state as the user last left it. 609 * <li> <p>An <b>empty process</b> is one hosting no activities or other 610 * application components (such as {@link Service} or 611 * {@link android.content.BroadcastReceiver} classes). These are killed very 612 * quickly by the system as memory becomes low. For this reason, any 613 * background operation you do outside of an activity must be executed in the 614 * context of an activity BroadcastReceiver or Service to ensure that the system 615 * knows it needs to keep your process around. 616 * </ol> 617 * 618 * <p>Sometimes an Activity may need to do a long-running operation that exists 619 * independently of the activity lifecycle itself. An example may be a camera 620 * application that allows you to upload a picture to a web site. The upload 621 * may take a long time, and the application should allow the user to leave 622 * the application will it is executing. To accomplish this, your Activity 623 * should start a {@link Service} in which the upload takes place. This allows 624 * the system to properly prioritize your process (considering it to be more 625 * important than other non-visible applications) for the duration of the 626 * upload, independent of whether the original activity is paused, stopped, 627 * or finished. 628 */ 629 public class Activity extends ContextThemeWrapper 630 implements LayoutInflater.Factory2, 631 Window.Callback, KeyEvent.Callback, 632 OnCreateContextMenuListener, ComponentCallbacks2 { 633 private static final String TAG = "Activity"; 634 635 /** Standard activity result: operation canceled. */ 636 public static final int RESULT_CANCELED = 0; 637 /** Standard activity result: operation succeeded. */ 638 public static final int RESULT_OK = -1; 639 /** Start of user-defined activity results. */ 640 public static final int RESULT_FIRST_USER = 1; 641 642 private static final String WINDOW_HIERARCHY_TAG = "android:viewHierarchyState"; 643 private static final String FRAGMENTS_TAG = "android:fragments"; 644 private static final String SAVED_DIALOG_IDS_KEY = "android:savedDialogIds"; 645 private static final String SAVED_DIALOGS_TAG = "android:savedDialogs"; 646 private static final String SAVED_DIALOG_KEY_PREFIX = "android:dialog_"; 647 private static final String SAVED_DIALOG_ARGS_KEY_PREFIX = "android:dialog_args_"; 648 649 private static class ManagedDialog { 650 Dialog mDialog; 651 Bundle mArgs; 652 } 653 private SparseArray<ManagedDialog> mManagedDialogs; 654 655 // set by the thread after the constructor and before onCreate(Bundle savedInstanceState) is called. 656 private Instrumentation mInstrumentation; 657 private IBinder mToken; 658 private int mIdent; 659 /*package*/ String mEmbeddedID; 660 private Application mApplication; 661 /*package*/ Intent mIntent; 662 private ComponentName mComponent; 663 /*package*/ ActivityInfo mActivityInfo; 664 /*package*/ ActivityThread mMainThread; 665 Activity mParent; 666 boolean mCalled; 667 boolean mCheckedForLoaderManager; 668 boolean mLoadersStarted; 669 /*package*/ boolean mResumed; 670 private boolean mStopped; 671 boolean mFinished; 672 boolean mStartedActivity; 673 /** true if the activity is going through a transient pause */ 674 /*package*/ boolean mTemporaryPause = false; 675 /** true if the activity is being destroyed in order to recreate it with a new configuration */ 676 /*package*/ boolean mChangingConfigurations = false; 677 /*package*/ int mConfigChangeFlags; 678 /*package*/ Configuration mCurrentConfig; 679 private SearchManager mSearchManager; 680 private MenuInflater mMenuInflater; 681 682 static final class NonConfigurationInstances { 683 Object activity; 684 HashMap<String, Object> children; 685 ArrayList<Fragment> fragments; 686 SparseArray<LoaderManagerImpl> loaders; 687 } 688 /* package */ NonConfigurationInstances mLastNonConfigurationInstances; 689 690 private Window mWindow; 691 692 private WindowManager mWindowManager; 693 /*package*/ View mDecor = null; 694 /*package*/ boolean mWindowAdded = false; 695 /*package*/ boolean mVisibleFromServer = false; 696 /*package*/ boolean mVisibleFromClient = true; 697 /*package*/ ActionBarImpl mActionBar = null; 698 699 private CharSequence mTitle; 700 private int mTitleColor = 0; 701 702 final FragmentManagerImpl mFragments = new FragmentManagerImpl(); 703 704 SparseArray<LoaderManagerImpl> mAllLoaderManagers; 705 LoaderManagerImpl mLoaderManager; 706 707 private static final class ManagedCursor { 708 ManagedCursor(Cursor cursor) { 709 mCursor = cursor; 710 mReleased = false; 711 mUpdated = false; 712 } 713 714 private final Cursor mCursor; 715 private boolean mReleased; 716 private boolean mUpdated; 717 } 718 private final ArrayList<ManagedCursor> mManagedCursors = 719 new ArrayList<ManagedCursor>(); 720 721 // protected by synchronized (this) 722 int mResultCode = RESULT_CANCELED; 723 Intent mResultData = null; 724 725 private boolean mTitleReady = false; 726 727 private int mDefaultKeyMode = DEFAULT_KEYS_DISABLE; 728 private SpannableStringBuilder mDefaultKeySsb = null; 729 730 protected static final int[] FOCUSED_STATE_SET = {com.android.internal.R.attr.state_focused}; 731 732 private final Object mInstanceTracker = StrictMode.trackActivity(this); 733 734 private Thread mUiThread; 735 final Handler mHandler = new Handler(); 736 737 /** Return the intent that started this activity. */ 738 public Intent getIntent() { 739 return mIntent; 740 } 741 742 /** 743 * Change the intent returned by {@link #getIntent}. This holds a 744 * reference to the given intent; it does not copy it. Often used in 745 * conjunction with {@link #onNewIntent}. 746 * 747 * @param newIntent The new Intent object to return from getIntent 748 * 749 * @see #getIntent 750 * @see #onNewIntent 751 */ 752 public void setIntent(Intent newIntent) { 753 mIntent = newIntent; 754 } 755 756 /** Return the application that owns this activity. */ 757 public final Application getApplication() { 758 return mApplication; 759 } 760 761 /** Is this activity embedded inside of another activity? */ 762 public final boolean isChild() { 763 return mParent != null; 764 } 765 766 /** Return the parent activity if this view is an embedded child. */ 767 public final Activity getParent() { 768 return mParent; 769 } 770 771 /** Retrieve the window manager for showing custom windows. */ 772 public WindowManager getWindowManager() { 773 return mWindowManager; 774 } 775 776 /** 777 * Retrieve the current {@link android.view.Window} for the activity. 778 * This can be used to directly access parts of the Window API that 779 * are not available through Activity/Screen. 780 * 781 * @return Window The current window, or null if the activity is not 782 * visual. 783 */ 784 public Window getWindow() { 785 return mWindow; 786 } 787 788 /** 789 * Return the LoaderManager for this fragment, creating it if needed. 790 */ 791 public LoaderManager getLoaderManager() { 792 if (mLoaderManager != null) { 793 return mLoaderManager; 794 } 795 mCheckedForLoaderManager = true; 796 mLoaderManager = getLoaderManager(-1, mLoadersStarted, true); 797 return mLoaderManager; 798 } 799 800 LoaderManagerImpl getLoaderManager(int index, boolean started, boolean create) { 801 if (mAllLoaderManagers == null) { 802 mAllLoaderManagers = new SparseArray<LoaderManagerImpl>(); 803 } 804 LoaderManagerImpl lm = mAllLoaderManagers.get(index); 805 if (lm == null) { 806 if (create) { 807 lm = new LoaderManagerImpl(this, started); 808 mAllLoaderManagers.put(index, lm); 809 } 810 } else { 811 lm.updateActivity(this); 812 } 813 return lm; 814 } 815 816 /** 817 * Calls {@link android.view.Window#getCurrentFocus} on the 818 * Window of this Activity to return the currently focused view. 819 * 820 * @return View The current View with focus or null. 821 * 822 * @see #getWindow 823 * @see android.view.Window#getCurrentFocus 824 */ 825 public View getCurrentFocus() { 826 return mWindow != null ? mWindow.getCurrentFocus() : null; 827 } 828 829 /** 830 * Called when the activity is starting. This is where most initialization 831 * should go: calling {@link #setContentView(int)} to inflate the 832 * activity's UI, using {@link #findViewById} to programmatically interact 833 * with widgets in the UI, calling 834 * {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve 835 * cursors for data being displayed, etc. 836 * 837 * <p>You can call {@link #finish} from within this function, in 838 * which case onDestroy() will be immediately called without any of the rest 839 * of the activity lifecycle ({@link #onStart}, {@link #onResume}, 840 * {@link #onPause}, etc) executing. 841 * 842 * <p><em>Derived classes must call through to the super class's 843 * implementation of this method. If they do not, an exception will be 844 * thrown.</em></p> 845 * 846 * @param savedInstanceState If the activity is being re-initialized after 847 * previously being shut down then this Bundle contains the data it most 848 * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b> 849 * 850 * @see #onStart 851 * @see #onSaveInstanceState 852 * @see #onRestoreInstanceState 853 * @see #onPostCreate 854 */ 855 protected void onCreate(Bundle savedInstanceState) { 856 if (mLastNonConfigurationInstances != null) { 857 mAllLoaderManagers = mLastNonConfigurationInstances.loaders; 858 } 859 if (savedInstanceState != null) { 860 Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG); 861 mFragments.restoreAllState(p, mLastNonConfigurationInstances != null 862 ? mLastNonConfigurationInstances.fragments : null); 863 } 864 mFragments.dispatchCreate(); 865 getApplication().dispatchActivityCreated(this, savedInstanceState); 866 mCalled = true; 867 } 868 869 /** 870 * The hook for {@link ActivityThread} to restore the state of this activity. 871 * 872 * Calls {@link #onSaveInstanceState(android.os.Bundle)} and 873 * {@link #restoreManagedDialogs(android.os.Bundle)}. 874 * 875 * @param savedInstanceState contains the saved state 876 */ 877 final void performRestoreInstanceState(Bundle savedInstanceState) { 878 onRestoreInstanceState(savedInstanceState); 879 restoreManagedDialogs(savedInstanceState); 880 } 881 882 /** 883 * This method is called after {@link #onStart} when the activity is 884 * being re-initialized from a previously saved state, given here in 885 * <var>savedInstanceState</var>. Most implementations will simply use {@link #onCreate} 886 * to restore their state, but it is sometimes convenient to do it here 887 * after all of the initialization has been done or to allow subclasses to 888 * decide whether to use your default implementation. The default 889 * implementation of this method performs a restore of any view state that 890 * had previously been frozen by {@link #onSaveInstanceState}. 891 * 892 * <p>This method is called between {@link #onStart} and 893 * {@link #onPostCreate}. 894 * 895 * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}. 896 * 897 * @see #onCreate 898 * @see #onPostCreate 899 * @see #onResume 900 * @see #onSaveInstanceState 901 */ 902 protected void onRestoreInstanceState(Bundle savedInstanceState) { 903 if (mWindow != null) { 904 Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG); 905 if (windowState != null) { 906 mWindow.restoreHierarchyState(windowState); 907 } 908 } 909 } 910 911 /** 912 * Restore the state of any saved managed dialogs. 913 * 914 * @param savedInstanceState The bundle to restore from. 915 */ 916 private void restoreManagedDialogs(Bundle savedInstanceState) { 917 final Bundle b = savedInstanceState.getBundle(SAVED_DIALOGS_TAG); 918 if (b == null) { 919 return; 920 } 921 922 final int[] ids = b.getIntArray(SAVED_DIALOG_IDS_KEY); 923 final int numDialogs = ids.length; 924 mManagedDialogs = new SparseArray<ManagedDialog>(numDialogs); 925 for (int i = 0; i < numDialogs; i++) { 926 final Integer dialogId = ids[i]; 927 Bundle dialogState = b.getBundle(savedDialogKeyFor(dialogId)); 928 if (dialogState != null) { 929 // Calling onRestoreInstanceState() below will invoke dispatchOnCreate 930 // so tell createDialog() not to do it, otherwise we get an exception 931 final ManagedDialog md = new ManagedDialog(); 932 md.mArgs = b.getBundle(savedDialogArgsKeyFor(dialogId)); 933 md.mDialog = createDialog(dialogId, dialogState, md.mArgs); 934 if (md.mDialog != null) { 935 mManagedDialogs.put(dialogId, md); 936 onPrepareDialog(dialogId, md.mDialog, md.mArgs); 937 md.mDialog.onRestoreInstanceState(dialogState); 938 } 939 } 940 } 941 } 942 943 private Dialog createDialog(Integer dialogId, Bundle state, Bundle args) { 944 final Dialog dialog = onCreateDialog(dialogId, args); 945 if (dialog == null) { 946 return null; 947 } 948 dialog.dispatchOnCreate(state); 949 return dialog; 950 } 951 952 private static String savedDialogKeyFor(int key) { 953 return SAVED_DIALOG_KEY_PREFIX + key; 954 } 955 956 private static String savedDialogArgsKeyFor(int key) { 957 return SAVED_DIALOG_ARGS_KEY_PREFIX + key; 958 } 959 960 /** 961 * Called when activity start-up is complete (after {@link #onStart} 962 * and {@link #onRestoreInstanceState} have been called). Applications will 963 * generally not implement this method; it is intended for system 964 * classes to do final initialization after application code has run. 965 * 966 * <p><em>Derived classes must call through to the super class's 967 * implementation of this method. If they do not, an exception will be 968 * thrown.</em></p> 969 * 970 * @param savedInstanceState If the activity is being re-initialized after 971 * previously being shut down then this Bundle contains the data it most 972 * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b> 973 * @see #onCreate 974 */ 975 protected void onPostCreate(Bundle savedInstanceState) { 976 if (!isChild()) { 977 mTitleReady = true; 978 onTitleChanged(getTitle(), getTitleColor()); 979 } 980 mCalled = true; 981 } 982 983 /** 984 * Called after {@link #onCreate} — or after {@link #onRestart} when 985 * the activity had been stopped, but is now again being displayed to the 986 * user. It will be followed by {@link #onResume}. 987 * 988 * <p><em>Derived classes must call through to the super class's 989 * implementation of this method. If they do not, an exception will be 990 * thrown.</em></p> 991 * 992 * @see #onCreate 993 * @see #onStop 994 * @see #onResume 995 */ 996 protected void onStart() { 997 mCalled = true; 998 999 if (!mLoadersStarted) { 1000 mLoadersStarted = true; 1001 if (mLoaderManager != null) { 1002 mLoaderManager.doStart(); 1003 } else if (!mCheckedForLoaderManager) { 1004 mLoaderManager = getLoaderManager(-1, mLoadersStarted, false); 1005 } 1006 mCheckedForLoaderManager = true; 1007 } 1008 1009 getApplication().dispatchActivityStarted(this); 1010 } 1011 1012 /** 1013 * Called after {@link #onStop} when the current activity is being 1014 * re-displayed to the user (the user has navigated back to it). It will 1015 * be followed by {@link #onStart} and then {@link #onResume}. 1016 * 1017 * <p>For activities that are using raw {@link Cursor} objects (instead of 1018 * creating them through 1019 * {@link #managedQuery(android.net.Uri , String[], String, String[], String)}, 1020 * this is usually the place 1021 * where the cursor should be requeried (because you had deactivated it in 1022 * {@link #onStop}. 1023 * 1024 * <p><em>Derived classes must call through to the super class's 1025 * implementation of this method. If they do not, an exception will be 1026 * thrown.</em></p> 1027 * 1028 * @see #onStop 1029 * @see #onStart 1030 * @see #onResume 1031 */ 1032 protected void onRestart() { 1033 mCalled = true; 1034 } 1035 1036 /** 1037 * Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or 1038 * {@link #onPause}, for your activity to start interacting with the user. 1039 * This is a good place to begin animations, open exclusive-access devices 1040 * (such as the camera), etc. 1041 * 1042 * <p>Keep in mind that onResume is not the best indicator that your activity 1043 * is visible to the user; a system window such as the keyguard may be in 1044 * front. Use {@link #onWindowFocusChanged} to know for certain that your 1045 * activity is visible to the user (for example, to resume a game). 1046 * 1047 * <p><em>Derived classes must call through to the super class's 1048 * implementation of this method. If they do not, an exception will be 1049 * thrown.</em></p> 1050 * 1051 * @see #onRestoreInstanceState 1052 * @see #onRestart 1053 * @see #onPostResume 1054 * @see #onPause 1055 */ 1056 protected void onResume() { 1057 getApplication().dispatchActivityResumed(this); 1058 mCalled = true; 1059 } 1060 1061 /** 1062 * Called when activity resume is complete (after {@link #onResume} has 1063 * been called). Applications will generally not implement this method; 1064 * it is intended for system classes to do final setup after application 1065 * resume code has run. 1066 * 1067 * <p><em>Derived classes must call through to the super class's 1068 * implementation of this method. If they do not, an exception will be 1069 * thrown.</em></p> 1070 * 1071 * @see #onResume 1072 */ 1073 protected void onPostResume() { 1074 final Window win = getWindow(); 1075 if (win != null) win.makeActive(); 1076 if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(true); 1077 mCalled = true; 1078 } 1079 1080 /** 1081 * This is called for activities that set launchMode to "singleTop" in 1082 * their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} 1083 * flag when calling {@link #startActivity}. In either case, when the 1084 * activity is re-launched while at the top of the activity stack instead 1085 * of a new instance of the activity being started, onNewIntent() will be 1086 * called on the existing instance with the Intent that was used to 1087 * re-launch it. 1088 * 1089 * <p>An activity will always be paused before receiving a new intent, so 1090 * you can count on {@link #onResume} being called after this method. 1091 * 1092 * <p>Note that {@link #getIntent} still returns the original Intent. You 1093 * can use {@link #setIntent} to update it to this new Intent. 1094 * 1095 * @param intent The new intent that was started for the activity. 1096 * 1097 * @see #getIntent 1098 * @see #setIntent 1099 * @see #onResume 1100 */ 1101 protected void onNewIntent(Intent intent) { 1102 } 1103 1104 /** 1105 * The hook for {@link ActivityThread} to save the state of this activity. 1106 * 1107 * Calls {@link #onSaveInstanceState(android.os.Bundle)} 1108 * and {@link #saveManagedDialogs(android.os.Bundle)}. 1109 * 1110 * @param outState The bundle to save the state to. 1111 */ 1112 final void performSaveInstanceState(Bundle outState) { 1113 onSaveInstanceState(outState); 1114 saveManagedDialogs(outState); 1115 } 1116 1117 /** 1118 * Called to retrieve per-instance state from an activity before being killed 1119 * so that the state can be restored in {@link #onCreate} or 1120 * {@link #onRestoreInstanceState} (the {@link Bundle} populated by this method 1121 * will be passed to both). 1122 * 1123 * <p>This method is called before an activity may be killed so that when it 1124 * comes back some time in the future it can restore its state. For example, 1125 * if activity B is launched in front of activity A, and at some point activity 1126 * A is killed to reclaim resources, activity A will have a chance to save the 1127 * current state of its user interface via this method so that when the user 1128 * returns to activity A, the state of the user interface can be restored 1129 * via {@link #onCreate} or {@link #onRestoreInstanceState}. 1130 * 1131 * <p>Do not confuse this method with activity lifecycle callbacks such as 1132 * {@link #onPause}, which is always called when an activity is being placed 1133 * in the background or on its way to destruction, or {@link #onStop} which 1134 * is called before destruction. One example of when {@link #onPause} and 1135 * {@link #onStop} is called and not this method is when a user navigates back 1136 * from activity B to activity A: there is no need to call {@link #onSaveInstanceState} 1137 * on B because that particular instance will never be restored, so the 1138 * system avoids calling it. An example when {@link #onPause} is called and 1139 * not {@link #onSaveInstanceState} is when activity B is launched in front of activity A: 1140 * the system may avoid calling {@link #onSaveInstanceState} on activity A if it isn't 1141 * killed during the lifetime of B since the state of the user interface of 1142 * A will stay intact. 1143 * 1144 * <p>The default implementation takes care of most of the UI per-instance 1145 * state for you by calling {@link android.view.View#onSaveInstanceState()} on each 1146 * view in the hierarchy that has an id, and by saving the id of the currently 1147 * focused view (all of which is restored by the default implementation of 1148 * {@link #onRestoreInstanceState}). If you override this method to save additional 1149 * information not captured by each individual view, you will likely want to 1150 * call through to the default implementation, otherwise be prepared to save 1151 * all of the state of each view yourself. 1152 * 1153 * <p>If called, this method will occur before {@link #onStop}. There are 1154 * no guarantees about whether it will occur before or after {@link #onPause}. 1155 * 1156 * @param outState Bundle in which to place your saved state. 1157 * 1158 * @see #onCreate 1159 * @see #onRestoreInstanceState 1160 * @see #onPause 1161 */ 1162 protected void onSaveInstanceState(Bundle outState) { 1163 outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState()); 1164 Parcelable p = mFragments.saveAllState(); 1165 if (p != null) { 1166 outState.putParcelable(FRAGMENTS_TAG, p); 1167 } 1168 getApplication().dispatchActivitySaveInstanceState(this, outState); 1169 } 1170 1171 /** 1172 * Save the state of any managed dialogs. 1173 * 1174 * @param outState place to store the saved state. 1175 */ 1176 private void saveManagedDialogs(Bundle outState) { 1177 if (mManagedDialogs == null) { 1178 return; 1179 } 1180 1181 final int numDialogs = mManagedDialogs.size(); 1182 if (numDialogs == 0) { 1183 return; 1184 } 1185 1186 Bundle dialogState = new Bundle(); 1187 1188 int[] ids = new int[mManagedDialogs.size()]; 1189 1190 // save each dialog's bundle, gather the ids 1191 for (int i = 0; i < numDialogs; i++) { 1192 final int key = mManagedDialogs.keyAt(i); 1193 ids[i] = key; 1194 final ManagedDialog md = mManagedDialogs.valueAt(i); 1195 dialogState.putBundle(savedDialogKeyFor(key), md.mDialog.onSaveInstanceState()); 1196 if (md.mArgs != null) { 1197 dialogState.putBundle(savedDialogArgsKeyFor(key), md.mArgs); 1198 } 1199 } 1200 1201 dialogState.putIntArray(SAVED_DIALOG_IDS_KEY, ids); 1202 outState.putBundle(SAVED_DIALOGS_TAG, dialogState); 1203 } 1204 1205 1206 /** 1207 * Called as part of the activity lifecycle when an activity is going into 1208 * the background, but has not (yet) been killed. The counterpart to 1209 * {@link #onResume}. 1210 * 1211 * <p>When activity B is launched in front of activity A, this callback will 1212 * be invoked on A. B will not be created until A's {@link #onPause} returns, 1213 * so be sure to not do anything lengthy here. 1214 * 1215 * <p>This callback is mostly used for saving any persistent state the 1216 * activity is editing, to present a "edit in place" model to the user and 1217 * making sure nothing is lost if there are not enough resources to start 1218 * the new activity without first killing this one. This is also a good 1219 * place to do things like stop animations and other things that consume a 1220 * noticeable mount of CPU in order to make the switch to the next activity 1221 * as fast as possible, or to close resources that are exclusive access 1222 * such as the camera. 1223 * 1224 * <p>In situations where the system needs more memory it may kill paused 1225 * processes to reclaim resources. Because of this, you should be sure 1226 * that all of your state is saved by the time you return from 1227 * this function. In general {@link #onSaveInstanceState} is used to save 1228 * per-instance state in the activity and this method is used to store 1229 * global persistent data (in content providers, files, etc.) 1230 * 1231 * <p>After receiving this call you will usually receive a following call 1232 * to {@link #onStop} (after the next activity has been resumed and 1233 * displayed), however in some cases there will be a direct call back to 1234 * {@link #onResume} without going through the stopped state. 1235 * 1236 * <p><em>Derived classes must call through to the super class's 1237 * implementation of this method. If they do not, an exception will be 1238 * thrown.</em></p> 1239 * 1240 * @see #onResume 1241 * @see #onSaveInstanceState 1242 * @see #onStop 1243 */ 1244 protected void onPause() { 1245 getApplication().dispatchActivityPaused(this); 1246 mCalled = true; 1247 } 1248 1249 /** 1250 * Called as part of the activity lifecycle when an activity is about to go 1251 * into the background as the result of user choice. For example, when the 1252 * user presses the Home key, {@link #onUserLeaveHint} will be called, but 1253 * when an incoming phone call causes the in-call Activity to be automatically 1254 * brought to the foreground, {@link #onUserLeaveHint} will not be called on 1255 * the activity being interrupted. In cases when it is invoked, this method 1256 * is called right before the activity's {@link #onPause} callback. 1257 * 1258 * <p>This callback and {@link #onUserInteraction} are intended to help 1259 * activities manage status bar notifications intelligently; specifically, 1260 * for helping activities determine the proper time to cancel a notfication. 1261 * 1262 * @see #onUserInteraction() 1263 */ 1264 protected void onUserLeaveHint() { 1265 } 1266 1267 /** 1268 * Generate a new thumbnail for this activity. This method is called before 1269 * pausing the activity, and should draw into <var>outBitmap</var> the 1270 * imagery for the desired thumbnail in the dimensions of that bitmap. It 1271 * can use the given <var>canvas</var>, which is configured to draw into the 1272 * bitmap, for rendering if desired. 1273 * 1274 * <p>The default implementation returns fails and does not draw a thumbnail; 1275 * this will result in the platform creating its own thumbnail if needed. 1276 * 1277 * @param outBitmap The bitmap to contain the thumbnail. 1278 * @param canvas Can be used to render into the bitmap. 1279 * 1280 * @return Return true if you have drawn into the bitmap; otherwise after 1281 * you return it will be filled with a default thumbnail. 1282 * 1283 * @see #onCreateDescription 1284 * @see #onSaveInstanceState 1285 * @see #onPause 1286 */ 1287 public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) { 1288 return false; 1289 } 1290 1291 /** 1292 * Generate a new description for this activity. This method is called 1293 * before pausing the activity and can, if desired, return some textual 1294 * description of its current state to be displayed to the user. 1295 * 1296 * <p>The default implementation returns null, which will cause you to 1297 * inherit the description from the previous activity. If all activities 1298 * return null, generally the label of the top activity will be used as the 1299 * description. 1300 * 1301 * @return A description of what the user is doing. It should be short and 1302 * sweet (only a few words). 1303 * 1304 * @see #onCreateThumbnail 1305 * @see #onSaveInstanceState 1306 * @see #onPause 1307 */ 1308 public CharSequence onCreateDescription() { 1309 return null; 1310 } 1311 1312 /** 1313 * Called when you are no longer visible to the user. You will next 1314 * receive either {@link #onRestart}, {@link #onDestroy}, or nothing, 1315 * depending on later user activity. 1316 * 1317 * <p>Note that this method may never be called, in low memory situations 1318 * where the system does not have enough memory to keep your activity's 1319 * process running after its {@link #onPause} method is called. 1320 * 1321 * <p><em>Derived classes must call through to the super class's 1322 * implementation of this method. If they do not, an exception will be 1323 * thrown.</em></p> 1324 * 1325 * @see #onRestart 1326 * @see #onResume 1327 * @see #onSaveInstanceState 1328 * @see #onDestroy 1329 */ 1330 protected void onStop() { 1331 if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false); 1332 getApplication().dispatchActivityStopped(this); 1333 mCalled = true; 1334 } 1335 1336 /** 1337 * Perform any final cleanup before an activity is destroyed. This can 1338 * happen either because the activity is finishing (someone called 1339 * {@link #finish} on it, or because the system is temporarily destroying 1340 * this instance of the activity to save space. You can distinguish 1341 * between these two scenarios with the {@link #isFinishing} method. 1342 * 1343 * <p><em>Note: do not count on this method being called as a place for 1344 * saving data! For example, if an activity is editing data in a content 1345 * provider, those edits should be committed in either {@link #onPause} or 1346 * {@link #onSaveInstanceState}, not here.</em> This method is usually implemented to 1347 * free resources like threads that are associated with an activity, so 1348 * that a destroyed activity does not leave such things around while the 1349 * rest of its application is still running. There are situations where 1350 * the system will simply kill the activity's hosting process without 1351 * calling this method (or any others) in it, so it should not be used to 1352 * do things that are intended to remain around after the process goes 1353 * away. 1354 * 1355 * <p><em>Derived classes must call through to the super class's 1356 * implementation of this method. If they do not, an exception will be 1357 * thrown.</em></p> 1358 * 1359 * @see #onPause 1360 * @see #onStop 1361 * @see #finish 1362 * @see #isFinishing 1363 */ 1364 protected void onDestroy() { 1365 mCalled = true; 1366 1367 // dismiss any dialogs we are managing. 1368 if (mManagedDialogs != null) { 1369 final int numDialogs = mManagedDialogs.size(); 1370 for (int i = 0; i < numDialogs; i++) { 1371 final ManagedDialog md = mManagedDialogs.valueAt(i); 1372 if (md.mDialog.isShowing()) { 1373 md.mDialog.dismiss(); 1374 } 1375 } 1376 mManagedDialogs = null; 1377 } 1378 1379 // close any cursors we are managing. 1380 synchronized (mManagedCursors) { 1381 int numCursors = mManagedCursors.size(); 1382 for (int i = 0; i < numCursors; i++) { 1383 ManagedCursor c = mManagedCursors.get(i); 1384 if (c != null) { 1385 c.mCursor.close(); 1386 } 1387 } 1388 mManagedCursors.clear(); 1389 } 1390 1391 // Close any open search dialog 1392 if (mSearchManager != null) { 1393 mSearchManager.stopSearch(); 1394 } 1395 1396 getApplication().dispatchActivityDestroyed(this); 1397 } 1398 1399 /** 1400 * Called by the system when the device configuration changes while your 1401 * activity is running. Note that this will <em>only</em> be called if 1402 * you have selected configurations you would like to handle with the 1403 * {@link android.R.attr#configChanges} attribute in your manifest. If 1404 * any configuration change occurs that is not selected to be reported 1405 * by that attribute, then instead of reporting it the system will stop 1406 * and restart the activity (to have it launched with the new 1407 * configuration). 1408 * 1409 * <p>At the time that this function has been called, your Resources 1410 * object will have been updated to return resource values matching the 1411 * new configuration. 1412 * 1413 * @param newConfig The new device configuration. 1414 */ 1415 public void onConfigurationChanged(Configuration newConfig) { 1416 mCalled = true; 1417 1418 mFragments.dispatchConfigurationChanged(newConfig); 1419 1420 if (mWindow != null) { 1421 // Pass the configuration changed event to the window 1422 mWindow.onConfigurationChanged(newConfig); 1423 } 1424 1425 if (mActionBar != null) { 1426 // Do this last; the action bar will need to access 1427 // view changes from above. 1428 mActionBar.onConfigurationChanged(newConfig); 1429 } 1430 } 1431 1432 /** 1433 * If this activity is being destroyed because it can not handle a 1434 * configuration parameter being changed (and thus its 1435 * {@link #onConfigurationChanged(Configuration)} method is 1436 * <em>not</em> being called), then you can use this method to discover 1437 * the set of changes that have occurred while in the process of being 1438 * destroyed. Note that there is no guarantee that these will be 1439 * accurate (other changes could have happened at any time), so you should 1440 * only use this as an optimization hint. 1441 * 1442 * @return Returns a bit field of the configuration parameters that are 1443 * changing, as defined by the {@link android.content.res.Configuration} 1444 * class. 1445 */ 1446 public int getChangingConfigurations() { 1447 return mConfigChangeFlags; 1448 } 1449 1450 /** 1451 * Retrieve the non-configuration instance data that was previously 1452 * returned by {@link #onRetainNonConfigurationInstance()}. This will 1453 * be available from the initial {@link #onCreate} and 1454 * {@link #onStart} calls to the new instance, allowing you to extract 1455 * any useful dynamic state from the previous instance. 1456 * 1457 * <p>Note that the data you retrieve here should <em>only</em> be used 1458 * as an optimization for handling configuration changes. You should always 1459 * be able to handle getting a null pointer back, and an activity must 1460 * still be able to restore itself to its previous state (through the 1461 * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this 1462 * function returns null. 1463 * 1464 * @return Returns the object previously returned by 1465 * {@link #onRetainNonConfigurationInstance()}. 1466 * 1467 * @deprecated Use the new {@link Fragment} API 1468 * {@link Fragment#setRetainInstance(boolean)} instead; this is also 1469 * available on older platforms through the Android compatibility package. 1470 */ 1471 @Deprecated 1472 public Object getLastNonConfigurationInstance() { 1473 return mLastNonConfigurationInstances != null 1474 ? mLastNonConfigurationInstances.activity : null; 1475 } 1476 1477 /** 1478 * Called by the system, as part of destroying an 1479 * activity due to a configuration change, when it is known that a new 1480 * instance will immediately be created for the new configuration. You 1481 * can return any object you like here, including the activity instance 1482 * itself, which can later be retrieved by calling 1483 * {@link #getLastNonConfigurationInstance()} in the new activity 1484 * instance. 1485 * 1486 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1487 * or later, consider instead using a {@link Fragment} with 1488 * {@link Fragment#setRetainInstance(boolean) 1489 * Fragment.setRetainInstance(boolean}.</em> 1490 * 1491 * <p>This function is called purely as an optimization, and you must 1492 * not rely on it being called. When it is called, a number of guarantees 1493 * will be made to help optimize configuration switching: 1494 * <ul> 1495 * <li> The function will be called between {@link #onStop} and 1496 * {@link #onDestroy}. 1497 * <li> A new instance of the activity will <em>always</em> be immediately 1498 * created after this one's {@link #onDestroy()} is called. In particular, 1499 * <em>no</em> messages will be dispatched during this time (when the returned 1500 * object does not have an activity to be associated with). 1501 * <li> The object you return here will <em>always</em> be available from 1502 * the {@link #getLastNonConfigurationInstance()} method of the following 1503 * activity instance as described there. 1504 * </ul> 1505 * 1506 * <p>These guarantees are designed so that an activity can use this API 1507 * to propagate extensive state from the old to new activity instance, from 1508 * loaded bitmaps, to network connections, to evenly actively running 1509 * threads. Note that you should <em>not</em> propagate any data that 1510 * may change based on the configuration, including any data loaded from 1511 * resources such as strings, layouts, or drawables. 1512 * 1513 * <p>The guarantee of no message handling during the switch to the next 1514 * activity simplifies use with active objects. For example if your retained 1515 * state is an {@link android.os.AsyncTask} you are guaranteed that its 1516 * call back functions (like {@link android.os.AsyncTask#onPostExecute}) will 1517 * not be called from the call here until you execute the next instance's 1518 * {@link #onCreate(Bundle)}. (Note however that there is of course no such 1519 * guarantee for {@link android.os.AsyncTask#doInBackground} since that is 1520 * running in a separate thread.) 1521 * 1522 * @return Return any Object holding the desired state to propagate to the 1523 * next activity instance. 1524 * 1525 * @deprecated Use the new {@link Fragment} API 1526 * {@link Fragment#setRetainInstance(boolean)} instead; this is also 1527 * available on older platforms through the Android compatibility package. 1528 */ 1529 public Object onRetainNonConfigurationInstance() { 1530 return null; 1531 } 1532 1533 /** 1534 * Retrieve the non-configuration instance data that was previously 1535 * returned by {@link #onRetainNonConfigurationChildInstances()}. This will 1536 * be available from the initial {@link #onCreate} and 1537 * {@link #onStart} calls to the new instance, allowing you to extract 1538 * any useful dynamic state from the previous instance. 1539 * 1540 * <p>Note that the data you retrieve here should <em>only</em> be used 1541 * as an optimization for handling configuration changes. You should always 1542 * be able to handle getting a null pointer back, and an activity must 1543 * still be able to restore itself to its previous state (through the 1544 * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this 1545 * function returns null. 1546 * 1547 * @return Returns the object previously returned by 1548 * {@link #onRetainNonConfigurationChildInstances()} 1549 */ 1550 HashMap<String, Object> getLastNonConfigurationChildInstances() { 1551 return mLastNonConfigurationInstances != null 1552 ? mLastNonConfigurationInstances.children : null; 1553 } 1554 1555 /** 1556 * This method is similar to {@link #onRetainNonConfigurationInstance()} except that 1557 * it should return either a mapping from child activity id strings to arbitrary objects, 1558 * or null. This method is intended to be used by Activity framework subclasses that control a 1559 * set of child activities, such as ActivityGroup. The same guarantees and restrictions apply 1560 * as for {@link #onRetainNonConfigurationInstance()}. The default implementation returns null. 1561 */ 1562 HashMap<String,Object> onRetainNonConfigurationChildInstances() { 1563 return null; 1564 } 1565 1566 NonConfigurationInstances retainNonConfigurationInstances() { 1567 Object activity = onRetainNonConfigurationInstance(); 1568 HashMap<String, Object> children = onRetainNonConfigurationChildInstances(); 1569 ArrayList<Fragment> fragments = mFragments.retainNonConfig(); 1570 boolean retainLoaders = false; 1571 if (mAllLoaderManagers != null) { 1572 // prune out any loader managers that were already stopped and so 1573 // have nothing useful to retain. 1574 for (int i=mAllLoaderManagers.size()-1; i>=0; i--) { 1575 LoaderManagerImpl lm = mAllLoaderManagers.valueAt(i); 1576 if (lm.mRetaining) { 1577 retainLoaders = true; 1578 } else { 1579 lm.doDestroy(); 1580 mAllLoaderManagers.removeAt(i); 1581 } 1582 } 1583 } 1584 if (activity == null && children == null && fragments == null && !retainLoaders) { 1585 return null; 1586 } 1587 1588 NonConfigurationInstances nci = new NonConfigurationInstances(); 1589 nci.activity = activity; 1590 nci.children = children; 1591 nci.fragments = fragments; 1592 nci.loaders = mAllLoaderManagers; 1593 return nci; 1594 } 1595 1596 public void onLowMemory() { 1597 mCalled = true; 1598 mFragments.dispatchLowMemory(); 1599 } 1600 1601 public void onTrimMemory(int level) { 1602 mCalled = true; 1603 mFragments.dispatchTrimMemory(level); 1604 } 1605 1606 /** 1607 * Return the FragmentManager for interacting with fragments associated 1608 * with this activity. 1609 */ 1610 public FragmentManager getFragmentManager() { 1611 return mFragments; 1612 } 1613 1614 void invalidateFragmentIndex(int index) { 1615 //Log.v(TAG, "invalidateFragmentIndex: index=" + index); 1616 if (mAllLoaderManagers != null) { 1617 LoaderManagerImpl lm = mAllLoaderManagers.get(index); 1618 if (lm != null && !lm.mRetaining) { 1619 lm.doDestroy(); 1620 mAllLoaderManagers.remove(index); 1621 } 1622 } 1623 } 1624 1625 /** 1626 * Called when a Fragment is being attached to this activity, immediately 1627 * after the call to its {@link Fragment#onAttach Fragment.onAttach()} 1628 * method and before {@link Fragment#onCreate Fragment.onCreate()}. 1629 */ 1630 public void onAttachFragment(Fragment fragment) { 1631 } 1632 1633 /** 1634 * Wrapper around 1635 * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)} 1636 * that gives the resulting {@link Cursor} to call 1637 * {@link #startManagingCursor} so that the activity will manage its 1638 * lifecycle for you. 1639 * 1640 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1641 * or later, consider instead using {@link LoaderManager} instead, available 1642 * via {@link #getLoaderManager()}.</em> 1643 * 1644 * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on a cursor obtained using 1645 * this method, because the activity will do that for you at the appropriate time. However, if 1646 * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will 1647 * not</em> automatically close the cursor and, in that case, you must call 1648 * {@link Cursor#close()}.</p> 1649 * 1650 * @param uri The URI of the content provider to query. 1651 * @param projection List of columns to return. 1652 * @param selection SQL WHERE clause. 1653 * @param sortOrder SQL ORDER BY clause. 1654 * 1655 * @return The Cursor that was returned by query(). 1656 * 1657 * @see ContentResolver#query(android.net.Uri , String[], String, String[], String) 1658 * @see #startManagingCursor 1659 * @hide 1660 * 1661 * @deprecated Use {@link CursorLoader} instead. 1662 */ 1663 @Deprecated 1664 public final Cursor managedQuery(Uri uri, String[] projection, String selection, 1665 String sortOrder) { 1666 Cursor c = getContentResolver().query(uri, projection, selection, null, sortOrder); 1667 if (c != null) { 1668 startManagingCursor(c); 1669 } 1670 return c; 1671 } 1672 1673 /** 1674 * Wrapper around 1675 * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)} 1676 * that gives the resulting {@link Cursor} to call 1677 * {@link #startManagingCursor} so that the activity will manage its 1678 * lifecycle for you. 1679 * 1680 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1681 * or later, consider instead using {@link LoaderManager} instead, available 1682 * via {@link #getLoaderManager()}.</em> 1683 * 1684 * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on a cursor obtained using 1685 * this method, because the activity will do that for you at the appropriate time. However, if 1686 * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will 1687 * not</em> automatically close the cursor and, in that case, you must call 1688 * {@link Cursor#close()}.</p> 1689 * 1690 * @param uri The URI of the content provider to query. 1691 * @param projection List of columns to return. 1692 * @param selection SQL WHERE clause. 1693 * @param selectionArgs The arguments to selection, if any ?s are pesent 1694 * @param sortOrder SQL ORDER BY clause. 1695 * 1696 * @return The Cursor that was returned by query(). 1697 * 1698 * @see ContentResolver#query(android.net.Uri , String[], String, String[], String) 1699 * @see #startManagingCursor 1700 * 1701 * @deprecated Use {@link CursorLoader} instead. 1702 */ 1703 @Deprecated 1704 public final Cursor managedQuery(Uri uri, String[] projection, String selection, 1705 String[] selectionArgs, String sortOrder) { 1706 Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); 1707 if (c != null) { 1708 startManagingCursor(c); 1709 } 1710 return c; 1711 } 1712 1713 /** 1714 * This method allows the activity to take care of managing the given 1715 * {@link Cursor}'s lifecycle for you based on the activity's lifecycle. 1716 * That is, when the activity is stopped it will automatically call 1717 * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted 1718 * it will call {@link Cursor#requery} for you. When the activity is 1719 * destroyed, all managed Cursors will be closed automatically. 1720 * 1721 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1722 * or later, consider instead using {@link LoaderManager} instead, available 1723 * via {@link #getLoaderManager()}.</em> 1724 * 1725 * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on cursor obtained from 1726 * {@link #managedQuery}, because the activity will do that for you at the appropriate time. 1727 * However, if you call {@link #stopManagingCursor} on a cursor from a managed query, the system 1728 * <em>will not</em> automatically close the cursor and, in that case, you must call 1729 * {@link Cursor#close()}.</p> 1730 * 1731 * @param c The Cursor to be managed. 1732 * 1733 * @see #managedQuery(android.net.Uri , String[], String, String[], String) 1734 * @see #stopManagingCursor 1735 * 1736 * @deprecated Use the new {@link android.content.CursorLoader} class with 1737 * {@link LoaderManager} instead; this is also 1738 * available on older platforms through the Android compatibility package. 1739 */ 1740 @Deprecated 1741 public void startManagingCursor(Cursor c) { 1742 synchronized (mManagedCursors) { 1743 mManagedCursors.add(new ManagedCursor(c)); 1744 } 1745 } 1746 1747 /** 1748 * Given a Cursor that was previously given to 1749 * {@link #startManagingCursor}, stop the activity's management of that 1750 * cursor. 1751 * 1752 * <p><strong>Warning:</strong> After calling this method on a cursor from a managed query, 1753 * the system <em>will not</em> automatically close the cursor and you must call 1754 * {@link Cursor#close()}.</p> 1755 * 1756 * @param c The Cursor that was being managed. 1757 * 1758 * @see #startManagingCursor 1759 * 1760 * @deprecated Use the new {@link android.content.CursorLoader} class with 1761 * {@link LoaderManager} instead; this is also 1762 * available on older platforms through the Android compatibility package. 1763 */ 1764 @Deprecated 1765 public void stopManagingCursor(Cursor c) { 1766 synchronized (mManagedCursors) { 1767 final int N = mManagedCursors.size(); 1768 for (int i=0; i<N; i++) { 1769 ManagedCursor mc = mManagedCursors.get(i); 1770 if (mc.mCursor == c) { 1771 mManagedCursors.remove(i); 1772 break; 1773 } 1774 } 1775 } 1776 } 1777 1778 /** 1779 * @deprecated As of {@link android.os.Build.VERSION_CODES#GINGERBREAD} 1780 * this is a no-op. 1781 * @hide 1782 */ 1783 @Deprecated 1784 public void setPersistent(boolean isPersistent) { 1785 } 1786 1787 /** 1788 * Finds a view that was identified by the id attribute from the XML that 1789 * was processed in {@link #onCreate}. 1790 * 1791 * @return The view if found or null otherwise. 1792 */ 1793 public View findViewById(int id) { 1794 return getWindow().findViewById(id); 1795 } 1796 1797 /** 1798 * Retrieve a reference to this activity's ActionBar. 1799 * 1800 * @return The Activity's ActionBar, or null if it does not have one. 1801 */ 1802 public ActionBar getActionBar() { 1803 initActionBar(); 1804 return mActionBar; 1805 } 1806 1807 /** 1808 * Creates a new ActionBar, locates the inflated ActionBarView, 1809 * initializes the ActionBar with the view, and sets mActionBar. 1810 */ 1811 private void initActionBar() { 1812 Window window = getWindow(); 1813 1814 // Initializing the window decor can change window feature flags. 1815 // Make sure that we have the correct set before performing the test below. 1816 window.getDecorView(); 1817 1818 if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) { 1819 return; 1820 } 1821 1822 mActionBar = new ActionBarImpl(this); 1823 } 1824 1825 /** 1826 * Set the activity content from a layout resource. The resource will be 1827 * inflated, adding all top-level views to the activity. 1828 * 1829 * @param layoutResID Resource ID to be inflated. 1830 * 1831 * @see #setContentView(android.view.View) 1832 * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) 1833 */ 1834 public void setContentView(int layoutResID) { 1835 getWindow().setContentView(layoutResID); 1836 initActionBar(); 1837 } 1838 1839 /** 1840 * Set the activity content to an explicit view. This view is placed 1841 * directly into the activity's view hierarchy. It can itself be a complex 1842 * view hierarchy. When calling this method, the layout parameters of the 1843 * specified view are ignored. Both the width and the height of the view are 1844 * set by default to {@link ViewGroup.LayoutParams#MATCH_PARENT}. To use 1845 * your own layout parameters, invoke 1846 * {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)} 1847 * instead. 1848 * 1849 * @param view The desired content to display. 1850 * 1851 * @see #setContentView(int) 1852 * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) 1853 */ 1854 public void setContentView(View view) { 1855 getWindow().setContentView(view); 1856 initActionBar(); 1857 } 1858 1859 /** 1860 * Set the activity content to an explicit view. This view is placed 1861 * directly into the activity's view hierarchy. It can itself be a complex 1862 * view hierarchy. 1863 * 1864 * @param view The desired content to display. 1865 * @param params Layout parameters for the view. 1866 * 1867 * @see #setContentView(android.view.View) 1868 * @see #setContentView(int) 1869 */ 1870 public void setContentView(View view, ViewGroup.LayoutParams params) { 1871 getWindow().setContentView(view, params); 1872 initActionBar(); 1873 } 1874 1875 /** 1876 * Add an additional content view to the activity. Added after any existing 1877 * ones in the activity -- existing views are NOT removed. 1878 * 1879 * @param view The desired content to display. 1880 * @param params Layout parameters for the view. 1881 */ 1882 public void addContentView(View view, ViewGroup.LayoutParams params) { 1883 getWindow().addContentView(view, params); 1884 initActionBar(); 1885 } 1886 1887 /** 1888 * Sets whether this activity is finished when touched outside its window's 1889 * bounds. 1890 */ 1891 public void setFinishOnTouchOutside(boolean finish) { 1892 mWindow.setCloseOnTouchOutside(finish); 1893 } 1894 1895 /** 1896 * Use with {@link #setDefaultKeyMode} to turn off default handling of 1897 * keys. 1898 * 1899 * @see #setDefaultKeyMode 1900 */ 1901 static public final int DEFAULT_KEYS_DISABLE = 0; 1902 /** 1903 * Use with {@link #setDefaultKeyMode} to launch the dialer during default 1904 * key handling. 1905 * 1906 * @see #setDefaultKeyMode 1907 */ 1908 static public final int DEFAULT_KEYS_DIALER = 1; 1909 /** 1910 * Use with {@link #setDefaultKeyMode} to execute a menu shortcut in 1911 * default key handling. 1912 * 1913 * <p>That is, the user does not need to hold down the menu key to execute menu shortcuts. 1914 * 1915 * @see #setDefaultKeyMode 1916 */ 1917 static public final int DEFAULT_KEYS_SHORTCUT = 2; 1918 /** 1919 * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes 1920 * will start an application-defined search. (If the application or activity does not 1921 * actually define a search, the the keys will be ignored.) 1922 * 1923 * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details. 1924 * 1925 * @see #setDefaultKeyMode 1926 */ 1927 static public final int DEFAULT_KEYS_SEARCH_LOCAL = 3; 1928 1929 /** 1930 * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes 1931 * will start a global search (typically web search, but some platforms may define alternate 1932 * methods for global search) 1933 * 1934 * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details. 1935 * 1936 * @see #setDefaultKeyMode 1937 */ 1938 static public final int DEFAULT_KEYS_SEARCH_GLOBAL = 4; 1939 1940 /** 1941 * Select the default key handling for this activity. This controls what 1942 * will happen to key events that are not otherwise handled. The default 1943 * mode ({@link #DEFAULT_KEYS_DISABLE}) will simply drop them on the 1944 * floor. Other modes allow you to launch the dialer 1945 * ({@link #DEFAULT_KEYS_DIALER}), execute a shortcut in your options 1946 * menu without requiring the menu key be held down 1947 * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL} 1948 * and {@link #DEFAULT_KEYS_SEARCH_GLOBAL}). 1949 * 1950 * <p>Note that the mode selected here does not impact the default 1951 * handling of system keys, such as the "back" and "menu" keys, and your 1952 * activity and its views always get a first chance to receive and handle 1953 * all application keys. 1954 * 1955 * @param mode The desired default key mode constant. 1956 * 1957 * @see #DEFAULT_KEYS_DISABLE 1958 * @see #DEFAULT_KEYS_DIALER 1959 * @see #DEFAULT_KEYS_SHORTCUT 1960 * @see #DEFAULT_KEYS_SEARCH_LOCAL 1961 * @see #DEFAULT_KEYS_SEARCH_GLOBAL 1962 * @see #onKeyDown 1963 */ 1964 public final void setDefaultKeyMode(int mode) { 1965 mDefaultKeyMode = mode; 1966 1967 // Some modes use a SpannableStringBuilder to track & dispatch input events 1968 // This list must remain in sync with the switch in onKeyDown() 1969 switch (mode) { 1970 case DEFAULT_KEYS_DISABLE: 1971 case DEFAULT_KEYS_SHORTCUT: 1972 mDefaultKeySsb = null; // not used in these modes 1973 break; 1974 case DEFAULT_KEYS_DIALER: 1975 case DEFAULT_KEYS_SEARCH_LOCAL: 1976 case DEFAULT_KEYS_SEARCH_GLOBAL: 1977 mDefaultKeySsb = new SpannableStringBuilder(); 1978 Selection.setSelection(mDefaultKeySsb,0); 1979 break; 1980 default: 1981 throw new IllegalArgumentException(); 1982 } 1983 } 1984 1985 /** 1986 * Called when a key was pressed down and not handled by any of the views 1987 * inside of the activity. So, for example, key presses while the cursor 1988 * is inside a TextView will not trigger the event (unless it is a navigation 1989 * to another object) because TextView handles its own key presses. 1990 * 1991 * <p>If the focused view didn't want this event, this method is called. 1992 * 1993 * <p>The default implementation takes care of {@link KeyEvent#KEYCODE_BACK} 1994 * by calling {@link #onBackPressed()}, though the behavior varies based 1995 * on the application compatibility mode: for 1996 * {@link android.os.Build.VERSION_CODES#ECLAIR} or later applications, 1997 * it will set up the dispatch to call {@link #onKeyUp} where the action 1998 * will be performed; for earlier applications, it will perform the 1999 * action immediately in on-down, as those versions of the platform 2000 * behaved. 2001 * 2002 * <p>Other additional default key handling may be performed 2003 * if configured with {@link #setDefaultKeyMode}. 2004 * 2005 * @return Return <code>true</code> to prevent this event from being propagated 2006 * further, or <code>false</code> to indicate that you have not handled 2007 * this event and it should continue to be propagated. 2008 * @see #onKeyUp 2009 * @see android.view.KeyEvent 2010 */ 2011 public boolean onKeyDown(int keyCode, KeyEvent event) { 2012 if (keyCode == KeyEvent.KEYCODE_BACK) { 2013 if (getApplicationInfo().targetSdkVersion 2014 >= Build.VERSION_CODES.ECLAIR) { 2015 event.startTracking(); 2016 } else { 2017 onBackPressed(); 2018 } 2019 return true; 2020 } 2021 2022 if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) { 2023 return false; 2024 } else if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) { 2025 if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL, 2026 keyCode, event, Menu.FLAG_ALWAYS_PERFORM_CLOSE)) { 2027 return true; 2028 } 2029 return false; 2030 } else { 2031 // Common code for DEFAULT_KEYS_DIALER & DEFAULT_KEYS_SEARCH_* 2032 boolean clearSpannable = false; 2033 boolean handled; 2034 if ((event.getRepeatCount() != 0) || event.isSystem()) { 2035 clearSpannable = true; 2036 handled = false; 2037 } else { 2038 handled = TextKeyListener.getInstance().onKeyDown( 2039 null, mDefaultKeySsb, keyCode, event); 2040 if (handled && mDefaultKeySsb.length() > 0) { 2041 // something useable has been typed - dispatch it now. 2042 2043 final String str = mDefaultKeySsb.toString(); 2044 clearSpannable = true; 2045 2046 switch (mDefaultKeyMode) { 2047 case DEFAULT_KEYS_DIALER: 2048 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + str)); 2049 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2050 startActivity(intent); 2051 break; 2052 case DEFAULT_KEYS_SEARCH_LOCAL: 2053 startSearch(str, false, null, false); 2054 break; 2055 case DEFAULT_KEYS_SEARCH_GLOBAL: 2056 startSearch(str, false, null, true); 2057 break; 2058 } 2059 } 2060 } 2061 if (clearSpannable) { 2062 mDefaultKeySsb.clear(); 2063 mDefaultKeySsb.clearSpans(); 2064 Selection.setSelection(mDefaultKeySsb,0); 2065 } 2066 return handled; 2067 } 2068 } 2069 2070 /** 2071 * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent) 2072 * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle 2073 * the event). 2074 */ 2075 public boolean onKeyLongPress(int keyCode, KeyEvent event) { 2076 return false; 2077 } 2078 2079 /** 2080 * Called when a key was released and not handled by any of the views 2081 * inside of the activity. So, for example, key presses while the cursor 2082 * is inside a TextView will not trigger the event (unless it is a navigation 2083 * to another object) because TextView handles its own key presses. 2084 * 2085 * <p>The default implementation handles KEYCODE_BACK to stop the activity 2086 * and go back. 2087 * 2088 * @return Return <code>true</code> to prevent this event from being propagated 2089 * further, or <code>false</code> to indicate that you have not handled 2090 * this event and it should continue to be propagated. 2091 * @see #onKeyDown 2092 * @see KeyEvent 2093 */ 2094 public boolean onKeyUp(int keyCode, KeyEvent event) { 2095 if (getApplicationInfo().targetSdkVersion 2096 >= Build.VERSION_CODES.ECLAIR) { 2097 if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() 2098 && !event.isCanceled()) { 2099 onBackPressed(); 2100 return true; 2101 } 2102 } 2103 return false; 2104 } 2105 2106 /** 2107 * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent) 2108 * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle 2109 * the event). 2110 */ 2111 public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { 2112 return false; 2113 } 2114 2115 /** 2116 * Called when the activity has detected the user's press of the back 2117 * key. The default implementation simply finishes the current activity, 2118 * but you can override this to do whatever you want. 2119 */ 2120 public void onBackPressed() { 2121 if (!mFragments.popBackStackImmediate()) { 2122 finish(); 2123 } 2124 } 2125 2126 /** 2127 * Called when a key shortcut event is not handled by any of the views in the Activity. 2128 * Override this method to implement global key shortcuts for the Activity. 2129 * Key shortcuts can also be implemented by setting the 2130 * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items. 2131 * 2132 * @param keyCode The value in event.getKeyCode(). 2133 * @param event Description of the key event. 2134 * @return True if the key shortcut was handled. 2135 */ 2136 public boolean onKeyShortcut(int keyCode, KeyEvent event) { 2137 return false; 2138 } 2139 2140 /** 2141 * Called when a touch screen event was not handled by any of the views 2142 * under it. This is most useful to process touch events that happen 2143 * outside of your window bounds, where there is no view to receive it. 2144 * 2145 * @param event The touch screen event being processed. 2146 * 2147 * @return Return true if you have consumed the event, false if you haven't. 2148 * The default implementation always returns false. 2149 */ 2150 public boolean onTouchEvent(MotionEvent event) { 2151 if (mWindow.shouldCloseOnTouch(this, event)) { 2152 finish(); 2153 return true; 2154 } 2155 2156 return false; 2157 } 2158 2159 /** 2160 * Called when the trackball was moved and not handled by any of the 2161 * views inside of the activity. So, for example, if the trackball moves 2162 * while focus is on a button, you will receive a call here because 2163 * buttons do not normally do anything with trackball events. The call 2164 * here happens <em>before</em> trackball movements are converted to 2165 * DPAD key events, which then get sent back to the view hierarchy, and 2166 * will be processed at the point for things like focus navigation. 2167 * 2168 * @param event The trackball event being processed. 2169 * 2170 * @return Return true if you have consumed the event, false if you haven't. 2171 * The default implementation always returns false. 2172 */ 2173 public boolean onTrackballEvent(MotionEvent event) { 2174 return false; 2175 } 2176 2177 /** 2178 * Called when a generic motion event was not handled by any of the 2179 * views inside of the activity. 2180 * <p> 2181 * Generic motion events describe joystick movements, mouse hovers, track pad 2182 * touches, scroll wheel movements and other input events. The 2183 * {@link MotionEvent#getSource() source} of the motion event specifies 2184 * the class of input that was received. Implementations of this method 2185 * must examine the bits in the source before processing the event. 2186 * The following code example shows how this is done. 2187 * </p><p> 2188 * Generic motion events with source class 2189 * {@link android.view.InputDevice#SOURCE_CLASS_POINTER} 2190 * are delivered to the view under the pointer. All other generic motion events are 2191 * delivered to the focused view. 2192 * </p><p> 2193 * See {@link View#onGenericMotionEvent(MotionEvent)} for an example of how to 2194 * handle this event. 2195 * </p> 2196 * 2197 * @param event The generic motion event being processed. 2198 * 2199 * @return Return true if you have consumed the event, false if you haven't. 2200 * The default implementation always returns false. 2201 */ 2202 public boolean onGenericMotionEvent(MotionEvent event) { 2203 return false; 2204 } 2205 2206 /** 2207 * Called whenever a key, touch, or trackball event is dispatched to the 2208 * activity. Implement this method if you wish to know that the user has 2209 * interacted with the device in some way while your activity is running. 2210 * This callback and {@link #onUserLeaveHint} are intended to help 2211 * activities manage status bar notifications intelligently; specifically, 2212 * for helping activities determine the proper time to cancel a notfication. 2213 * 2214 * <p>All calls to your activity's {@link #onUserLeaveHint} callback will 2215 * be accompanied by calls to {@link #onUserInteraction}. This 2216 * ensures that your activity will be told of relevant user activity such 2217 * as pulling down the notification pane and touching an item there. 2218 * 2219 * <p>Note that this callback will be invoked for the touch down action 2220 * that begins a touch gesture, but may not be invoked for the touch-moved 2221 * and touch-up actions that follow. 2222 * 2223 * @see #onUserLeaveHint() 2224 */ 2225 public void onUserInteraction() { 2226 } 2227 2228 public void onWindowAttributesChanged(WindowManager.LayoutParams params) { 2229 // Update window manager if: we have a view, that view is 2230 // attached to its parent (which will be a RootView), and 2231 // this activity is not embedded. 2232 if (mParent == null) { 2233 View decor = mDecor; 2234 if (decor != null && decor.getParent() != null) { 2235 getWindowManager().updateViewLayout(decor, params); 2236 } 2237 } 2238 } 2239 2240 public void onContentChanged() { 2241 } 2242 2243 /** 2244 * Called when the current {@link Window} of the activity gains or loses 2245 * focus. This is the best indicator of whether this activity is visible 2246 * to the user. The default implementation clears the key tracking 2247 * state, so should always be called. 2248 * 2249 * <p>Note that this provides information about global focus state, which 2250 * is managed independently of activity lifecycles. As such, while focus 2251 * changes will generally have some relation to lifecycle changes (an 2252 * activity that is stopped will not generally get window focus), you 2253 * should not rely on any particular order between the callbacks here and 2254 * those in the other lifecycle methods such as {@link #onResume}. 2255 * 2256 * <p>As a general rule, however, a resumed activity will have window 2257 * focus... unless it has displayed other dialogs or popups that take 2258 * input focus, in which case the activity itself will not have focus 2259 * when the other windows have it. Likewise, the system may display 2260 * system-level windows (such as the status bar notification panel or 2261 * a system alert) which will temporarily take window input focus without 2262 * pausing the foreground activity. 2263 * 2264 * @param hasFocus Whether the window of this activity has focus. 2265 * 2266 * @see #hasWindowFocus() 2267 * @see #onResume 2268 * @see View#onWindowFocusChanged(boolean) 2269 */ 2270 public void onWindowFocusChanged(boolean hasFocus) { 2271 } 2272 2273 /** 2274 * Called when the main window associated with the activity has been 2275 * attached to the window manager. 2276 * See {@link View#onAttachedToWindow() View.onAttachedToWindow()} 2277 * for more information. 2278 * @see View#onAttachedToWindow 2279 */ 2280 public void onAttachedToWindow() { 2281 } 2282 2283 /** 2284 * Called when the main window associated with the activity has been 2285 * detached from the window manager. 2286 * See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()} 2287 * for more information. 2288 * @see View#onDetachedFromWindow 2289 */ 2290 public void onDetachedFromWindow() { 2291 } 2292 2293 /** 2294 * Returns true if this activity's <em>main</em> window currently has window focus. 2295 * Note that this is not the same as the view itself having focus. 2296 * 2297 * @return True if this activity's main window currently has window focus. 2298 * 2299 * @see #onWindowAttributesChanged(android.view.WindowManager.LayoutParams) 2300 */ 2301 public boolean hasWindowFocus() { 2302 Window w = getWindow(); 2303 if (w != null) { 2304 View d = w.getDecorView(); 2305 if (d != null) { 2306 return d.hasWindowFocus(); 2307 } 2308 } 2309 return false; 2310 } 2311 2312 /** 2313 * Called to process key events. You can override this to intercept all 2314 * key events before they are dispatched to the window. Be sure to call 2315 * this implementation for key events that should be handled normally. 2316 * 2317 * @param event The key event. 2318 * 2319 * @return boolean Return true if this event was consumed. 2320 */ 2321 public boolean dispatchKeyEvent(KeyEvent event) { 2322 onUserInteraction(); 2323 Window win = getWindow(); 2324 if (win.superDispatchKeyEvent(event)) { 2325 return true; 2326 } 2327 View decor = mDecor; 2328 if (decor == null) decor = win.getDecorView(); 2329 return event.dispatch(this, decor != null 2330 ? decor.getKeyDispatcherState() : null, this); 2331 } 2332 2333 /** 2334 * Called to process a key shortcut event. 2335 * You can override this to intercept all key shortcut events before they are 2336 * dispatched to the window. Be sure to call this implementation for key shortcut 2337 * events that should be handled normally. 2338 * 2339 * @param event The key shortcut event. 2340 * @return True if this event was consumed. 2341 */ 2342 public boolean dispatchKeyShortcutEvent(KeyEvent event) { 2343 onUserInteraction(); 2344 if (getWindow().superDispatchKeyShortcutEvent(event)) { 2345 return true; 2346 } 2347 return onKeyShortcut(event.getKeyCode(), event); 2348 } 2349 2350 /** 2351 * Called to process touch screen events. You can override this to 2352 * intercept all touch screen events before they are dispatched to the 2353 * window. Be sure to call this implementation for touch screen events 2354 * that should be handled normally. 2355 * 2356 * @param ev The touch screen event. 2357 * 2358 * @return boolean Return true if this event was consumed. 2359 */ 2360 public boolean dispatchTouchEvent(MotionEvent ev) { 2361 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 2362 onUserInteraction(); 2363 } 2364 if (getWindow().superDispatchTouchEvent(ev)) { 2365 return true; 2366 } 2367 return onTouchEvent(ev); 2368 } 2369 2370 /** 2371 * Called to process trackball events. You can override this to 2372 * intercept all trackball events before they are dispatched to the 2373 * window. Be sure to call this implementation for trackball events 2374 * that should be handled normally. 2375 * 2376 * @param ev The trackball event. 2377 * 2378 * @return boolean Return true if this event was consumed. 2379 */ 2380 public boolean dispatchTrackballEvent(MotionEvent ev) { 2381 onUserInteraction(); 2382 if (getWindow().superDispatchTrackballEvent(ev)) { 2383 return true; 2384 } 2385 return onTrackballEvent(ev); 2386 } 2387 2388 /** 2389 * Called to process generic motion events. You can override this to 2390 * intercept all generic motion events before they are dispatched to the 2391 * window. Be sure to call this implementation for generic motion events 2392 * that should be handled normally. 2393 * 2394 * @param ev The generic motion event. 2395 * 2396 * @return boolean Return true if this event was consumed. 2397 */ 2398 public boolean dispatchGenericMotionEvent(MotionEvent ev) { 2399 onUserInteraction(); 2400 if (getWindow().superDispatchGenericMotionEvent(ev)) { 2401 return true; 2402 } 2403 return onGenericMotionEvent(ev); 2404 } 2405 2406 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 2407 event.setClassName(getClass().getName()); 2408 event.setPackageName(getPackageName()); 2409 2410 LayoutParams params = getWindow().getAttributes(); 2411 boolean isFullScreen = (params.width == LayoutParams.MATCH_PARENT) && 2412 (params.height == LayoutParams.MATCH_PARENT); 2413 event.setFullScreen(isFullScreen); 2414 2415 CharSequence title = getTitle(); 2416 if (!TextUtils.isEmpty(title)) { 2417 event.getText().add(title); 2418 } 2419 2420 return true; 2421 } 2422 2423 /** 2424 * Default implementation of 2425 * {@link android.view.Window.Callback#onCreatePanelView} 2426 * for activities. This 2427 * simply returns null so that all panel sub-windows will have the default 2428 * menu behavior. 2429 */ 2430 public View onCreatePanelView(int featureId) { 2431 return null; 2432 } 2433 2434 /** 2435 * Default implementation of 2436 * {@link android.view.Window.Callback#onCreatePanelMenu} 2437 * for activities. This calls through to the new 2438 * {@link #onCreateOptionsMenu} method for the 2439 * {@link android.view.Window#FEATURE_OPTIONS_PANEL} panel, 2440 * so that subclasses of Activity don't need to deal with feature codes. 2441 */ 2442 public boolean onCreatePanelMenu(int featureId, Menu menu) { 2443 if (featureId == Window.FEATURE_OPTIONS_PANEL) { 2444 boolean show = onCreateOptionsMenu(menu); 2445 show |= mFragments.dispatchCreateOptionsMenu(menu, getMenuInflater()); 2446 return show; 2447 } 2448 return false; 2449 } 2450 2451 /** 2452 * Default implementation of 2453 * {@link android.view.Window.Callback#onPreparePanel} 2454 * for activities. This 2455 * calls through to the new {@link #onPrepareOptionsMenu} method for the 2456 * {@link android.view.Window#FEATURE_OPTIONS_PANEL} 2457 * panel, so that subclasses of 2458 * Activity don't need to deal with feature codes. 2459 */ 2460 public boolean onPreparePanel(int featureId, View view, Menu menu) { 2461 if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) { 2462 boolean goforit = onPrepareOptionsMenu(menu); 2463 goforit |= mFragments.dispatchPrepareOptionsMenu(menu); 2464 return goforit && menu.hasVisibleItems(); 2465 } 2466 return true; 2467 } 2468 2469 /** 2470 * {@inheritDoc} 2471 * 2472 * @return The default implementation returns true. 2473 */ 2474 public boolean onMenuOpened(int featureId, Menu menu) { 2475 if (featureId == Window.FEATURE_ACTION_BAR) { 2476 initActionBar(); 2477 if (mActionBar != null) { 2478 mActionBar.dispatchMenuVisibilityChanged(true); 2479 } else { 2480 Log.e(TAG, "Tried to open action bar menu with no action bar"); 2481 } 2482 } 2483 return true; 2484 } 2485 2486 /** 2487 * Default implementation of 2488 * {@link android.view.Window.Callback#onMenuItemSelected} 2489 * for activities. This calls through to the new 2490 * {@link #onOptionsItemSelected} method for the 2491 * {@link android.view.Window#FEATURE_OPTIONS_PANEL} 2492 * panel, so that subclasses of 2493 * Activity don't need to deal with feature codes. 2494 */ 2495 public boolean onMenuItemSelected(int featureId, MenuItem item) { 2496 switch (featureId) { 2497 case Window.FEATURE_OPTIONS_PANEL: 2498 // Put event logging here so it gets called even if subclass 2499 // doesn't call through to superclass's implmeentation of each 2500 // of these methods below 2501 EventLog.writeEvent(50000, 0, item.getTitleCondensed()); 2502 if (onOptionsItemSelected(item)) { 2503 return true; 2504 } 2505 return mFragments.dispatchOptionsItemSelected(item); 2506 2507 case Window.FEATURE_CONTEXT_MENU: 2508 EventLog.writeEvent(50000, 1, item.getTitleCondensed()); 2509 if (onContextItemSelected(item)) { 2510 return true; 2511 } 2512 return mFragments.dispatchContextItemSelected(item); 2513 2514 default: 2515 return false; 2516 } 2517 } 2518 2519 /** 2520 * Default implementation of 2521 * {@link android.view.Window.Callback#onPanelClosed(int, Menu)} for 2522 * activities. This calls through to {@link #onOptionsMenuClosed(Menu)} 2523 * method for the {@link android.view.Window#FEATURE_OPTIONS_PANEL} panel, 2524 * so that subclasses of Activity don't need to deal with feature codes. 2525 * For context menus ({@link Window#FEATURE_CONTEXT_MENU}), the 2526 * {@link #onContextMenuClosed(Menu)} will be called. 2527 */ 2528 public void onPanelClosed(int featureId, Menu menu) { 2529 switch (featureId) { 2530 case Window.FEATURE_OPTIONS_PANEL: 2531 mFragments.dispatchOptionsMenuClosed(menu); 2532 onOptionsMenuClosed(menu); 2533 break; 2534 2535 case Window.FEATURE_CONTEXT_MENU: 2536 onContextMenuClosed(menu); 2537 break; 2538 2539 case Window.FEATURE_ACTION_BAR: 2540 initActionBar(); 2541 mActionBar.dispatchMenuVisibilityChanged(false); 2542 break; 2543 } 2544 } 2545 2546 /** 2547 * Declare that the options menu has changed, so should be recreated. 2548 * The {@link #onCreateOptionsMenu(Menu)} method will be called the next 2549 * time it needs to be displayed. 2550 */ 2551 public void invalidateOptionsMenu() { 2552 mWindow.invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL); 2553 } 2554 2555 /** 2556 * Initialize the contents of the Activity's standard options menu. You 2557 * should place your menu items in to <var>menu</var>. 2558 * 2559 * <p>This is only called once, the first time the options menu is 2560 * displayed. To update the menu every time it is displayed, see 2561 * {@link #onPrepareOptionsMenu}. 2562 * 2563 * <p>The default implementation populates the menu with standard system 2564 * menu items. These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that 2565 * they will be correctly ordered with application-defined menu items. 2566 * Deriving classes should always call through to the base implementation. 2567 * 2568 * <p>You can safely hold on to <var>menu</var> (and any items created 2569 * from it), making modifications to it as desired, until the next 2570 * time onCreateOptionsMenu() is called. 2571 * 2572 * <p>When you add items to the menu, you can implement the Activity's 2573 * {@link #onOptionsItemSelected} method to handle them there. 2574 * 2575 * @param menu The options menu in which you place your items. 2576 * 2577 * @return You must return true for the menu to be displayed; 2578 * if you return false it will not be shown. 2579 * 2580 * @see #onPrepareOptionsMenu 2581 * @see #onOptionsItemSelected 2582 */ 2583 public boolean onCreateOptionsMenu(Menu menu) { 2584 if (mParent != null) { 2585 return mParent.onCreateOptionsMenu(menu); 2586 } 2587 return true; 2588 } 2589 2590 /** 2591 * Prepare the Screen's standard options menu to be displayed. This is 2592 * called right before the menu is shown, every time it is shown. You can 2593 * use this method to efficiently enable/disable items or otherwise 2594 * dynamically modify the contents. 2595 * 2596 * <p>The default implementation updates the system menu items based on the 2597 * activity's state. Deriving classes should always call through to the 2598 * base class implementation. 2599 * 2600 * @param menu The options menu as last shown or first initialized by 2601 * onCreateOptionsMenu(). 2602 * 2603 * @return You must return true for the menu to be displayed; 2604 * if you return false it will not be shown. 2605 * 2606 * @see #onCreateOptionsMenu 2607 */ 2608 public boolean onPrepareOptionsMenu(Menu menu) { 2609 if (mParent != null) { 2610 return mParent.onPrepareOptionsMenu(menu); 2611 } 2612 return true; 2613 } 2614 2615 /** 2616 * This hook is called whenever an item in your options menu is selected. 2617 * The default implementation simply returns false to have the normal 2618 * processing happen (calling the item's Runnable or sending a message to 2619 * its Handler as appropriate). You can use this method for any items 2620 * for which you would like to do processing without those other 2621 * facilities. 2622 * 2623 * <p>Derived classes should call through to the base class for it to 2624 * perform the default menu handling. 2625 * 2626 * @param item The menu item that was selected. 2627 * 2628 * @return boolean Return false to allow normal menu processing to 2629 * proceed, true to consume it here. 2630 * 2631 * @see #onCreateOptionsMenu 2632 */ 2633 public boolean onOptionsItemSelected(MenuItem item) { 2634 if (mParent != null) { 2635 return mParent.onOptionsItemSelected(item); 2636 } 2637 return false; 2638 } 2639 2640 /** 2641 * This hook is called whenever the options menu is being closed (either by the user canceling 2642 * the menu with the back/menu button, or when an item is selected). 2643 * 2644 * @param menu The options menu as last shown or first initialized by 2645 * onCreateOptionsMenu(). 2646 */ 2647 public void onOptionsMenuClosed(Menu menu) { 2648 if (mParent != null) { 2649 mParent.onOptionsMenuClosed(menu); 2650 } 2651 } 2652 2653 /** 2654 * Programmatically opens the options menu. If the options menu is already 2655 * open, this method does nothing. 2656 */ 2657 public void openOptionsMenu() { 2658 mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null); 2659 } 2660 2661 /** 2662 * Progammatically closes the options menu. If the options menu is already 2663 * closed, this method does nothing. 2664 */ 2665 public void closeOptionsMenu() { 2666 mWindow.closePanel(Window.FEATURE_OPTIONS_PANEL); 2667 } 2668 2669 /** 2670 * Called when a context menu for the {@code view} is about to be shown. 2671 * Unlike {@link #onCreateOptionsMenu(Menu)}, this will be called every 2672 * time the context menu is about to be shown and should be populated for 2673 * the view (or item inside the view for {@link AdapterView} subclasses, 2674 * this can be found in the {@code menuInfo})). 2675 * <p> 2676 * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an 2677 * item has been selected. 2678 * <p> 2679 * It is not safe to hold onto the context menu after this method returns. 2680 * {@inheritDoc} 2681 */ 2682 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 2683 } 2684 2685 /** 2686 * Registers a context menu to be shown for the given view (multiple views 2687 * can show the context menu). This method will set the 2688 * {@link OnCreateContextMenuListener} on the view to this activity, so 2689 * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be 2690 * called when it is time to show the context menu. 2691 * 2692 * @see #unregisterForContextMenu(View) 2693 * @param view The view that should show a context menu. 2694 */ 2695 public void registerForContextMenu(View view) { 2696 view.setOnCreateContextMenuListener(this); 2697 } 2698 2699 /** 2700 * Prevents a context menu to be shown for the given view. This method will remove the 2701 * {@link OnCreateContextMenuListener} on the view. 2702 * 2703 * @see #registerForContextMenu(View) 2704 * @param view The view that should stop showing a context menu. 2705 */ 2706 public void unregisterForContextMenu(View view) { 2707 view.setOnCreateContextMenuListener(null); 2708 } 2709 2710 /** 2711 * Programmatically opens the context menu for a particular {@code view}. 2712 * The {@code view} should have been added via 2713 * {@link #registerForContextMenu(View)}. 2714 * 2715 * @param view The view to show the context menu for. 2716 */ 2717 public void openContextMenu(View view) { 2718 view.showContextMenu(); 2719 } 2720 2721 /** 2722 * Programmatically closes the most recently opened context menu, if showing. 2723 */ 2724 public void closeContextMenu() { 2725 mWindow.closePanel(Window.FEATURE_CONTEXT_MENU); 2726 } 2727 2728 /** 2729 * This hook is called whenever an item in a context menu is selected. The 2730 * default implementation simply returns false to have the normal processing 2731 * happen (calling the item's Runnable or sending a message to its Handler 2732 * as appropriate). You can use this method for any items for which you 2733 * would like to do processing without those other facilities. 2734 * <p> 2735 * Use {@link MenuItem#getMenuInfo()} to get extra information set by the 2736 * View that added this menu item. 2737 * <p> 2738 * Derived classes should call through to the base class for it to perform 2739 * the default menu handling. 2740 * 2741 * @param item The context menu item that was selected. 2742 * @return boolean Return false to allow normal context menu processing to 2743 * proceed, true to consume it here. 2744 */ 2745 public boolean onContextItemSelected(MenuItem item) { 2746 if (mParent != null) { 2747 return mParent.onContextItemSelected(item); 2748 } 2749 return false; 2750 } 2751 2752 /** 2753 * This hook is called whenever the context menu is being closed (either by 2754 * the user canceling the menu with the back/menu button, or when an item is 2755 * selected). 2756 * 2757 * @param menu The context menu that is being closed. 2758 */ 2759 public void onContextMenuClosed(Menu menu) { 2760 if (mParent != null) { 2761 mParent.onContextMenuClosed(menu); 2762 } 2763 } 2764 2765 /** 2766 * @deprecated Old no-arguments version of {@link #onCreateDialog(int, Bundle)}. 2767 */ 2768 @Deprecated 2769 protected Dialog onCreateDialog(int id) { 2770 return null; 2771 } 2772 2773 /** 2774 * Callback for creating dialogs that are managed (saved and restored) for you 2775 * by the activity. The default implementation calls through to 2776 * {@link #onCreateDialog(int)} for compatibility. 2777 * 2778 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 2779 * or later, consider instead using a {@link DialogFragment} instead.</em> 2780 * 2781 * <p>If you use {@link #showDialog(int)}, the activity will call through to 2782 * this method the first time, and hang onto it thereafter. Any dialog 2783 * that is created by this method will automatically be saved and restored 2784 * for you, including whether it is showing. 2785 * 2786 * <p>If you would like the activity to manage saving and restoring dialogs 2787 * for you, you should override this method and handle any ids that are 2788 * passed to {@link #showDialog}. 2789 * 2790 * <p>If you would like an opportunity to prepare your dialog before it is shown, 2791 * override {@link #onPrepareDialog(int, Dialog, Bundle)}. 2792 * 2793 * @param id The id of the dialog. 2794 * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}. 2795 * @return The dialog. If you return null, the dialog will not be created. 2796 * 2797 * @see #onPrepareDialog(int, Dialog, Bundle) 2798 * @see #showDialog(int, Bundle) 2799 * @see #dismissDialog(int) 2800 * @see #removeDialog(int) 2801 * 2802 * @deprecated Use the new {@link DialogFragment} class with 2803 * {@link FragmentManager} instead; this is also 2804 * available on older platforms through the Android compatibility package. 2805 */ 2806 @Deprecated 2807 protected Dialog onCreateDialog(int id, Bundle args) { 2808 return onCreateDialog(id); 2809 } 2810 2811 /** 2812 * @deprecated Old no-arguments version of 2813 * {@link #onPrepareDialog(int, Dialog, Bundle)}. 2814 */ 2815 @Deprecated 2816 protected void onPrepareDialog(int id, Dialog dialog) { 2817 dialog.setOwnerActivity(this); 2818 } 2819 2820 /** 2821 * Provides an opportunity to prepare a managed dialog before it is being 2822 * shown. The default implementation calls through to 2823 * {@link #onPrepareDialog(int, Dialog)} for compatibility. 2824 * 2825 * <p> 2826 * Override this if you need to update a managed dialog based on the state 2827 * of the application each time it is shown. For example, a time picker 2828 * dialog might want to be updated with the current time. You should call 2829 * through to the superclass's implementation. The default implementation 2830 * will set this Activity as the owner activity on the Dialog. 2831 * 2832 * @param id The id of the managed dialog. 2833 * @param dialog The dialog. 2834 * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}. 2835 * @see #onCreateDialog(int, Bundle) 2836 * @see #showDialog(int) 2837 * @see #dismissDialog(int) 2838 * @see #removeDialog(int) 2839 * 2840 * @deprecated Use the new {@link DialogFragment} class with 2841 * {@link FragmentManager} instead; this is also 2842 * available on older platforms through the Android compatibility package. 2843 */ 2844 @Deprecated 2845 protected void onPrepareDialog(int id, Dialog dialog, Bundle args) { 2846 onPrepareDialog(id, dialog); 2847 } 2848 2849 /** 2850 * Simple version of {@link #showDialog(int, Bundle)} that does not 2851 * take any arguments. Simply calls {@link #showDialog(int, Bundle)} 2852 * with null arguments. 2853 * 2854 * @deprecated Use the new {@link DialogFragment} class with 2855 * {@link FragmentManager} instead; this is also 2856 * available on older platforms through the Android compatibility package. 2857 */ 2858 @Deprecated 2859 public final void showDialog(int id) { 2860 showDialog(id, null); 2861 } 2862 2863 /** 2864 * Show a dialog managed by this activity. A call to {@link #onCreateDialog(int, Bundle)} 2865 * will be made with the same id the first time this is called for a given 2866 * id. From thereafter, the dialog will be automatically saved and restored. 2867 * 2868 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 2869 * or later, consider instead using a {@link DialogFragment} instead.</em> 2870 * 2871 * <p>Each time a dialog is shown, {@link #onPrepareDialog(int, Dialog, Bundle)} will 2872 * be made to provide an opportunity to do any timely preparation. 2873 * 2874 * @param id The id of the managed dialog. 2875 * @param args Arguments to pass through to the dialog. These will be saved 2876 * and restored for you. Note that if the dialog is already created, 2877 * {@link #onCreateDialog(int, Bundle)} will not be called with the new 2878 * arguments but {@link #onPrepareDialog(int, Dialog, Bundle)} will be. 2879 * If you need to rebuild the dialog, call {@link #removeDialog(int)} first. 2880 * @return Returns true if the Dialog was created; false is returned if 2881 * it is not created because {@link #onCreateDialog(int, Bundle)} returns false. 2882 * 2883 * @see Dialog 2884 * @see #onCreateDialog(int, Bundle) 2885 * @see #onPrepareDialog(int, Dialog, Bundle) 2886 * @see #dismissDialog(int) 2887 * @see #removeDialog(int) 2888 * 2889 * @deprecated Use the new {@link DialogFragment} class with 2890 * {@link FragmentManager} instead; this is also 2891 * available on older platforms through the Android compatibility package. 2892 */ 2893 @Deprecated 2894 public final boolean showDialog(int id, Bundle args) { 2895 if (mManagedDialogs == null) { 2896 mManagedDialogs = new SparseArray<ManagedDialog>(); 2897 } 2898 ManagedDialog md = mManagedDialogs.get(id); 2899 if (md == null) { 2900 md = new ManagedDialog(); 2901 md.mDialog = createDialog(id, null, args); 2902 if (md.mDialog == null) { 2903 return false; 2904 } 2905 mManagedDialogs.put(id, md); 2906 } 2907 2908 md.mArgs = args; 2909 onPrepareDialog(id, md.mDialog, args); 2910 md.mDialog.show(); 2911 return true; 2912 } 2913 2914 /** 2915 * Dismiss a dialog that was previously shown via {@link #showDialog(int)}. 2916 * 2917 * @param id The id of the managed dialog. 2918 * 2919 * @throws IllegalArgumentException if the id was not previously shown via 2920 * {@link #showDialog(int)}. 2921 * 2922 * @see #onCreateDialog(int, Bundle) 2923 * @see #onPrepareDialog(int, Dialog, Bundle) 2924 * @see #showDialog(int) 2925 * @see #removeDialog(int) 2926 * 2927 * @deprecated Use the new {@link DialogFragment} class with 2928 * {@link FragmentManager} instead; this is also 2929 * available on older platforms through the Android compatibility package. 2930 */ 2931 @Deprecated 2932 public final void dismissDialog(int id) { 2933 if (mManagedDialogs == null) { 2934 throw missingDialog(id); 2935 } 2936 2937 final ManagedDialog md = mManagedDialogs.get(id); 2938 if (md == null) { 2939 throw missingDialog(id); 2940 } 2941 md.mDialog.dismiss(); 2942 } 2943 2944 /** 2945 * Creates an exception to throw if a user passed in a dialog id that is 2946 * unexpected. 2947 */ 2948 private IllegalArgumentException missingDialog(int id) { 2949 return new IllegalArgumentException("no dialog with id " + id + " was ever " 2950 + "shown via Activity#showDialog"); 2951 } 2952 2953 /** 2954 * Removes any internal references to a dialog managed by this Activity. 2955 * If the dialog is showing, it will dismiss it as part of the clean up. 2956 * 2957 * <p>This can be useful if you know that you will never show a dialog again and 2958 * want to avoid the overhead of saving and restoring it in the future. 2959 * 2960 * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, this function 2961 * will not throw an exception if you try to remove an ID that does not 2962 * currently have an associated dialog.</p> 2963 * 2964 * @param id The id of the managed dialog. 2965 * 2966 * @see #onCreateDialog(int, Bundle) 2967 * @see #onPrepareDialog(int, Dialog, Bundle) 2968 * @see #showDialog(int) 2969 * @see #dismissDialog(int) 2970 * 2971 * @deprecated Use the new {@link DialogFragment} class with 2972 * {@link FragmentManager} instead; this is also 2973 * available on older platforms through the Android compatibility package. 2974 */ 2975 @Deprecated 2976 public final void removeDialog(int id) { 2977 if (mManagedDialogs != null) { 2978 final ManagedDialog md = mManagedDialogs.get(id); 2979 if (md != null) { 2980 md.mDialog.dismiss(); 2981 mManagedDialogs.remove(id); 2982 } 2983 } 2984 } 2985 2986 /** 2987 * This hook is called when the user signals the desire to start a search. 2988 * 2989 * <p>You can use this function as a simple way to launch the search UI, in response to a 2990 * menu item, search button, or other widgets within your activity. Unless overidden, 2991 * calling this function is the same as calling 2992 * {@link #startSearch startSearch(null, false, null, false)}, which launches 2993 * search for the current activity as specified in its manifest, see {@link SearchManager}. 2994 * 2995 * <p>You can override this function to force global search, e.g. in response to a dedicated 2996 * search key, or to block search entirely (by simply returning false). 2997 * 2998 * @return Returns {@code true} if search launched, and {@code false} if activity blocks it. 2999 * The default implementation always returns {@code true}. 3000 * 3001 * @see android.app.SearchManager 3002 */ 3003 public boolean onSearchRequested() { 3004 startSearch(null, false, null, false); 3005 return true; 3006 } 3007 3008 /** 3009 * This hook is called to launch the search UI. 3010 * 3011 * <p>It is typically called from onSearchRequested(), either directly from 3012 * Activity.onSearchRequested() or from an overridden version in any given 3013 * Activity. If your goal is simply to activate search, it is preferred to call 3014 * onSearchRequested(), which may have been overriden elsewhere in your Activity. If your goal 3015 * is to inject specific data such as context data, it is preferred to <i>override</i> 3016 * onSearchRequested(), so that any callers to it will benefit from the override. 3017 * 3018 * @param initialQuery Any non-null non-empty string will be inserted as 3019 * pre-entered text in the search query box. 3020 * @param selectInitialQuery If true, the intial query will be preselected, which means that 3021 * any further typing will replace it. This is useful for cases where an entire pre-formed 3022 * query is being inserted. If false, the selection point will be placed at the end of the 3023 * inserted query. This is useful when the inserted query is text that the user entered, 3024 * and the user would expect to be able to keep typing. <i>This parameter is only meaningful 3025 * if initialQuery is a non-empty string.</i> 3026 * @param appSearchData An application can insert application-specific 3027 * context here, in order to improve quality or specificity of its own 3028 * searches. This data will be returned with SEARCH intent(s). Null if 3029 * no extra data is required. 3030 * @param globalSearch If false, this will only launch the search that has been specifically 3031 * defined by the application (which is usually defined as a local search). If no default 3032 * search is defined in the current application or activity, global search will be launched. 3033 * If true, this will always launch a platform-global (e.g. web-based) search instead. 3034 * 3035 * @see android.app.SearchManager 3036 * @see #onSearchRequested 3037 */ 3038 public void startSearch(String initialQuery, boolean selectInitialQuery, 3039 Bundle appSearchData, boolean globalSearch) { 3040 ensureSearchManager(); 3041 mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(), 3042 appSearchData, globalSearch); 3043 } 3044 3045 /** 3046 * Similar to {@link #startSearch}, but actually fires off the search query after invoking 3047 * the search dialog. Made available for testing purposes. 3048 * 3049 * @param query The query to trigger. If empty, the request will be ignored. 3050 * @param appSearchData An application can insert application-specific 3051 * context here, in order to improve quality or specificity of its own 3052 * searches. This data will be returned with SEARCH intent(s). Null if 3053 * no extra data is required. 3054 */ 3055 public void triggerSearch(String query, Bundle appSearchData) { 3056 ensureSearchManager(); 3057 mSearchManager.triggerSearch(query, getComponentName(), appSearchData); 3058 } 3059 3060 /** 3061 * Request that key events come to this activity. Use this if your 3062 * activity has no views with focus, but the activity still wants 3063 * a chance to process key events. 3064 * 3065 * @see android.view.Window#takeKeyEvents 3066 */ 3067 public void takeKeyEvents(boolean get) { 3068 getWindow().takeKeyEvents(get); 3069 } 3070 3071 /** 3072 * Enable extended window features. This is a convenience for calling 3073 * {@link android.view.Window#requestFeature getWindow().requestFeature()}. 3074 * 3075 * @param featureId The desired feature as defined in 3076 * {@link android.view.Window}. 3077 * @return Returns true if the requested feature is supported and now 3078 * enabled. 3079 * 3080 * @see android.view.Window#requestFeature 3081 */ 3082 public final boolean requestWindowFeature(int featureId) { 3083 return getWindow().requestFeature(featureId); 3084 } 3085 3086 /** 3087 * Convenience for calling 3088 * {@link android.view.Window#setFeatureDrawableResource}. 3089 */ 3090 public final void setFeatureDrawableResource(int featureId, int resId) { 3091 getWindow().setFeatureDrawableResource(featureId, resId); 3092 } 3093 3094 /** 3095 * Convenience for calling 3096 * {@link android.view.Window#setFeatureDrawableUri}. 3097 */ 3098 public final void setFeatureDrawableUri(int featureId, Uri uri) { 3099 getWindow().setFeatureDrawableUri(featureId, uri); 3100 } 3101 3102 /** 3103 * Convenience for calling 3104 * {@link android.view.Window#setFeatureDrawable(int, Drawable)}. 3105 */ 3106 public final void setFeatureDrawable(int featureId, Drawable drawable) { 3107 getWindow().setFeatureDrawable(featureId, drawable); 3108 } 3109 3110 /** 3111 * Convenience for calling 3112 * {@link android.view.Window#setFeatureDrawableAlpha}. 3113 */ 3114 public final void setFeatureDrawableAlpha(int featureId, int alpha) { 3115 getWindow().setFeatureDrawableAlpha(featureId, alpha); 3116 } 3117 3118 /** 3119 * Convenience for calling 3120 * {@link android.view.Window#getLayoutInflater}. 3121 */ 3122 public LayoutInflater getLayoutInflater() { 3123 return getWindow().getLayoutInflater(); 3124 } 3125 3126 /** 3127 * Returns a {@link MenuInflater} with this context. 3128 */ 3129 public MenuInflater getMenuInflater() { 3130 // Make sure that action views can get an appropriate theme. 3131 if (mMenuInflater == null) { 3132 initActionBar(); 3133 if (mActionBar != null) { 3134 mMenuInflater = new MenuInflater(mActionBar.getThemedContext()); 3135 } else { 3136 mMenuInflater = new MenuInflater(this); 3137 } 3138 } 3139 return mMenuInflater; 3140 } 3141 3142 @Override 3143 protected void onApplyThemeResource(Resources.Theme theme, int resid, 3144 boolean first) { 3145 if (mParent == null) { 3146 super.onApplyThemeResource(theme, resid, first); 3147 } else { 3148 try { 3149 theme.setTo(mParent.getTheme()); 3150 } catch (Exception e) { 3151 // Empty 3152 } 3153 theme.applyStyle(resid, false); 3154 } 3155 } 3156 3157 /** 3158 * Launch an activity for which you would like a result when it finished. 3159 * When this activity exits, your 3160 * onActivityResult() method will be called with the given requestCode. 3161 * Using a negative requestCode is the same as calling 3162 * {@link #startActivity} (the activity is not launched as a sub-activity). 3163 * 3164 * <p>Note that this method should only be used with Intent protocols 3165 * that are defined to return a result. In other protocols (such as 3166 * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may 3167 * not get the result when you expect. For example, if the activity you 3168 * are launching uses the singleTask launch mode, it will not run in your 3169 * task and thus you will immediately receive a cancel result. 3170 * 3171 * <p>As a special case, if you call startActivityForResult() with a requestCode 3172 * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your 3173 * activity, then your window will not be displayed until a result is 3174 * returned back from the started activity. This is to avoid visible 3175 * flickering when redirecting to another activity. 3176 * 3177 * <p>This method throws {@link android.content.ActivityNotFoundException} 3178 * if there was no Activity found to run the given Intent. 3179 * 3180 * @param intent The intent to start. 3181 * @param requestCode If >= 0, this code will be returned in 3182 * onActivityResult() when the activity exits. 3183 * 3184 * @throws android.content.ActivityNotFoundException 3185 * 3186 * @see #startActivity 3187 */ 3188 public void startActivityForResult(Intent intent, int requestCode) { 3189 if (mParent == null) { 3190 Instrumentation.ActivityResult ar = 3191 mInstrumentation.execStartActivity( 3192 this, mMainThread.getApplicationThread(), mToken, this, 3193 intent, requestCode); 3194 if (ar != null) { 3195 mMainThread.sendActivityResult( 3196 mToken, mEmbeddedID, requestCode, ar.getResultCode(), 3197 ar.getResultData()); 3198 } 3199 if (requestCode >= 0) { 3200 // If this start is requesting a result, we can avoid making 3201 // the activity visible until the result is received. Setting 3202 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 3203 // activity hidden during this time, to avoid flickering. 3204 // This can only be done when a result is requested because 3205 // that guarantees we will get information back when the 3206 // activity is finished, no matter what happens to it. 3207 mStartedActivity = true; 3208 } 3209 } else { 3210 mParent.startActivityFromChild(this, intent, requestCode); 3211 } 3212 } 3213 3214 /** 3215 * Like {@link #startActivityForResult(Intent, int)}, but allowing you 3216 * to use a IntentSender to describe the activity to be started. If 3217 * the IntentSender is for an activity, that activity will be started 3218 * as if you had called the regular {@link #startActivityForResult(Intent, int)} 3219 * here; otherwise, its associated action will be executed (such as 3220 * sending a broadcast) as if you had called 3221 * {@link IntentSender#sendIntent IntentSender.sendIntent} on it. 3222 * 3223 * @param intent The IntentSender to launch. 3224 * @param requestCode If >= 0, this code will be returned in 3225 * onActivityResult() when the activity exits. 3226 * @param fillInIntent If non-null, this will be provided as the 3227 * intent parameter to {@link IntentSender#sendIntent}. 3228 * @param flagsMask Intent flags in the original IntentSender that you 3229 * would like to change. 3230 * @param flagsValues Desired values for any bits set in 3231 * <var>flagsMask</var> 3232 * @param extraFlags Always set to 0. 3233 */ 3234 public void startIntentSenderForResult(IntentSender intent, int requestCode, 3235 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 3236 throws IntentSender.SendIntentException { 3237 if (mParent == null) { 3238 startIntentSenderForResultInner(intent, requestCode, fillInIntent, 3239 flagsMask, flagsValues, this); 3240 } else { 3241 mParent.startIntentSenderFromChild(this, intent, requestCode, 3242 fillInIntent, flagsMask, flagsValues, extraFlags); 3243 } 3244 } 3245 3246 private void startIntentSenderForResultInner(IntentSender intent, int requestCode, 3247 Intent fillInIntent, int flagsMask, int flagsValues, Activity activity) 3248 throws IntentSender.SendIntentException { 3249 try { 3250 String resolvedType = null; 3251 if (fillInIntent != null) { 3252 fillInIntent.setAllowFds(false); 3253 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); 3254 } 3255 int result = ActivityManagerNative.getDefault() 3256 .startActivityIntentSender(mMainThread.getApplicationThread(), intent, 3257 fillInIntent, resolvedType, mToken, activity.mEmbeddedID, 3258 requestCode, flagsMask, flagsValues); 3259 if (result == IActivityManager.START_CANCELED) { 3260 throw new IntentSender.SendIntentException(); 3261 } 3262 Instrumentation.checkStartActivityResult(result, null); 3263 } catch (RemoteException e) { 3264 } 3265 if (requestCode >= 0) { 3266 // If this start is requesting a result, we can avoid making 3267 // the activity visible until the result is received. Setting 3268 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 3269 // activity hidden during this time, to avoid flickering. 3270 // This can only be done when a result is requested because 3271 // that guarantees we will get information back when the 3272 // activity is finished, no matter what happens to it. 3273 mStartedActivity = true; 3274 } 3275 } 3276 3277 /** 3278 * Launch a new activity. You will not receive any information about when 3279 * the activity exits. This implementation overrides the base version, 3280 * providing information about 3281 * the activity performing the launch. Because of this additional 3282 * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not 3283 * required; if not specified, the new activity will be added to the 3284 * task of the caller. 3285 * 3286 * <p>This method throws {@link android.content.ActivityNotFoundException} 3287 * if there was no Activity found to run the given Intent. 3288 * 3289 * @param intent The intent to start. 3290 * 3291 * @throws android.content.ActivityNotFoundException 3292 * 3293 * @see #startActivityForResult 3294 */ 3295 @Override 3296 public void startActivity(Intent intent) { 3297 startActivityForResult(intent, -1); 3298 } 3299 3300 /** 3301 * Launch a new activity. You will not receive any information about when 3302 * the activity exits. This implementation overrides the base version, 3303 * providing information about 3304 * the activity performing the launch. Because of this additional 3305 * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not 3306 * required; if not specified, the new activity will be added to the 3307 * task of the caller. 3308 * 3309 * <p>This method throws {@link android.content.ActivityNotFoundException} 3310 * if there was no Activity found to run the given Intent. 3311 * 3312 * @param intents The intents to start. 3313 * 3314 * @throws android.content.ActivityNotFoundException 3315 * 3316 * @see #startActivityForResult 3317 */ 3318 @Override 3319 public void startActivities(Intent[] intents) { 3320 mInstrumentation.execStartActivities(this, mMainThread.getApplicationThread(), 3321 mToken, this, intents); 3322 } 3323 3324 /** 3325 * Like {@link #startActivity(Intent)}, but taking a IntentSender 3326 * to start; see 3327 * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int)} 3328 * for more information. 3329 * 3330 * @param intent The IntentSender to launch. 3331 * @param fillInIntent If non-null, this will be provided as the 3332 * intent parameter to {@link IntentSender#sendIntent}. 3333 * @param flagsMask Intent flags in the original IntentSender that you 3334 * would like to change. 3335 * @param flagsValues Desired values for any bits set in 3336 * <var>flagsMask</var> 3337 * @param extraFlags Always set to 0. 3338 */ 3339 public void startIntentSender(IntentSender intent, 3340 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 3341 throws IntentSender.SendIntentException { 3342 startIntentSenderForResult(intent, -1, fillInIntent, flagsMask, 3343 flagsValues, extraFlags); 3344 } 3345 3346 /** 3347 * A special variation to launch an activity only if a new activity 3348 * instance is needed to handle the given Intent. In other words, this is 3349 * just like {@link #startActivityForResult(Intent, int)} except: if you are 3350 * using the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag, or 3351 * singleTask or singleTop 3352 * {@link android.R.styleable#AndroidManifestActivity_launchMode launchMode}, 3353 * and the activity 3354 * that handles <var>intent</var> is the same as your currently running 3355 * activity, then a new instance is not needed. In this case, instead of 3356 * the normal behavior of calling {@link #onNewIntent} this function will 3357 * return and you can handle the Intent yourself. 3358 * 3359 * <p>This function can only be called from a top-level activity; if it is 3360 * called from a child activity, a runtime exception will be thrown. 3361 * 3362 * @param intent The intent to start. 3363 * @param requestCode If >= 0, this code will be returned in 3364 * onActivityResult() when the activity exits, as described in 3365 * {@link #startActivityForResult}. 3366 * 3367 * @return If a new activity was launched then true is returned; otherwise 3368 * false is returned and you must handle the Intent yourself. 3369 * 3370 * @see #startActivity 3371 * @see #startActivityForResult 3372 */ 3373 public boolean startActivityIfNeeded(Intent intent, int requestCode) { 3374 if (mParent == null) { 3375 int result = IActivityManager.START_RETURN_INTENT_TO_CALLER; 3376 try { 3377 intent.setAllowFds(false); 3378 result = ActivityManagerNative.getDefault() 3379 .startActivity(mMainThread.getApplicationThread(), 3380 intent, intent.resolveTypeIfNeeded( 3381 getContentResolver()), 3382 null, 0, 3383 mToken, mEmbeddedID, requestCode, true, false, 3384 null, null, false); 3385 } catch (RemoteException e) { 3386 // Empty 3387 } 3388 3389 Instrumentation.checkStartActivityResult(result, intent); 3390 3391 if (requestCode >= 0) { 3392 // If this start is requesting a result, we can avoid making 3393 // the activity visible until the result is received. Setting 3394 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 3395 // activity hidden during this time, to avoid flickering. 3396 // This can only be done when a result is requested because 3397 // that guarantees we will get information back when the 3398 // activity is finished, no matter what happens to it. 3399 mStartedActivity = true; 3400 } 3401 return result != IActivityManager.START_RETURN_INTENT_TO_CALLER; 3402 } 3403 3404 throw new UnsupportedOperationException( 3405 "startActivityIfNeeded can only be called from a top-level activity"); 3406 } 3407 3408 /** 3409 * Special version of starting an activity, for use when you are replacing 3410 * other activity components. You can use this to hand the Intent off 3411 * to the next Activity that can handle it. You typically call this in 3412 * {@link #onCreate} with the Intent returned by {@link #getIntent}. 3413 * 3414 * @param intent The intent to dispatch to the next activity. For 3415 * correct behavior, this must be the same as the Intent that started 3416 * your own activity; the only changes you can make are to the extras 3417 * inside of it. 3418 * 3419 * @return Returns a boolean indicating whether there was another Activity 3420 * to start: true if there was a next activity to start, false if there 3421 * wasn't. In general, if true is returned you will then want to call 3422 * finish() on yourself. 3423 */ 3424 public boolean startNextMatchingActivity(Intent intent) { 3425 if (mParent == null) { 3426 try { 3427 intent.setAllowFds(false); 3428 return ActivityManagerNative.getDefault() 3429 .startNextMatchingActivity(mToken, intent); 3430 } catch (RemoteException e) { 3431 // Empty 3432 } 3433 return false; 3434 } 3435 3436 throw new UnsupportedOperationException( 3437 "startNextMatchingActivity can only be called from a top-level activity"); 3438 } 3439 3440 /** 3441 * This is called when a child activity of this one calls its 3442 * {@link #startActivity} or {@link #startActivityForResult} method. 3443 * 3444 * <p>This method throws {@link android.content.ActivityNotFoundException} 3445 * if there was no Activity found to run the given Intent. 3446 * 3447 * @param child The activity making the call. 3448 * @param intent The intent to start. 3449 * @param requestCode Reply request code. < 0 if reply is not requested. 3450 * 3451 * @throws android.content.ActivityNotFoundException 3452 * 3453 * @see #startActivity 3454 * @see #startActivityForResult 3455 */ 3456 public void startActivityFromChild(Activity child, Intent intent, 3457 int requestCode) { 3458 Instrumentation.ActivityResult ar = 3459 mInstrumentation.execStartActivity( 3460 this, mMainThread.getApplicationThread(), mToken, child, 3461 intent, requestCode); 3462 if (ar != null) { 3463 mMainThread.sendActivityResult( 3464 mToken, child.mEmbeddedID, requestCode, 3465 ar.getResultCode(), ar.getResultData()); 3466 } 3467 } 3468 3469 /** 3470 * This is called when a Fragment in this activity calls its 3471 * {@link Fragment#startActivity} or {@link Fragment#startActivityForResult} 3472 * method. 3473 * 3474 * <p>This method throws {@link android.content.ActivityNotFoundException} 3475 * if there was no Activity found to run the given Intent. 3476 * 3477 * @param fragment The fragment making the call. 3478 * @param intent The intent to start. 3479 * @param requestCode Reply request code. < 0 if reply is not requested. 3480 * 3481 * @throws android.content.ActivityNotFoundException 3482 * 3483 * @see Fragment#startActivity 3484 * @see Fragment#startActivityForResult 3485 */ 3486 public void startActivityFromFragment(Fragment fragment, Intent intent, 3487 int requestCode) { 3488 Instrumentation.ActivityResult ar = 3489 mInstrumentation.execStartActivity( 3490 this, mMainThread.getApplicationThread(), mToken, fragment, 3491 intent, requestCode); 3492 if (ar != null) { 3493 mMainThread.sendActivityResult( 3494 mToken, fragment.mWho, requestCode, 3495 ar.getResultCode(), ar.getResultData()); 3496 } 3497 } 3498 3499 /** 3500 * Like {@link #startActivityFromChild(Activity, Intent, int)}, but 3501 * taking a IntentSender; see 3502 * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int)} 3503 * for more information. 3504 */ 3505 public void startIntentSenderFromChild(Activity child, IntentSender intent, 3506 int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, 3507 int extraFlags) 3508 throws IntentSender.SendIntentException { 3509 startIntentSenderForResultInner(intent, requestCode, fillInIntent, 3510 flagsMask, flagsValues, child); 3511 } 3512 3513 /** 3514 * Call immediately after one of the flavors of {@link #startActivity(Intent)} 3515 * or {@link #finish} to specify an explicit transition animation to 3516 * perform next. 3517 * @param enterAnim A resource ID of the animation resource to use for 3518 * the incoming activity. Use 0 for no animation. 3519 * @param exitAnim A resource ID of the animation resource to use for 3520 * the outgoing activity. Use 0 for no animation. 3521 */ 3522 public void overridePendingTransition(int enterAnim, int exitAnim) { 3523 try { 3524 ActivityManagerNative.getDefault().overridePendingTransition( 3525 mToken, getPackageName(), enterAnim, exitAnim); 3526 } catch (RemoteException e) { 3527 } 3528 } 3529 3530 /** 3531 * Call this to set the result that your activity will return to its 3532 * caller. 3533 * 3534 * @param resultCode The result code to propagate back to the originating 3535 * activity, often RESULT_CANCELED or RESULT_OK 3536 * 3537 * @see #RESULT_CANCELED 3538 * @see #RESULT_OK 3539 * @see #RESULT_FIRST_USER 3540 * @see #setResult(int, Intent) 3541 */ 3542 public final void setResult(int resultCode) { 3543 synchronized (this) { 3544 mResultCode = resultCode; 3545 mResultData = null; 3546 } 3547 } 3548 3549 /** 3550 * Call this to set the result that your activity will return to its 3551 * caller. 3552 * 3553 * @param resultCode The result code to propagate back to the originating 3554 * activity, often RESULT_CANCELED or RESULT_OK 3555 * @param data The data to propagate back to the originating activity. 3556 * 3557 * @see #RESULT_CANCELED 3558 * @see #RESULT_OK 3559 * @see #RESULT_FIRST_USER 3560 * @see #setResult(int) 3561 */ 3562 public final void setResult(int resultCode, Intent data) { 3563 synchronized (this) { 3564 mResultCode = resultCode; 3565 mResultData = data; 3566 } 3567 } 3568 3569 /** 3570 * Return the name of the package that invoked this activity. This is who 3571 * the data in {@link #setResult setResult()} will be sent to. You can 3572 * use this information to validate that the recipient is allowed to 3573 * receive the data. 3574 * 3575 * <p>Note: if the calling activity is not expecting a result (that is it 3576 * did not use the {@link #startActivityForResult} 3577 * form that includes a request code), then the calling package will be 3578 * null. 3579 * 3580 * @return The package of the activity that will receive your 3581 * reply, or null if none. 3582 */ 3583 public String getCallingPackage() { 3584 try { 3585 return ActivityManagerNative.getDefault().getCallingPackage(mToken); 3586 } catch (RemoteException e) { 3587 return null; 3588 } 3589 } 3590 3591 /** 3592 * Return the name of the activity that invoked this activity. This is 3593 * who the data in {@link #setResult setResult()} will be sent to. You 3594 * can use this information to validate that the recipient is allowed to 3595 * receive the data. 3596 * 3597 * <p>Note: if the calling activity is not expecting a result (that is it 3598 * did not use the {@link #startActivityForResult} 3599 * form that includes a request code), then the calling package will be 3600 * null. 3601 * 3602 * @return String The full name of the activity that will receive your 3603 * reply, or null if none. 3604 */ 3605 public ComponentName getCallingActivity() { 3606 try { 3607 return ActivityManagerNative.getDefault().getCallingActivity(mToken); 3608 } catch (RemoteException e) { 3609 return null; 3610 } 3611 } 3612 3613 /** 3614 * Control whether this activity's main window is visible. This is intended 3615 * only for the special case of an activity that is not going to show a 3616 * UI itself, but can't just finish prior to onResume() because it needs 3617 * to wait for a service binding or such. Setting this to false allows 3618 * you to prevent your UI from being shown during that time. 3619 * 3620 * <p>The default value for this is taken from the 3621 * {@link android.R.attr#windowNoDisplay} attribute of the activity's theme. 3622 */ 3623 public void setVisible(boolean visible) { 3624 if (mVisibleFromClient != visible) { 3625 mVisibleFromClient = visible; 3626 if (mVisibleFromServer) { 3627 if (visible) makeVisible(); 3628 else mDecor.setVisibility(View.INVISIBLE); 3629 } 3630 } 3631 } 3632 3633 void makeVisible() { 3634 if (!mWindowAdded) { 3635 ViewManager wm = getWindowManager(); 3636 wm.addView(mDecor, getWindow().getAttributes()); 3637 mWindowAdded = true; 3638 } 3639 mDecor.setVisibility(View.VISIBLE); 3640 } 3641 3642 /** 3643 * Check to see whether this activity is in the process of finishing, 3644 * either because you called {@link #finish} on it or someone else 3645 * has requested that it finished. This is often used in 3646 * {@link #onPause} to determine whether the activity is simply pausing or 3647 * completely finishing. 3648 * 3649 * @return If the activity is finishing, returns true; else returns false. 3650 * 3651 * @see #finish 3652 */ 3653 public boolean isFinishing() { 3654 return mFinished; 3655 } 3656 3657 /** 3658 * Check to see whether this activity is in the process of being destroyed in order to be 3659 * recreated with a new configuration. This is often used in 3660 * {@link #onStop} to determine whether the state needs to be cleaned up or will be passed 3661 * on to the next instance of the activity via {@link #onRetainNonConfigurationInstance()}. 3662 * 3663 * @return If the activity is being torn down in order to be recreated with a new configuration, 3664 * returns true; else returns false. 3665 */ 3666 public boolean isChangingConfigurations() { 3667 return mChangingConfigurations; 3668 } 3669 3670 /** 3671 * Cause this Activity to be recreated with a new instance. This results 3672 * in essentially the same flow as when the Activity is created due to 3673 * a configuration change -- the current instance will go through its 3674 * lifecycle to {@link #onDestroy} and a new instance then created after it. 3675 */ 3676 public void recreate() { 3677 if (mParent != null) { 3678 throw new IllegalStateException("Can only be called on top-level activity"); 3679 } 3680 if (Looper.myLooper() != mMainThread.getLooper()) { 3681 throw new IllegalStateException("Must be called from main thread"); 3682 } 3683 mMainThread.requestRelaunchActivity(mToken, null, null, 0, false, null, false); 3684 } 3685 3686 /** 3687 * Call this when your activity is done and should be closed. The 3688 * ActivityResult is propagated back to whoever launched you via 3689 * onActivityResult(). 3690 */ 3691 public void finish() { 3692 if (mParent == null) { 3693 int resultCode; 3694 Intent resultData; 3695 synchronized (this) { 3696 resultCode = mResultCode; 3697 resultData = mResultData; 3698 } 3699 if (false) Log.v(TAG, "Finishing self: token=" + mToken); 3700 try { 3701 if (resultData != null) { 3702 resultData.setAllowFds(false); 3703 } 3704 if (ActivityManagerNative.getDefault() 3705 .finishActivity(mToken, resultCode, resultData)) { 3706 mFinished = true; 3707 } 3708 } catch (RemoteException e) { 3709 // Empty 3710 } 3711 } else { 3712 mParent.finishFromChild(this); 3713 } 3714 } 3715 3716 /** 3717 * This is called when a child activity of this one calls its 3718 * {@link #finish} method. The default implementation simply calls 3719 * finish() on this activity (the parent), finishing the entire group. 3720 * 3721 * @param child The activity making the call. 3722 * 3723 * @see #finish 3724 */ 3725 public void finishFromChild(Activity child) { 3726 finish(); 3727 } 3728 3729 /** 3730 * Force finish another activity that you had previously started with 3731 * {@link #startActivityForResult}. 3732 * 3733 * @param requestCode The request code of the activity that you had 3734 * given to startActivityForResult(). If there are multiple 3735 * activities started with this request code, they 3736 * will all be finished. 3737 */ 3738 public void finishActivity(int requestCode) { 3739 if (mParent == null) { 3740 try { 3741 ActivityManagerNative.getDefault() 3742 .finishSubActivity(mToken, mEmbeddedID, requestCode); 3743 } catch (RemoteException e) { 3744 // Empty 3745 } 3746 } else { 3747 mParent.finishActivityFromChild(this, requestCode); 3748 } 3749 } 3750 3751 /** 3752 * This is called when a child activity of this one calls its 3753 * finishActivity(). 3754 * 3755 * @param child The activity making the call. 3756 * @param requestCode Request code that had been used to start the 3757 * activity. 3758 */ 3759 public void finishActivityFromChild(Activity child, int requestCode) { 3760 try { 3761 ActivityManagerNative.getDefault() 3762 .finishSubActivity(mToken, child.mEmbeddedID, requestCode); 3763 } catch (RemoteException e) { 3764 // Empty 3765 } 3766 } 3767 3768 /** 3769 * Called when an activity you launched exits, giving you the requestCode 3770 * you started it with, the resultCode it returned, and any additional 3771 * data from it. The <var>resultCode</var> will be 3772 * {@link #RESULT_CANCELED} if the activity explicitly returned that, 3773 * didn't return any result, or crashed during its operation. 3774 * 3775 * <p>You will receive this call immediately before onResume() when your 3776 * activity is re-starting. 3777 * 3778 * @param requestCode The integer request code originally supplied to 3779 * startActivityForResult(), allowing you to identify who this 3780 * result came from. 3781 * @param resultCode The integer result code returned by the child activity 3782 * through its setResult(). 3783 * @param data An Intent, which can return result data to the caller 3784 * (various data can be attached to Intent "extras"). 3785 * 3786 * @see #startActivityForResult 3787 * @see #createPendingResult 3788 * @see #setResult(int) 3789 */ 3790 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 3791 } 3792 3793 /** 3794 * Create a new PendingIntent object which you can hand to others 3795 * for them to use to send result data back to your 3796 * {@link #onActivityResult} callback. The created object will be either 3797 * one-shot (becoming invalid after a result is sent back) or multiple 3798 * (allowing any number of results to be sent through it). 3799 * 3800 * @param requestCode Private request code for the sender that will be 3801 * associated with the result data when it is returned. The sender can not 3802 * modify this value, allowing you to identify incoming results. 3803 * @param data Default data to supply in the result, which may be modified 3804 * by the sender. 3805 * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT PendingIntent.FLAG_ONE_SHOT}, 3806 * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE}, 3807 * {@link PendingIntent#FLAG_CANCEL_CURRENT PendingIntent.FLAG_CANCEL_CURRENT}, 3808 * {@link PendingIntent#FLAG_UPDATE_CURRENT PendingIntent.FLAG_UPDATE_CURRENT}, 3809 * or any of the flags as supported by 3810 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 3811 * of the intent that can be supplied when the actual send happens. 3812 * 3813 * @return Returns an existing or new PendingIntent matching the given 3814 * parameters. May return null only if 3815 * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE} has been 3816 * supplied. 3817 * 3818 * @see PendingIntent 3819 */ 3820 public PendingIntent createPendingResult(int requestCode, Intent data, 3821 int flags) { 3822 String packageName = getPackageName(); 3823 try { 3824 data.setAllowFds(false); 3825 IIntentSender target = 3826 ActivityManagerNative.getDefault().getIntentSender( 3827 IActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName, 3828 mParent == null ? mToken : mParent.mToken, 3829 mEmbeddedID, requestCode, new Intent[] { data }, null, flags); 3830 return target != null ? new PendingIntent(target) : null; 3831 } catch (RemoteException e) { 3832 // Empty 3833 } 3834 return null; 3835 } 3836 3837 /** 3838 * Change the desired orientation of this activity. If the activity 3839 * is currently in the foreground or otherwise impacting the screen 3840 * orientation, the screen will immediately be changed (possibly causing 3841 * the activity to be restarted). Otherwise, this will be used the next 3842 * time the activity is visible. 3843 * 3844 * @param requestedOrientation An orientation constant as used in 3845 * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}. 3846 */ 3847 public void setRequestedOrientation(int requestedOrientation) { 3848 if (mParent == null) { 3849 try { 3850 ActivityManagerNative.getDefault().setRequestedOrientation( 3851 mToken, requestedOrientation); 3852 } catch (RemoteException e) { 3853 // Empty 3854 } 3855 } else { 3856 mParent.setRequestedOrientation(requestedOrientation); 3857 } 3858 } 3859 3860 /** 3861 * Return the current requested orientation of the activity. This will 3862 * either be the orientation requested in its component's manifest, or 3863 * the last requested orientation given to 3864 * {@link #setRequestedOrientation(int)}. 3865 * 3866 * @return Returns an orientation constant as used in 3867 * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}. 3868 */ 3869 public int getRequestedOrientation() { 3870 if (mParent == null) { 3871 try { 3872 return ActivityManagerNative.getDefault() 3873 .getRequestedOrientation(mToken); 3874 } catch (RemoteException e) { 3875 // Empty 3876 } 3877 } else { 3878 return mParent.getRequestedOrientation(); 3879 } 3880 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3881 } 3882 3883 /** 3884