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