Activity.java revision d7ad54e603cedcb5a927e92cd231d7e8549831ef
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.annotation.CallSuper; 20import android.annotation.DrawableRes; 21import android.annotation.IdRes; 22import android.annotation.IntDef; 23import android.annotation.LayoutRes; 24import android.annotation.MainThread; 25import android.annotation.NonNull; 26import android.annotation.Nullable; 27import android.annotation.RequiresPermission; 28import android.annotation.StyleRes; 29import android.os.PersistableBundle; 30import android.transition.Scene; 31import android.transition.TransitionManager; 32import android.util.ArrayMap; 33import android.util.SuperNotCalledException; 34import android.view.Window.WindowControllerCallback; 35import android.widget.Toolbar; 36 37import com.android.internal.app.IVoiceInteractor; 38import com.android.internal.app.WindowDecorActionBar; 39import com.android.internal.app.ToolbarActionBar; 40 41import android.annotation.SystemApi; 42import android.app.admin.DevicePolicyManager; 43import android.app.assist.AssistContent; 44import android.content.ComponentCallbacks2; 45import android.content.ComponentName; 46import android.content.ContentResolver; 47import android.content.Context; 48import android.content.CursorLoader; 49import android.content.IIntentSender; 50import android.content.Intent; 51import android.content.IntentSender; 52import android.content.SharedPreferences; 53import android.content.pm.ActivityInfo; 54import android.content.pm.PackageManager; 55import android.content.pm.PackageManager.NameNotFoundException; 56import android.content.res.Configuration; 57import android.content.res.Resources; 58import android.content.res.TypedArray; 59import android.database.Cursor; 60import android.graphics.Bitmap; 61import android.graphics.Canvas; 62import android.graphics.drawable.Drawable; 63import android.graphics.Rect; 64import android.media.AudioManager; 65import android.media.session.MediaController; 66import android.net.Uri; 67import android.os.Build; 68import android.os.Bundle; 69import android.os.Handler; 70import android.os.IBinder; 71import android.os.Looper; 72import android.os.Parcelable; 73import android.os.RemoteException; 74import android.os.StrictMode; 75import android.os.UserHandle; 76import android.text.Selection; 77import android.text.SpannableStringBuilder; 78import android.text.TextUtils; 79import android.text.method.TextKeyListener; 80import android.util.AttributeSet; 81import android.util.EventLog; 82import android.util.Log; 83import android.util.PrintWriterPrinter; 84import android.util.Slog; 85import android.util.SparseArray; 86import android.view.ActionMode; 87import android.view.ContextMenu; 88import android.view.ContextMenu.ContextMenuInfo; 89import android.view.ContextThemeWrapper; 90import android.view.KeyEvent; 91import android.view.LayoutInflater; 92import android.view.Menu; 93import android.view.MenuInflater; 94import android.view.MenuItem; 95import android.view.MotionEvent; 96import com.android.internal.policy.PhoneWindow; 97import android.view.SearchEvent; 98import android.view.View; 99import android.view.View.OnCreateContextMenuListener; 100import android.view.ViewGroup; 101import android.view.ViewGroup.LayoutParams; 102import android.view.ViewManager; 103import android.view.ViewRootImpl; 104import android.view.Window; 105import android.view.WindowManager; 106import android.view.WindowManagerGlobal; 107import android.view.accessibility.AccessibilityEvent; 108import android.widget.AdapterView; 109 110import java.io.FileDescriptor; 111import java.io.PrintWriter; 112import java.lang.annotation.Retention; 113import java.lang.annotation.RetentionPolicy; 114import java.util.ArrayList; 115import java.util.HashMap; 116import java.util.List; 117 118/** 119 * An activity is a single, focused thing that the user can do. Almost all 120 * activities interact with the user, so the Activity class takes care of 121 * creating a window for you in which you can place your UI with 122 * {@link #setContentView}. While activities are often presented to the user 123 * as full-screen windows, they can also be used in other ways: as floating 124 * windows (via a theme with {@link android.R.attr#windowIsFloating} set) 125 * or embedded inside of another activity (using {@link ActivityGroup}). 126 * 127 * There are two methods almost all subclasses of Activity will implement: 128 * 129 * <ul> 130 * <li> {@link #onCreate} is where you initialize your activity. Most 131 * importantly, here you will usually call {@link #setContentView(int)} 132 * with a layout resource defining your UI, and using {@link #findViewById} 133 * to retrieve the widgets in that UI that you need to interact with 134 * programmatically. 135 * 136 * <li> {@link #onPause} is where you deal with the user leaving your 137 * activity. Most importantly, any changes made by the user should at this 138 * point be committed (usually to the 139 * {@link android.content.ContentProvider} holding the data). 140 * </ul> 141 * 142 * <p>To be of use with {@link android.content.Context#startActivity Context.startActivity()}, all 143 * activity classes must have a corresponding 144 * {@link android.R.styleable#AndroidManifestActivity <activity>} 145 * declaration in their package's <code>AndroidManifest.xml</code>.</p> 146 * 147 * <p>Topics covered here: 148 * <ol> 149 * <li><a href="#Fragments">Fragments</a> 150 * <li><a href="#ActivityLifecycle">Activity Lifecycle</a> 151 * <li><a href="#ConfigurationChanges">Configuration Changes</a> 152 * <li><a href="#StartingActivities">Starting Activities and Getting Results</a> 153 * <li><a href="#SavingPersistentState">Saving Persistent State</a> 154 * <li><a href="#Permissions">Permissions</a> 155 * <li><a href="#ProcessLifecycle">Process Lifecycle</a> 156 * </ol> 157 * 158 * <div class="special reference"> 159 * <h3>Developer Guides</h3> 160 * <p>The Activity class is an important part of an application's overall lifecycle, 161 * and the way activities are launched and put together is a fundamental 162 * part of the platform's application model. For a detailed perspective on the structure of an 163 * Android application and how activities behave, please read the 164 * <a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> and 165 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a> 166 * developer guides.</p> 167 * 168 * <p>You can also find a detailed discussion about how to create activities in the 169 * <a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a> 170 * developer guide.</p> 171 * </div> 172 * 173 * <a name="Fragments"></a> 174 * <h3>Fragments</h3> 175 * 176 * <p>Starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB}, Activity 177 * implementations can make use of the {@link Fragment} class to better 178 * modularize their code, build more sophisticated user interfaces for larger 179 * screens, and help scale their application between small and large screens. 180 * 181 * <a name="ActivityLifecycle"></a> 182 * <h3>Activity Lifecycle</h3> 183 * 184 * <p>Activities in the system are managed as an <em>activity stack</em>. 185 * When a new activity is started, it is placed on the top of the stack 186 * and becomes the running activity -- the previous activity always remains 187 * below it in the stack, and will not come to the foreground again until 188 * the new activity exits.</p> 189 * 190 * <p>An activity has essentially four states:</p> 191 * <ul> 192 * <li> If an activity in the foreground of the screen (at the top of 193 * the stack), 194 * it is <em>active</em> or <em>running</em>. </li> 195 * <li>If an activity has lost focus but is still visible (that is, a new non-full-sized 196 * or transparent activity has focus on top of your activity), it 197 * is <em>paused</em>. A paused activity is completely alive (it 198 * maintains all state and member information and remains attached to 199 * the window manager), but can be killed by the system in extreme 200 * low memory situations. 201 * <li>If an activity is completely obscured by another activity, 202 * it is <em>stopped</em>. It still retains all state and member information, 203 * however, it is no longer visible to the user so its window is hidden 204 * and it will often be killed by the system when memory is needed 205 * elsewhere.</li> 206 * <li>If an activity is paused or stopped, the system can drop the activity 207 * from memory by either asking it to finish, or simply killing its 208 * process. When it is displayed again to the user, it must be 209 * completely restarted and restored to its previous state.</li> 210 * </ul> 211 * 212 * <p>The following diagram shows the important state paths of an Activity. 213 * The square rectangles represent callback methods you can implement to 214 * perform operations when the Activity moves between states. The colored 215 * ovals are major states the Activity can be in.</p> 216 * 217 * <p><img src="../../../images/activity_lifecycle.png" 218 * alt="State diagram for an Android Activity Lifecycle." border="0" /></p> 219 * 220 * <p>There are three key loops you may be interested in monitoring within your 221 * activity: 222 * 223 * <ul> 224 * <li>The <b>entire lifetime</b> of an activity happens between the first call 225 * to {@link android.app.Activity#onCreate} through to a single final call 226 * to {@link android.app.Activity#onDestroy}. An activity will do all setup 227 * of "global" state in onCreate(), and release all remaining resources in 228 * onDestroy(). For example, if it has a thread running in the background 229 * to download data from the network, it may create that thread in onCreate() 230 * and then stop the thread in onDestroy(). 231 * 232 * <li>The <b>visible lifetime</b> of an activity happens between a call to 233 * {@link android.app.Activity#onStart} until a corresponding call to 234 * {@link android.app.Activity#onStop}. During this time the user can see the 235 * activity on-screen, though it may not be in the foreground and interacting 236 * with the user. Between these two methods you can maintain resources that 237 * are needed to show the activity to the user. For example, you can register 238 * a {@link android.content.BroadcastReceiver} in onStart() to monitor for changes 239 * that impact your UI, and unregister it in onStop() when the user no 240 * longer sees what you are displaying. The onStart() and onStop() methods 241 * can be called multiple times, as the activity becomes visible and hidden 242 * to the user. 243 * 244 * <li>The <b>foreground lifetime</b> of an activity happens between a call to 245 * {@link android.app.Activity#onResume} until a corresponding call to 246 * {@link android.app.Activity#onPause}. During this time the activity is 247 * in front of all other activities and interacting with the user. An activity 248 * can frequently go between the resumed and paused states -- for example when 249 * the device goes to sleep, when an activity result is delivered, when a new 250 * intent is delivered -- so the code in these methods should be fairly 251 * lightweight. 252 * </ul> 253 * 254 * <p>The entire lifecycle of an activity is defined by the following 255 * Activity methods. All of these are hooks that you can override 256 * to do appropriate work when the activity changes state. All 257 * activities will implement {@link android.app.Activity#onCreate} 258 * to do their initial setup; many will also implement 259 * {@link android.app.Activity#onPause} to commit changes to data and 260 * otherwise prepare to stop interacting with the user. You should always 261 * call up to your superclass when implementing these methods.</p> 262 * 263 * </p> 264 * <pre class="prettyprint"> 265 * public class Activity extends ApplicationContext { 266 * protected void onCreate(Bundle savedInstanceState); 267 * 268 * protected void onStart(); 269 * 270 * protected void onRestart(); 271 * 272 * protected void onResume(); 273 * 274 * protected void onPause(); 275 * 276 * protected void onStop(); 277 * 278 * protected void onDestroy(); 279 * } 280 * </pre> 281 * 282 * <p>In general the movement through an activity's lifecycle looks like 283 * this:</p> 284 * 285 * <table border="2" width="85%" align="center" frame="hsides" rules="rows"> 286 * <colgroup align="left" span="3" /> 287 * <colgroup align="left" /> 288 * <colgroup align="center" /> 289 * <colgroup align="center" /> 290 * 291 * <thead> 292 * <tr><th colspan="3">Method</th> <th>Description</th> <th>Killable?</th> <th>Next</th></tr> 293 * </thead> 294 * 295 * <tbody> 296 * <tr><th colspan="3" align="left" border="0">{@link android.app.Activity#onCreate onCreate()}</th> 297 * <td>Called when the activity is first created. 298 * This is where you should do all of your normal static set up: 299 * create views, bind data to lists, etc. This method also 300 * provides you with a Bundle containing the activity's previously 301 * frozen state, if there was one. 302 * <p>Always followed by <code>onStart()</code>.</td> 303 * <td align="center">No</td> 304 * <td align="center"><code>onStart()</code></td> 305 * </tr> 306 * 307 * <tr><td rowspan="5" style="border-left: none; border-right: none;"> </td> 308 * <th colspan="2" align="left" border="0">{@link android.app.Activity#onRestart onRestart()}</th> 309 * <td>Called after your activity has been stopped, prior to it being 310 * started again. 311 * <p>Always followed by <code>onStart()</code></td> 312 * <td align="center">No</td> 313 * <td align="center"><code>onStart()</code></td> 314 * </tr> 315 * 316 * <tr><th colspan="2" align="left" border="0">{@link android.app.Activity#onStart onStart()}</th> 317 * <td>Called when the activity is becoming visible to the user. 318 * <p>Followed by <code>onResume()</code> if the activity comes 319 * to the foreground, or <code>onStop()</code> if it becomes hidden.</td> 320 * <td align="center">No</td> 321 * <td align="center"><code>onResume()</code> or <code>onStop()</code></td> 322 * </tr> 323 * 324 * <tr><td rowspan="2" style="border-left: none;"> </td> 325 * <th align="left" border="0">{@link android.app.Activity#onResume onResume()}</th> 326 * <td>Called when the activity will start 327 * interacting with the user. At this point your activity is at 328 * the top of the activity stack, with user input going to it. 329 * <p>Always followed by <code>onPause()</code>.</td> 330 * <td align="center">No</td> 331 * <td align="center"><code>onPause()</code></td> 332 * </tr> 333 * 334 * <tr><th align="left" border="0">{@link android.app.Activity#onPause onPause()}</th> 335 * <td>Called when the system is about to start resuming a previous 336 * activity. This is typically used to commit unsaved changes to 337 * persistent data, stop animations and other things that may be consuming 338 * CPU, etc. Implementations of this method must be very quick because 339 * the next activity will not be resumed until this method returns. 340 * <p>Followed by either <code>onResume()</code> if the activity 341 * returns back to the front, or <code>onStop()</code> if it becomes 342 * invisible to the user.</td> 343 * <td align="center"><font color="#800000"><strong>Pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB}</strong></font></td> 344 * <td align="center"><code>onResume()</code> or<br> 345 * <code>onStop()</code></td> 346 * </tr> 347 * 348 * <tr><th colspan="2" align="left" border="0">{@link android.app.Activity#onStop onStop()}</th> 349 * <td>Called when the activity is no longer visible to the user, because 350 * another activity has been resumed and is covering this one. This 351 * may happen either because a new activity is being started, an existing 352 * one is being brought in front of this one, or this one is being 353 * destroyed. 354 * <p>Followed by either <code>onRestart()</code> if 355 * this activity is coming back to interact with the user, or 356 * <code>onDestroy()</code> if this activity is going away.</td> 357 * <td align="center"><font color="#800000"><strong>Yes</strong></font></td> 358 * <td align="center"><code>onRestart()</code> or<br> 359 * <code>onDestroy()</code></td> 360 * </tr> 361 * 362 * <tr><th colspan="3" align="left" border="0">{@link android.app.Activity#onDestroy onDestroy()}</th> 363 * <td>The final call you receive before your 364 * activity is destroyed. This can happen either because the 365 * activity is finishing (someone called {@link Activity#finish} on 366 * it, or because the system is temporarily destroying this 367 * instance of the activity to save space. You can distinguish 368 * between these two scenarios with the {@link 369 * Activity#isFinishing} method.</td> 370 * <td align="center"><font color="#800000"><strong>Yes</strong></font></td> 371 * <td align="center"><em>nothing</em></td> 372 * </tr> 373 * </tbody> 374 * </table> 375 * 376 * <p>Note the "Killable" column in the above table -- for those methods that 377 * are marked as being killable, after that method returns the process hosting the 378 * activity may be killed by the system <em>at any time</em> without another line 379 * of its code being executed. Because of this, you should use the 380 * {@link #onPause} method to write any persistent data (such as user edits) 381 * to storage. In addition, the method 382 * {@link #onSaveInstanceState(Bundle)} is called before placing the activity 383 * in such a background state, allowing you to save away any dynamic instance 384 * state in your activity into the given Bundle, to be later received in 385 * {@link #onCreate} if the activity needs to be re-created. 386 * See the <a href="#ProcessLifecycle">Process Lifecycle</a> 387 * section for more information on how the lifecycle of a process is tied 388 * to the activities it is hosting. Note that it is important to save 389 * persistent data in {@link #onPause} instead of {@link #onSaveInstanceState} 390 * because the latter is not part of the lifecycle callbacks, so will not 391 * be called in every situation as described in its documentation.</p> 392 * 393 * <p class="note">Be aware that these semantics will change slightly between 394 * applications targeting platforms starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB} 395 * vs. those targeting prior platforms. Starting with Honeycomb, an application 396 * is not in the killable state until its {@link #onStop} has returned. This 397 * impacts when {@link #onSaveInstanceState(Bundle)} may be called (it may be 398 * safely called after {@link #onPause()} and allows and application to safely 399 * wait until {@link #onStop()} to save persistent state.</p> 400 * 401 * <p>For those methods that are not marked as being killable, the activity's 402 * process will not be killed by the system starting from the time the method 403 * is called and continuing after it returns. Thus an activity is in the killable 404 * state, for example, between after <code>onPause()</code> to the start of 405 * <code>onResume()</code>.</p> 406 * 407 * <a name="ConfigurationChanges"></a> 408 * <h3>Configuration Changes</h3> 409 * 410 * <p>If the configuration of the device (as defined by the 411 * {@link Configuration Resources.Configuration} class) changes, 412 * then anything displaying a user interface will need to update to match that 413 * configuration. Because Activity is the primary mechanism for interacting 414 * with the user, it includes special support for handling configuration 415 * changes.</p> 416 * 417 * <p>Unless you specify otherwise, a configuration change (such as a change 418 * in screen orientation, language, input devices, etc) will cause your 419 * current activity to be <em>destroyed</em>, going through the normal activity 420 * lifecycle process of {@link #onPause}, 421 * {@link #onStop}, and {@link #onDestroy} as appropriate. If the activity 422 * had been in the foreground or visible to the user, once {@link #onDestroy} is 423 * called in that instance then a new instance of the activity will be 424 * created, with whatever savedInstanceState the previous instance had generated 425 * from {@link #onSaveInstanceState}.</p> 426 * 427 * <p>This is done because any application resource, 428 * including layout files, can change based on any configuration value. Thus 429 * the only safe way to handle a configuration change is to re-retrieve all 430 * resources, including layouts, drawables, and strings. Because activities 431 * must already know how to save their state and re-create themselves from 432 * that state, this is a convenient way to have an activity restart itself 433 * with a new configuration.</p> 434 * 435 * <p>In some special cases, you may want to bypass restarting of your 436 * activity based on one or more types of configuration changes. This is 437 * done with the {@link android.R.attr#configChanges android:configChanges} 438 * attribute in its manifest. For any types of configuration changes you say 439 * that you handle there, you will receive a call to your current activity's 440 * {@link #onConfigurationChanged} method instead of being restarted. If 441 * a configuration change involves any that you do not handle, however, the 442 * activity will still be restarted and {@link #onConfigurationChanged} 443 * will not be called.</p> 444 * 445 * <a name="StartingActivities"></a> 446 * <h3>Starting Activities and Getting Results</h3> 447 * 448 * <p>The {@link android.app.Activity#startActivity} 449 * method is used to start a 450 * new activity, which will be placed at the top of the activity stack. It 451 * takes a single argument, an {@link android.content.Intent Intent}, 452 * which describes the activity 453 * to be executed.</p> 454 * 455 * <p>Sometimes you want to get a result back from an activity when it 456 * ends. For example, you may start an activity that lets the user pick 457 * a person in a list of contacts; when it ends, it returns the person 458 * that was selected. To do this, you call the 459 * {@link android.app.Activity#startActivityForResult(Intent, int)} 460 * version with a second integer parameter identifying the call. The result 461 * will come back through your {@link android.app.Activity#onActivityResult} 462 * method.</p> 463 * 464 * <p>When an activity exits, it can call 465 * {@link android.app.Activity#setResult(int)} 466 * to return data back to its parent. It must always supply a result code, 467 * which can be the standard results RESULT_CANCELED, RESULT_OK, or any 468 * custom values starting at RESULT_FIRST_USER. In addition, it can optionally 469 * return back an Intent containing any additional data it wants. All of this 470 * information appears back on the 471 * parent's <code>Activity.onActivityResult()</code>, along with the integer 472 * identifier it originally supplied.</p> 473 * 474 * <p>If a child activity fails for any reason (such as crashing), the parent 475 * activity will receive a result with the code RESULT_CANCELED.</p> 476 * 477 * <pre class="prettyprint"> 478 * public class MyActivity extends Activity { 479 * ... 480 * 481 * static final int PICK_CONTACT_REQUEST = 0; 482 * 483 * public boolean onKeyDown(int keyCode, KeyEvent event) { 484 * if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 485 * // When the user center presses, let them pick a contact. 486 * startActivityForResult( 487 * new Intent(Intent.ACTION_PICK, 488 * new Uri("content://contacts")), 489 * PICK_CONTACT_REQUEST); 490 * return true; 491 * } 492 * return false; 493 * } 494 * 495 * protected void onActivityResult(int requestCode, int resultCode, 496 * Intent data) { 497 * if (requestCode == PICK_CONTACT_REQUEST) { 498 * if (resultCode == RESULT_OK) { 499 * // A contact was picked. Here we will just display it 500 * // to the user. 501 * startActivity(new Intent(Intent.ACTION_VIEW, data)); 502 * } 503 * } 504 * } 505 * } 506 * </pre> 507 * 508 * <a name="SavingPersistentState"></a> 509 * <h3>Saving Persistent State</h3> 510 * 511 * <p>There are generally two kinds of persistent state than an activity 512 * will deal with: shared document-like data (typically stored in a SQLite 513 * database using a {@linkplain android.content.ContentProvider content provider}) 514 * and internal state such as user preferences.</p> 515 * 516 * <p>For content provider data, we suggest that activities use a 517 * "edit in place" user model. That is, any edits a user makes are effectively 518 * made immediately without requiring an additional confirmation step. 519 * Supporting this model is generally a simple matter of following two rules:</p> 520 * 521 * <ul> 522 * <li> <p>When creating a new document, the backing database entry or file for 523 * it is created immediately. For example, if the user chooses to write 524 * a new e-mail, a new entry for that e-mail is created as soon as they 525 * start entering data, so that if they go to any other activity after 526 * that point this e-mail will now appear in the list of drafts.</p> 527 * <li> <p>When an activity's <code>onPause()</code> method is called, it should 528 * commit to the backing content provider or file any changes the user 529 * has made. This ensures that those changes will be seen by any other 530 * activity that is about to run. You will probably want to commit 531 * your data even more aggressively at key times during your 532 * activity's lifecycle: for example before starting a new 533 * activity, before finishing your own activity, when the user 534 * switches between input fields, etc.</p> 535 * </ul> 536 * 537 * <p>This model is designed to prevent data loss when a user is navigating 538 * between activities, and allows the system to safely kill an activity (because 539 * system resources are needed somewhere else) at any time after it has been 540 * paused. Note this implies 541 * that the user pressing BACK from your activity does <em>not</em> 542 * mean "cancel" -- it means to leave the activity with its current contents 543 * saved away. Canceling edits in an activity must be provided through 544 * some other mechanism, such as an explicit "revert" or "undo" option.</p> 545 * 546 * <p>See the {@linkplain android.content.ContentProvider content package} for 547 * more information about content providers. These are a key aspect of how 548 * different activities invoke and propagate data between themselves.</p> 549 * 550 * <p>The Activity class also provides an API for managing internal persistent state 551 * associated with an activity. This can be used, for example, to remember 552 * the user's preferred initial display in a calendar (day view or week view) 553 * or the user's default home page in a web browser.</p> 554 * 555 * <p>Activity persistent state is managed 556 * with the method {@link #getPreferences}, 557 * allowing you to retrieve and 558 * modify a set of name/value pairs associated with the activity. To use 559 * preferences that are shared across multiple application components 560 * (activities, receivers, services, providers), you can use the underlying 561 * {@link Context#getSharedPreferences Context.getSharedPreferences()} method 562 * to retrieve a preferences 563 * object stored under a specific name. 564 * (Note that it is not possible to share settings data across application 565 * packages -- for that you will need a content provider.)</p> 566 * 567 * <p>Here is an excerpt from a calendar activity that stores the user's 568 * preferred view mode in its persistent settings:</p> 569 * 570 * <pre class="prettyprint"> 571 * public class CalendarActivity extends Activity { 572 * ... 573 * 574 * static final int DAY_VIEW_MODE = 0; 575 * static final int WEEK_VIEW_MODE = 1; 576 * 577 * private SharedPreferences mPrefs; 578 * private int mCurViewMode; 579 * 580 * protected void onCreate(Bundle savedInstanceState) { 581 * super.onCreate(savedInstanceState); 582 * 583 * SharedPreferences mPrefs = getSharedPreferences(); 584 * mCurViewMode = mPrefs.getInt("view_mode", DAY_VIEW_MODE); 585 * } 586 * 587 * protected void onPause() { 588 * super.onPause(); 589 * 590 * SharedPreferences.Editor ed = mPrefs.edit(); 591 * ed.putInt("view_mode", mCurViewMode); 592 * ed.commit(); 593 * } 594 * } 595 * </pre> 596 * 597 * <a name="Permissions"></a> 598 * <h3>Permissions</h3> 599 * 600 * <p>The ability to start a particular Activity can be enforced when it is 601 * declared in its 602 * manifest's {@link android.R.styleable#AndroidManifestActivity <activity>} 603 * tag. By doing so, other applications will need to declare a corresponding 604 * {@link android.R.styleable#AndroidManifestUsesPermission <uses-permission>} 605 * element in their own manifest to be able to start that activity. 606 * 607 * <p>When starting an Activity you can set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION 608 * Intent.FLAG_GRANT_READ_URI_PERMISSION} and/or {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION 609 * Intent.FLAG_GRANT_WRITE_URI_PERMISSION} on the Intent. This will grant the 610 * Activity access to the specific URIs in the Intent. Access will remain 611 * until the Activity has finished (it will remain across the hosting 612 * process being killed and other temporary destruction). As of 613 * {@link android.os.Build.VERSION_CODES#GINGERBREAD}, if the Activity 614 * was already created and a new Intent is being delivered to 615 * {@link #onNewIntent(Intent)}, any newly granted URI permissions will be added 616 * to the existing ones it holds. 617 * 618 * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> 619 * document for more information on permissions and security in general. 620 * 621 * <a name="ProcessLifecycle"></a> 622 * <h3>Process Lifecycle</h3> 623 * 624 * <p>The Android system attempts to keep application process around for as 625 * long as possible, but eventually will need to remove old processes when 626 * memory runs low. As described in <a href="#ActivityLifecycle">Activity 627 * Lifecycle</a>, the decision about which process to remove is intimately 628 * tied to the state of the user's interaction with it. In general, there 629 * are four states a process can be in based on the activities running in it, 630 * listed here in order of importance. The system will kill less important 631 * processes (the last ones) before it resorts to killing more important 632 * processes (the first ones). 633 * 634 * <ol> 635 * <li> <p>The <b>foreground activity</b> (the activity at the top of the screen 636 * that the user is currently interacting with) is considered the most important. 637 * Its process will only be killed as a last resort, if it uses more memory 638 * than is available on the device. Generally at this point the device has 639 * reached a memory paging state, so this is required in order to keep the user 640 * interface responsive. 641 * <li> <p>A <b>visible activity</b> (an activity that is visible to the user 642 * but not in the foreground, such as one sitting behind a foreground dialog) 643 * is considered extremely important and will not be killed unless that is 644 * required to keep the foreground activity running. 645 * <li> <p>A <b>background activity</b> (an activity that is not visible to 646 * the user and has been paused) is no longer critical, so the system may 647 * safely kill its process to reclaim memory for other foreground or 648 * visible processes. If its process needs to be killed, when the user navigates 649 * back to the activity (making it visible on the screen again), its 650 * {@link #onCreate} method will be called with the savedInstanceState it had previously 651 * supplied in {@link #onSaveInstanceState} so that it can restart itself in the same 652 * state as the user last left it. 653 * <li> <p>An <b>empty process</b> is one hosting no activities or other 654 * application components (such as {@link Service} or 655 * {@link android.content.BroadcastReceiver} classes). These are killed very 656 * quickly by the system as memory becomes low. For this reason, any 657 * background operation you do outside of an activity must be executed in the 658 * context of an activity BroadcastReceiver or Service to ensure that the system 659 * knows it needs to keep your process around. 660 * </ol> 661 * 662 * <p>Sometimes an Activity may need to do a long-running operation that exists 663 * independently of the activity lifecycle itself. An example may be a camera 664 * application that allows you to upload a picture to a web site. The upload 665 * may take a long time, and the application should allow the user to leave 666 * the application will it is executing. To accomplish this, your Activity 667 * should start a {@link Service} in which the upload takes place. This allows 668 * the system to properly prioritize your process (considering it to be more 669 * important than other non-visible applications) for the duration of the 670 * upload, independent of whether the original activity is paused, stopped, 671 * or finished. 672 */ 673public class Activity extends ContextThemeWrapper 674 implements LayoutInflater.Factory2, 675 Window.Callback, KeyEvent.Callback, 676 OnCreateContextMenuListener, ComponentCallbacks2, 677 Window.OnWindowDismissedCallback, WindowControllerCallback { 678 private static final String TAG = "Activity"; 679 private static final boolean DEBUG_LIFECYCLE = false; 680 681 /** Standard activity result: operation canceled. */ 682 public static final int RESULT_CANCELED = 0; 683 /** Standard activity result: operation succeeded. */ 684 public static final int RESULT_OK = -1; 685 /** Start of user-defined activity results. */ 686 public static final int RESULT_FIRST_USER = 1; 687 688 /** @hide Task isn't finished when activity is finished */ 689 public static final int DONT_FINISH_TASK_WITH_ACTIVITY = 0; 690 /** @hide Task is finished if the finishing activity is the root of the task */ 691 public static final int FINISH_TASK_WITH_ROOT_ACTIVITY = 1; 692 /** @hide Task is finished along with the finishing activity*/ 693 public static final int FINISH_TASK_WITH_ACTIVITY = 2; 694 695 static final String FRAGMENTS_TAG = "android:fragments"; 696 697 private static final String WINDOW_HIERARCHY_TAG = "android:viewHierarchyState"; 698 private static final String SAVED_DIALOG_IDS_KEY = "android:savedDialogIds"; 699 private static final String SAVED_DIALOGS_TAG = "android:savedDialogs"; 700 private static final String SAVED_DIALOG_KEY_PREFIX = "android:dialog_"; 701 private static final String SAVED_DIALOG_ARGS_KEY_PREFIX = "android:dialog_args_"; 702 703 private static final String REQUEST_PERMISSIONS_WHO_PREFIX = "@android:requestPermissions:"; 704 705 private static class ManagedDialog { 706 Dialog mDialog; 707 Bundle mArgs; 708 } 709 private SparseArray<ManagedDialog> mManagedDialogs; 710 711 // set by the thread after the constructor and before onCreate(Bundle savedInstanceState) is called. 712 private Instrumentation mInstrumentation; 713 private IBinder mToken; 714 private int mIdent; 715 /*package*/ String mEmbeddedID; 716 private Application mApplication; 717 /*package*/ Intent mIntent; 718 /*package*/ String mReferrer; 719 private ComponentName mComponent; 720 /*package*/ ActivityInfo mActivityInfo; 721 /*package*/ ActivityThread mMainThread; 722 Activity mParent; 723 boolean mCalled; 724 /*package*/ boolean mResumed; 725 private boolean mStopped; 726 boolean mFinished; 727 boolean mStartedActivity; 728 private boolean mDestroyed; 729 private boolean mDoReportFullyDrawn = true; 730 /** true if the activity is going through a transient pause */ 731 /*package*/ boolean mTemporaryPause = false; 732 /** true if the activity is being destroyed in order to recreate it with a new configuration */ 733 /*package*/ boolean mChangingConfigurations = false; 734 /*package*/ int mConfigChangeFlags; 735 /*package*/ Configuration mCurrentConfig; 736 private SearchManager mSearchManager; 737 private MenuInflater mMenuInflater; 738 739 static final class NonConfigurationInstances { 740 Object activity; 741 HashMap<String, Object> children; 742 List<Fragment> fragments; 743 ArrayMap<String, LoaderManager> loaders; 744 VoiceInteractor voiceInteractor; 745 } 746 /* package */ NonConfigurationInstances mLastNonConfigurationInstances; 747 748 private Window mWindow; 749 750 private WindowManager mWindowManager; 751 /*package*/ View mDecor = null; 752 /*package*/ boolean mWindowAdded = false; 753 /*package*/ boolean mVisibleFromServer = false; 754 /*package*/ boolean mVisibleFromClient = true; 755 /*package*/ ActionBar mActionBar = null; 756 private boolean mEnableDefaultActionBarUp; 757 758 private VoiceInteractor mVoiceInteractor; 759 760 private CharSequence mTitle; 761 private int mTitleColor = 0; 762 763 // we must have a handler before the FragmentController is constructed 764 final Handler mHandler = new Handler(); 765 final FragmentController mFragments = FragmentController.createController(new HostCallbacks()); 766 767 // Most recent call to requestVisibleBehind(). 768 boolean mVisibleBehind; 769 770 private static final class ManagedCursor { 771 ManagedCursor(Cursor cursor) { 772 mCursor = cursor; 773 mReleased = false; 774 mUpdated = false; 775 } 776 777 private final Cursor mCursor; 778 private boolean mReleased; 779 private boolean mUpdated; 780 } 781 private final ArrayList<ManagedCursor> mManagedCursors = 782 new ArrayList<ManagedCursor>(); 783 784 // protected by synchronized (this) 785 int mResultCode = RESULT_CANCELED; 786 Intent mResultData = null; 787 788 private TranslucentConversionListener mTranslucentCallback; 789 private boolean mChangeCanvasToTranslucent; 790 791 private SearchEvent mSearchEvent; 792 793 private boolean mTitleReady = false; 794 private int mActionModeTypeStarting = ActionMode.TYPE_PRIMARY; 795 796 private int mDefaultKeyMode = DEFAULT_KEYS_DISABLE; 797 private SpannableStringBuilder mDefaultKeySsb = null; 798 799 protected static final int[] FOCUSED_STATE_SET = {com.android.internal.R.attr.state_focused}; 800 801 @SuppressWarnings("unused") 802 private final Object mInstanceTracker = StrictMode.trackActivity(this); 803 804 private Thread mUiThread; 805 806 ActivityTransitionState mActivityTransitionState = new ActivityTransitionState(); 807 SharedElementCallback mEnterTransitionListener = SharedElementCallback.NULL_CALLBACK; 808 SharedElementCallback mExitTransitionListener = SharedElementCallback.NULL_CALLBACK; 809 810 /** Return the intent that started this activity. */ 811 public Intent getIntent() { 812 return mIntent; 813 } 814 815 /** 816 * Change the intent returned by {@link #getIntent}. This holds a 817 * reference to the given intent; it does not copy it. Often used in 818 * conjunction with {@link #onNewIntent}. 819 * 820 * @param newIntent The new Intent object to return from getIntent 821 * 822 * @see #getIntent 823 * @see #onNewIntent 824 */ 825 public void setIntent(Intent newIntent) { 826 mIntent = newIntent; 827 } 828 829 /** Return the application that owns this activity. */ 830 public final Application getApplication() { 831 return mApplication; 832 } 833 834 /** Is this activity embedded inside of another activity? */ 835 public final boolean isChild() { 836 return mParent != null; 837 } 838 839 /** Return the parent activity if this view is an embedded child. */ 840 public final Activity getParent() { 841 return mParent; 842 } 843 844 /** Retrieve the window manager for showing custom windows. */ 845 public WindowManager getWindowManager() { 846 return mWindowManager; 847 } 848 849 /** 850 * Retrieve the current {@link android.view.Window} for the activity. 851 * This can be used to directly access parts of the Window API that 852 * are not available through Activity/Screen. 853 * 854 * @return Window The current window, or null if the activity is not 855 * visual. 856 */ 857 public Window getWindow() { 858 return mWindow; 859 } 860 861 /** 862 * Return the LoaderManager for this activity, creating it if needed. 863 */ 864 public LoaderManager getLoaderManager() { 865 return mFragments.getLoaderManager(); 866 } 867 868 /** 869 * Calls {@link android.view.Window#getCurrentFocus} on the 870 * Window of this Activity to return the currently focused view. 871 * 872 * @return View The current View with focus or null. 873 * 874 * @see #getWindow 875 * @see android.view.Window#getCurrentFocus 876 */ 877 @Nullable 878 public View getCurrentFocus() { 879 return mWindow != null ? mWindow.getCurrentFocus() : null; 880 } 881 882 /** 883 * Called when the activity is starting. This is where most initialization 884 * should go: calling {@link #setContentView(int)} to inflate the 885 * activity's UI, using {@link #findViewById} to programmatically interact 886 * with widgets in the UI, calling 887 * {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve 888 * cursors for data being displayed, etc. 889 * 890 * <p>You can call {@link #finish} from within this function, in 891 * which case onDestroy() will be immediately called without any of the rest 892 * of the activity lifecycle ({@link #onStart}, {@link #onResume}, 893 * {@link #onPause}, etc) executing. 894 * 895 * <p><em>Derived classes must call through to the super class's 896 * implementation of this method. If they do not, an exception will be 897 * thrown.</em></p> 898 * 899 * @param savedInstanceState If the activity is being re-initialized after 900 * previously being shut down then this Bundle contains the data it most 901 * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b> 902 * 903 * @see #onStart 904 * @see #onSaveInstanceState 905 * @see #onRestoreInstanceState 906 * @see #onPostCreate 907 */ 908 @MainThread 909 @CallSuper 910 protected void onCreate(@Nullable Bundle savedInstanceState) { 911 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState); 912 if (mLastNonConfigurationInstances != null) { 913 mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders); 914 } 915 if (mActivityInfo.parentActivityName != null) { 916 if (mActionBar == null) { 917 mEnableDefaultActionBarUp = true; 918 } else { 919 mActionBar.setDefaultDisplayHomeAsUpEnabled(true); 920 } 921 } 922 if (savedInstanceState != null) { 923 Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG); 924 mFragments.restoreAllState(p, mLastNonConfigurationInstances != null 925 ? mLastNonConfigurationInstances.fragments : null); 926 } 927 mFragments.dispatchCreate(); 928 getApplication().dispatchActivityCreated(this, savedInstanceState); 929 if (mVoiceInteractor != null) { 930 mVoiceInteractor.attachActivity(this); 931 } 932 mCalled = true; 933 } 934 935 /** 936 * Same as {@link #onCreate(android.os.Bundle)} but called for those activities created with 937 * the attribute {@link android.R.attr#persistableMode} set to 938 * <code>persistAcrossReboots</code>. 939 * 940 * @param savedInstanceState if the activity is being re-initialized after 941 * previously being shut down then this Bundle contains the data it most 942 * recently supplied in {@link #onSaveInstanceState}. 943 * <b><i>Note: Otherwise it is null.</i></b> 944 * @param persistentState if the activity is being re-initialized after 945 * previously being shut down or powered off then this Bundle contains the data it most 946 * recently supplied to outPersistentState in {@link #onSaveInstanceState}. 947 * <b><i>Note: Otherwise it is null.</i></b> 948 * 949 * @see #onCreate(android.os.Bundle) 950 * @see #onStart 951 * @see #onSaveInstanceState 952 * @see #onRestoreInstanceState 953 * @see #onPostCreate 954 */ 955 public void onCreate(@Nullable Bundle savedInstanceState, 956 @Nullable PersistableBundle persistentState) { 957 onCreate(savedInstanceState); 958 } 959 960 /** 961 * The hook for {@link ActivityThread} to restore the state of this activity. 962 * 963 * Calls {@link #onSaveInstanceState(android.os.Bundle)} and 964 * {@link #restoreManagedDialogs(android.os.Bundle)}. 965 * 966 * @param savedInstanceState contains the saved state 967 */ 968 final void performRestoreInstanceState(Bundle savedInstanceState) { 969 onRestoreInstanceState(savedInstanceState); 970 restoreManagedDialogs(savedInstanceState); 971 } 972 973 /** 974 * The hook for {@link ActivityThread} to restore the state of this activity. 975 * 976 * Calls {@link #onSaveInstanceState(android.os.Bundle)} and 977 * {@link #restoreManagedDialogs(android.os.Bundle)}. 978 * 979 * @param savedInstanceState contains the saved state 980 * @param persistentState contains the persistable saved state 981 */ 982 final void performRestoreInstanceState(Bundle savedInstanceState, 983 PersistableBundle persistentState) { 984 onRestoreInstanceState(savedInstanceState, persistentState); 985 if (savedInstanceState != null) { 986 restoreManagedDialogs(savedInstanceState); 987 } 988 } 989 990 /** 991 * This method is called after {@link #onStart} when the activity is 992 * being re-initialized from a previously saved state, given here in 993 * <var>savedInstanceState</var>. Most implementations will simply use {@link #onCreate} 994 * to restore their state, but it is sometimes convenient to do it here 995 * after all of the initialization has been done or to allow subclasses to 996 * decide whether to use your default implementation. The default 997 * implementation of this method performs a restore of any view state that 998 * had previously been frozen by {@link #onSaveInstanceState}. 999 * 1000 * <p>This method is called between {@link #onStart} and 1001 * {@link #onPostCreate}. 1002 * 1003 * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}. 1004 * 1005 * @see #onCreate 1006 * @see #onPostCreate 1007 * @see #onResume 1008 * @see #onSaveInstanceState 1009 */ 1010 protected void onRestoreInstanceState(Bundle savedInstanceState) { 1011 if (mWindow != null) { 1012 Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG); 1013 if (windowState != null) { 1014 mWindow.restoreHierarchyState(windowState); 1015 } 1016 } 1017 } 1018 1019 /** 1020 * This is the same as {@link #onRestoreInstanceState(Bundle)} but is called for activities 1021 * created with the attribute {@link android.R.attr#persistableMode} set to 1022 * <code>persistAcrossReboots</code>. The {@link android.os.PersistableBundle} passed 1023 * came from the restored PersistableBundle first 1024 * saved in {@link #onSaveInstanceState(Bundle, PersistableBundle)}. 1025 * 1026 * <p>This method is called between {@link #onStart} and 1027 * {@link #onPostCreate}. 1028 * 1029 * <p>If this method is called {@link #onRestoreInstanceState(Bundle)} will not be called. 1030 * 1031 * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}. 1032 * @param persistentState the data most recently supplied in {@link #onSaveInstanceState}. 1033 * 1034 * @see #onRestoreInstanceState(Bundle) 1035 * @see #onCreate 1036 * @see #onPostCreate 1037 * @see #onResume 1038 * @see #onSaveInstanceState 1039 */ 1040 public void onRestoreInstanceState(Bundle savedInstanceState, 1041 PersistableBundle persistentState) { 1042 if (savedInstanceState != null) { 1043 onRestoreInstanceState(savedInstanceState); 1044 } 1045 } 1046 1047 /** 1048 * Restore the state of any saved managed dialogs. 1049 * 1050 * @param savedInstanceState The bundle to restore from. 1051 */ 1052 private void restoreManagedDialogs(Bundle savedInstanceState) { 1053 final Bundle b = savedInstanceState.getBundle(SAVED_DIALOGS_TAG); 1054 if (b == null) { 1055 return; 1056 } 1057 1058 final int[] ids = b.getIntArray(SAVED_DIALOG_IDS_KEY); 1059 final int numDialogs = ids.length; 1060 mManagedDialogs = new SparseArray<ManagedDialog>(numDialogs); 1061 for (int i = 0; i < numDialogs; i++) { 1062 final Integer dialogId = ids[i]; 1063 Bundle dialogState = b.getBundle(savedDialogKeyFor(dialogId)); 1064 if (dialogState != null) { 1065 // Calling onRestoreInstanceState() below will invoke dispatchOnCreate 1066 // so tell createDialog() not to do it, otherwise we get an exception 1067 final ManagedDialog md = new ManagedDialog(); 1068 md.mArgs = b.getBundle(savedDialogArgsKeyFor(dialogId)); 1069 md.mDialog = createDialog(dialogId, dialogState, md.mArgs); 1070 if (md.mDialog != null) { 1071 mManagedDialogs.put(dialogId, md); 1072 onPrepareDialog(dialogId, md.mDialog, md.mArgs); 1073 md.mDialog.onRestoreInstanceState(dialogState); 1074 } 1075 } 1076 } 1077 } 1078 1079 private Dialog createDialog(Integer dialogId, Bundle state, Bundle args) { 1080 final Dialog dialog = onCreateDialog(dialogId, args); 1081 if (dialog == null) { 1082 return null; 1083 } 1084 dialog.dispatchOnCreate(state); 1085 return dialog; 1086 } 1087 1088 private static String savedDialogKeyFor(int key) { 1089 return SAVED_DIALOG_KEY_PREFIX + key; 1090 } 1091 1092 private static String savedDialogArgsKeyFor(int key) { 1093 return SAVED_DIALOG_ARGS_KEY_PREFIX + key; 1094 } 1095 1096 /** 1097 * Called when activity start-up is complete (after {@link #onStart} 1098 * and {@link #onRestoreInstanceState} have been called). Applications will 1099 * generally not implement this method; it is intended for system 1100 * classes to do final initialization after application code has run. 1101 * 1102 * <p><em>Derived classes must call through to the super class's 1103 * implementation of this method. If they do not, an exception will be 1104 * thrown.</em></p> 1105 * 1106 * @param savedInstanceState If the activity is being re-initialized after 1107 * previously being shut down then this Bundle contains the data it most 1108 * recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b> 1109 * @see #onCreate 1110 */ 1111 @CallSuper 1112 protected void onPostCreate(@Nullable Bundle savedInstanceState) { 1113 if (!isChild()) { 1114 mTitleReady = true; 1115 onTitleChanged(getTitle(), getTitleColor()); 1116 } 1117 mCalled = true; 1118 } 1119 1120 /** 1121 * This is the same as {@link #onPostCreate(Bundle)} but is called for activities 1122 * created with the attribute {@link android.R.attr#persistableMode} set to 1123 * <code>persistAcrossReboots</code>. 1124 * 1125 * @param savedInstanceState The data most recently supplied in {@link #onSaveInstanceState} 1126 * @param persistentState The data caming from the PersistableBundle first 1127 * saved in {@link #onSaveInstanceState(Bundle, PersistableBundle)}. 1128 * 1129 * @see #onCreate 1130 */ 1131 public void onPostCreate(@Nullable Bundle savedInstanceState, 1132 @Nullable PersistableBundle persistentState) { 1133 onPostCreate(savedInstanceState); 1134 } 1135 1136 /** 1137 * Called after {@link #onCreate} — or after {@link #onRestart} when 1138 * the activity had been stopped, but is now again being displayed to the 1139 * user. It will be followed by {@link #onResume}. 1140 * 1141 * <p><em>Derived classes must call through to the super class's 1142 * implementation of this method. If they do not, an exception will be 1143 * thrown.</em></p> 1144 * 1145 * @see #onCreate 1146 * @see #onStop 1147 * @see #onResume 1148 */ 1149 @CallSuper 1150 protected void onStart() { 1151 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this); 1152 mCalled = true; 1153 1154 mFragments.doLoaderStart(); 1155 1156 getApplication().dispatchActivityStarted(this); 1157 } 1158 1159 /** 1160 * Called after {@link #onStop} when the current activity is being 1161 * re-displayed to the user (the user has navigated back to it). It will 1162 * be followed by {@link #onStart} and then {@link #onResume}. 1163 * 1164 * <p>For activities that are using raw {@link Cursor} objects (instead of 1165 * creating them through 1166 * {@link #managedQuery(android.net.Uri , String[], String, String[], String)}, 1167 * this is usually the place 1168 * where the cursor should be requeried (because you had deactivated it in 1169 * {@link #onStop}. 1170 * 1171 * <p><em>Derived classes must call through to the super class's 1172 * implementation of this method. If they do not, an exception will be 1173 * thrown.</em></p> 1174 * 1175 * @see #onStop 1176 * @see #onStart 1177 * @see #onResume 1178 */ 1179 @CallSuper 1180 protected void onRestart() { 1181 mCalled = true; 1182 } 1183 1184 /** 1185 * Called when an {@link #onResume} is coming up, prior to other pre-resume callbacks 1186 * such as {@link #onNewIntent} and {@link #onActivityResult}. This is primarily intended 1187 * to give the activity a hint that its state is no longer saved -- it will generally 1188 * be called after {@link #onSaveInstanceState} and prior to the activity being 1189 * resumed/started again. 1190 */ 1191 public void onStateNotSaved() { 1192 } 1193 1194 /** 1195 * Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or 1196 * {@link #onPause}, for your activity to start interacting with the user. 1197 * This is a good place to begin animations, open exclusive-access devices 1198 * (such as the camera), etc. 1199 * 1200 * <p>Keep in mind that onResume is not the best indicator that your activity 1201 * is visible to the user; a system window such as the keyguard may be in 1202 * front. Use {@link #onWindowFocusChanged} to know for certain that your 1203 * activity is visible to the user (for example, to resume a game). 1204 * 1205 * <p><em>Derived classes must call through to the super class's 1206 * implementation of this method. If they do not, an exception will be 1207 * thrown.</em></p> 1208 * 1209 * @see #onRestoreInstanceState 1210 * @see #onRestart 1211 * @see #onPostResume 1212 * @see #onPause 1213 */ 1214 @CallSuper 1215 protected void onResume() { 1216 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this); 1217 getApplication().dispatchActivityResumed(this); 1218 mActivityTransitionState.onResume(); 1219 mCalled = true; 1220 } 1221 1222 /** 1223 * Called when activity resume is complete (after {@link #onResume} has 1224 * been called). Applications will generally not implement this method; 1225 * it is intended for system classes to do final setup after application 1226 * resume code has run. 1227 * 1228 * <p><em>Derived classes must call through to the super class's 1229 * implementation of this method. If they do not, an exception will be 1230 * thrown.</em></p> 1231 * 1232 * @see #onResume 1233 */ 1234 @CallSuper 1235 protected void onPostResume() { 1236 final Window win = getWindow(); 1237 if (win != null) win.makeActive(); 1238 if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(true); 1239 mCalled = true; 1240 } 1241 1242 /** 1243 * Check whether this activity is running as part of a voice interaction with the user. 1244 * If true, it should perform its interaction with the user through the 1245 * {@link VoiceInteractor} returned by {@link #getVoiceInteractor}. 1246 */ 1247 public boolean isVoiceInteraction() { 1248 return mVoiceInteractor != null; 1249 } 1250 1251 /** 1252 * Like {@link #isVoiceInteraction}, but only returns true if this is also the root 1253 * of a voice interaction. That is, returns true if this activity was directly 1254 * started by the voice interaction service as the initiation of a voice interaction. 1255 * Otherwise, for example if it was started by another activity while under voice 1256 * interaction, returns false. 1257 */ 1258 public boolean isVoiceInteractionRoot() { 1259 try { 1260 return mVoiceInteractor != null 1261 && ActivityManagerNative.getDefault().isRootVoiceInteraction(mToken); 1262 } catch (RemoteException e) { 1263 } 1264 return false; 1265 } 1266 1267 /** 1268 * Retrieve the active {@link VoiceInteractor} that the user is going through to 1269 * interact with this activity. 1270 */ 1271 public VoiceInteractor getVoiceInteractor() { 1272 return mVoiceInteractor; 1273 } 1274 1275 /** 1276 * This is called for activities that set launchMode to "singleTop" in 1277 * their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} 1278 * flag when calling {@link #startActivity}. In either case, when the 1279 * activity is re-launched while at the top of the activity stack instead 1280 * of a new instance of the activity being started, onNewIntent() will be 1281 * called on the existing instance with the Intent that was used to 1282 * re-launch it. 1283 * 1284 * <p>An activity will always be paused before receiving a new intent, so 1285 * you can count on {@link #onResume} being called after this method. 1286 * 1287 * <p>Note that {@link #getIntent} still returns the original Intent. You 1288 * can use {@link #setIntent} to update it to this new Intent. 1289 * 1290 * @param intent The new intent that was started for the activity. 1291 * 1292 * @see #getIntent 1293 * @see #setIntent 1294 * @see #onResume 1295 */ 1296 protected void onNewIntent(Intent intent) { 1297 } 1298 1299 /** 1300 * The hook for {@link ActivityThread} to save the state of this activity. 1301 * 1302 * Calls {@link #onSaveInstanceState(android.os.Bundle)} 1303 * and {@link #saveManagedDialogs(android.os.Bundle)}. 1304 * 1305 * @param outState The bundle to save the state to. 1306 */ 1307 final void performSaveInstanceState(Bundle outState) { 1308 onSaveInstanceState(outState); 1309 saveManagedDialogs(outState); 1310 mActivityTransitionState.saveState(outState); 1311 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState); 1312 } 1313 1314 /** 1315 * The hook for {@link ActivityThread} to save the state of this activity. 1316 * 1317 * Calls {@link #onSaveInstanceState(android.os.Bundle)} 1318 * and {@link #saveManagedDialogs(android.os.Bundle)}. 1319 * 1320 * @param outState The bundle to save the state to. 1321 * @param outPersistentState The bundle to save persistent state to. 1322 */ 1323 final void performSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { 1324 onSaveInstanceState(outState, outPersistentState); 1325 saveManagedDialogs(outState); 1326 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState + 1327 ", " + outPersistentState); 1328 } 1329 1330 /** 1331 * Called to retrieve per-instance state from an activity before being killed 1332 * so that the state can be restored in {@link #onCreate} or 1333 * {@link #onRestoreInstanceState} (the {@link Bundle} populated by this method 1334 * will be passed to both). 1335 * 1336 * <p>This method is called before an activity may be killed so that when it 1337 * comes back some time in the future it can restore its state. For example, 1338 * if activity B is launched in front of activity A, and at some point activity 1339 * A is killed to reclaim resources, activity A will have a chance to save the 1340 * current state of its user interface via this method so that when the user 1341 * returns to activity A, the state of the user interface can be restored 1342 * via {@link #onCreate} or {@link #onRestoreInstanceState}. 1343 * 1344 * <p>Do not confuse this method with activity lifecycle callbacks such as 1345 * {@link #onPause}, which is always called when an activity is being placed 1346 * in the background or on its way to destruction, or {@link #onStop} which 1347 * is called before destruction. One example of when {@link #onPause} and 1348 * {@link #onStop} is called and not this method is when a user navigates back 1349 * from activity B to activity A: there is no need to call {@link #onSaveInstanceState} 1350 * on B because that particular instance will never be restored, so the 1351 * system avoids calling it. An example when {@link #onPause} is called and 1352 * not {@link #onSaveInstanceState} is when activity B is launched in front of activity A: 1353 * the system may avoid calling {@link #onSaveInstanceState} on activity A if it isn't 1354 * killed during the lifetime of B since the state of the user interface of 1355 * A will stay intact. 1356 * 1357 * <p>The default implementation takes care of most of the UI per-instance 1358 * state for you by calling {@link android.view.View#onSaveInstanceState()} on each 1359 * view in the hierarchy that has an id, and by saving the id of the currently 1360 * focused view (all of which is restored by the default implementation of 1361 * {@link #onRestoreInstanceState}). If you override this method to save additional 1362 * information not captured by each individual view, you will likely want to 1363 * call through to the default implementation, otherwise be prepared to save 1364 * all of the state of each view yourself. 1365 * 1366 * <p>If called, this method will occur before {@link #onStop}. There are 1367 * no guarantees about whether it will occur before or after {@link #onPause}. 1368 * 1369 * @param outState Bundle in which to place your saved state. 1370 * 1371 * @see #onCreate 1372 * @see #onRestoreInstanceState 1373 * @see #onPause 1374 */ 1375 protected void onSaveInstanceState(Bundle outState) { 1376 outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState()); 1377 Parcelable p = mFragments.saveAllState(); 1378 if (p != null) { 1379 outState.putParcelable(FRAGMENTS_TAG, p); 1380 } 1381 getApplication().dispatchActivitySaveInstanceState(this, outState); 1382 } 1383 1384 /** 1385 * This is the same as {@link #onSaveInstanceState} but is called for activities 1386 * created with the attribute {@link android.R.attr#persistableMode} set to 1387 * <code>persistAcrossReboots</code>. The {@link android.os.PersistableBundle} passed 1388 * in will be saved and presented in {@link #onCreate(Bundle, PersistableBundle)} 1389 * the first time that this activity is restarted following the next device reboot. 1390 * 1391 * @param outState Bundle in which to place your saved state. 1392 * @param outPersistentState State which will be saved across reboots. 1393 * 1394 * @see #onSaveInstanceState(Bundle) 1395 * @see #onCreate 1396 * @see #onRestoreInstanceState(Bundle, PersistableBundle) 1397 * @see #onPause 1398 */ 1399 public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { 1400 onSaveInstanceState(outState); 1401 } 1402 1403 /** 1404 * Save the state of any managed dialogs. 1405 * 1406 * @param outState place to store the saved state. 1407 */ 1408 private void saveManagedDialogs(Bundle outState) { 1409 if (mManagedDialogs == null) { 1410 return; 1411 } 1412 1413 final int numDialogs = mManagedDialogs.size(); 1414 if (numDialogs == 0) { 1415 return; 1416 } 1417 1418 Bundle dialogState = new Bundle(); 1419 1420 int[] ids = new int[mManagedDialogs.size()]; 1421 1422 // save each dialog's bundle, gather the ids 1423 for (int i = 0; i < numDialogs; i++) { 1424 final int key = mManagedDialogs.keyAt(i); 1425 ids[i] = key; 1426 final ManagedDialog md = mManagedDialogs.valueAt(i); 1427 dialogState.putBundle(savedDialogKeyFor(key), md.mDialog.onSaveInstanceState()); 1428 if (md.mArgs != null) { 1429 dialogState.putBundle(savedDialogArgsKeyFor(key), md.mArgs); 1430 } 1431 } 1432 1433 dialogState.putIntArray(SAVED_DIALOG_IDS_KEY, ids); 1434 outState.putBundle(SAVED_DIALOGS_TAG, dialogState); 1435 } 1436 1437 1438 /** 1439 * Called as part of the activity lifecycle when an activity is going into 1440 * the background, but has not (yet) been killed. The counterpart to 1441 * {@link #onResume}. 1442 * 1443 * <p>When activity B is launched in front of activity A, this callback will 1444 * be invoked on A. B will not be created until A's {@link #onPause} returns, 1445 * so be sure to not do anything lengthy here. 1446 * 1447 * <p>This callback is mostly used for saving any persistent state the 1448 * activity is editing, to present a "edit in place" model to the user and 1449 * making sure nothing is lost if there are not enough resources to start 1450 * the new activity without first killing this one. This is also a good 1451 * place to do things like stop animations and other things that consume a 1452 * noticeable amount of CPU in order to make the switch to the next activity 1453 * as fast as possible, or to close resources that are exclusive access 1454 * such as the camera. 1455 * 1456 * <p>In situations where the system needs more memory it may kill paused 1457 * processes to reclaim resources. Because of this, you should be sure 1458 * that all of your state is saved by the time you return from 1459 * this function. In general {@link #onSaveInstanceState} is used to save 1460 * per-instance state in the activity and this method is used to store 1461 * global persistent data (in content providers, files, etc.) 1462 * 1463 * <p>After receiving this call you will usually receive a following call 1464 * to {@link #onStop} (after the next activity has been resumed and 1465 * displayed), however in some cases there will be a direct call back to 1466 * {@link #onResume} without going through the stopped state. 1467 * 1468 * <p><em>Derived classes must call through to the super class's 1469 * implementation of this method. If they do not, an exception will be 1470 * thrown.</em></p> 1471 * 1472 * @see #onResume 1473 * @see #onSaveInstanceState 1474 * @see #onStop 1475 */ 1476 @CallSuper 1477 protected void onPause() { 1478 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this); 1479 getApplication().dispatchActivityPaused(this); 1480 mCalled = true; 1481 } 1482 1483 /** 1484 * Called as part of the activity lifecycle when an activity is about to go 1485 * into the background as the result of user choice. For example, when the 1486 * user presses the Home key, {@link #onUserLeaveHint} will be called, but 1487 * when an incoming phone call causes the in-call Activity to be automatically 1488 * brought to the foreground, {@link #onUserLeaveHint} will not be called on 1489 * the activity being interrupted. In cases when it is invoked, this method 1490 * is called right before the activity's {@link #onPause} callback. 1491 * 1492 * <p>This callback and {@link #onUserInteraction} are intended to help 1493 * activities manage status bar notifications intelligently; specifically, 1494 * for helping activities determine the proper time to cancel a notfication. 1495 * 1496 * @see #onUserInteraction() 1497 */ 1498 protected void onUserLeaveHint() { 1499 } 1500 1501 /** 1502 * Generate a new thumbnail for this activity. This method is called before 1503 * pausing the activity, and should draw into <var>outBitmap</var> the 1504 * imagery for the desired thumbnail in the dimensions of that bitmap. It 1505 * can use the given <var>canvas</var>, which is configured to draw into the 1506 * bitmap, for rendering if desired. 1507 * 1508 * <p>The default implementation returns fails and does not draw a thumbnail; 1509 * this will result in the platform creating its own thumbnail if needed. 1510 * 1511 * @param outBitmap The bitmap to contain the thumbnail. 1512 * @param canvas Can be used to render into the bitmap. 1513 * 1514 * @return Return true if you have drawn into the bitmap; otherwise after 1515 * you return it will be filled with a default thumbnail. 1516 * 1517 * @see #onCreateDescription 1518 * @see #onSaveInstanceState 1519 * @see #onPause 1520 */ 1521 public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) { 1522 return false; 1523 } 1524 1525 /** 1526 * Generate a new description for this activity. This method is called 1527 * before pausing the activity and can, if desired, return some textual 1528 * description of its current state to be displayed to the user. 1529 * 1530 * <p>The default implementation returns null, which will cause you to 1531 * inherit the description from the previous activity. If all activities 1532 * return null, generally the label of the top activity will be used as the 1533 * description. 1534 * 1535 * @return A description of what the user is doing. It should be short and 1536 * sweet (only a few words). 1537 * 1538 * @see #onCreateThumbnail 1539 * @see #onSaveInstanceState 1540 * @see #onPause 1541 */ 1542 @Nullable 1543 public CharSequence onCreateDescription() { 1544 return null; 1545 } 1546 1547 /** 1548 * This is called when the user is requesting an assist, to build a full 1549 * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current 1550 * application. You can override this method to place into the bundle anything 1551 * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part 1552 * of the assist Intent. 1553 * 1554 * <p>This function will be called after any global assist callbacks that had 1555 * been registered with {@link Application#registerOnProvideAssistDataListener 1556 * Application.registerOnProvideAssistDataListener}. 1557 */ 1558 public void onProvideAssistData(Bundle data) { 1559 } 1560 1561 /** 1562 * This is called when the user is requesting an assist, to provide references 1563 * to content related to the current activity. Before being called, the 1564 * {@code outContent} Intent is filled with the base Intent of the activity (the Intent 1565 * returned by {@link #getIntent()}). The Intent's extras are stripped of any types 1566 * that are not valid for {@link PersistableBundle} or non-framework Parcelables, and 1567 * the flags {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION} and 1568 * {@link Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION} are cleared from the Intent. 1569 * 1570 * <p>Custom implementation may adjust the content intent to better reflect the top-level 1571 * context of the activity, and fill in its ClipData with additional content of 1572 * interest that the user is currently viewing. For example, an image gallery application 1573 * that has launched in to an activity allowing the user to swipe through pictures should 1574 * modify the intent to reference the current image they are looking it; such an 1575 * application when showing a list of pictures should add a ClipData that has 1576 * references to all of the pictures currently visible on screen.</p> 1577 * 1578 * @param outContent The assist content to return. 1579 */ 1580 public void onProvideAssistContent(AssistContent outContent) { 1581 } 1582 1583 /** 1584 * Ask to have the current assistant shown to the user. This only works if the calling 1585 * activity is the current foreground activity. It is the same as calling 1586 * {@link android.service.voice.VoiceInteractionService#showSession 1587 * VoiceInteractionService.showSession} and requesting all of the possible context. 1588 * The receiver will always see 1589 * {@link android.service.voice.VoiceInteractionSession#SHOW_SOURCE_APPLICATION} set. 1590 * @return Returns true if the assistant was successfully invoked, else false. For example 1591 * false will be returned if the caller is not the current top activity. 1592 */ 1593 public boolean showAssist(Bundle args) { 1594 try { 1595 return ActivityManagerNative.getDefault().showAssistFromActivity(mToken, args); 1596 } catch (RemoteException e) { 1597 } 1598 return false; 1599 } 1600 1601 /** 1602 * Called when you are no longer visible to the user. You will next 1603 * receive either {@link #onRestart}, {@link #onDestroy}, or nothing, 1604 * depending on later user activity. 1605 * 1606 * <p>Note that this method may never be called, in low memory situations 1607 * where the system does not have enough memory to keep your activity's 1608 * process running after its {@link #onPause} method is called. 1609 * 1610 * <p><em>Derived classes must call through to the super class's 1611 * implementation of this method. If they do not, an exception will be 1612 * thrown.</em></p> 1613 * 1614 * @see #onRestart 1615 * @see #onResume 1616 * @see #onSaveInstanceState 1617 * @see #onDestroy 1618 */ 1619 @CallSuper 1620 protected void onStop() { 1621 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this); 1622 if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false); 1623 mActivityTransitionState.onStop(); 1624 getApplication().dispatchActivityStopped(this); 1625 mTranslucentCallback = null; 1626 mCalled = true; 1627 } 1628 1629 /** 1630 * Perform any final cleanup before an activity is destroyed. This can 1631 * happen either because the activity is finishing (someone called 1632 * {@link #finish} on it, or because the system is temporarily destroying 1633 * this instance of the activity to save space. You can distinguish 1634 * between these two scenarios with the {@link #isFinishing} method. 1635 * 1636 * <p><em>Note: do not count on this method being called as a place for 1637 * saving data! For example, if an activity is editing data in a content 1638 * provider, those edits should be committed in either {@link #onPause} or 1639 * {@link #onSaveInstanceState}, not here.</em> This method is usually implemented to 1640 * free resources like threads that are associated with an activity, so 1641 * that a destroyed activity does not leave such things around while the 1642 * rest of its application is still running. There are situations where 1643 * the system will simply kill the activity's hosting process without 1644 * calling this method (or any others) in it, so it should not be used to 1645 * do things that are intended to remain around after the process goes 1646 * away. 1647 * 1648 * <p><em>Derived classes must call through to the super class's 1649 * implementation of this method. If they do not, an exception will be 1650 * thrown.</em></p> 1651 * 1652 * @see #onPause 1653 * @see #onStop 1654 * @see #finish 1655 * @see #isFinishing 1656 */ 1657 @CallSuper 1658 protected void onDestroy() { 1659 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this); 1660 mCalled = true; 1661 1662 // dismiss any dialogs we are managing. 1663 if (mManagedDialogs != null) { 1664 final int numDialogs = mManagedDialogs.size(); 1665 for (int i = 0; i < numDialogs; i++) { 1666 final ManagedDialog md = mManagedDialogs.valueAt(i); 1667 if (md.mDialog.isShowing()) { 1668 md.mDialog.dismiss(); 1669 } 1670 } 1671 mManagedDialogs = null; 1672 } 1673 1674 // close any cursors we are managing. 1675 synchronized (mManagedCursors) { 1676 int numCursors = mManagedCursors.size(); 1677 for (int i = 0; i < numCursors; i++) { 1678 ManagedCursor c = mManagedCursors.get(i); 1679 if (c != null) { 1680 c.mCursor.close(); 1681 } 1682 } 1683 mManagedCursors.clear(); 1684 } 1685 1686 // Close any open search dialog 1687 if (mSearchManager != null) { 1688 mSearchManager.stopSearch(); 1689 } 1690 1691 getApplication().dispatchActivityDestroyed(this); 1692 } 1693 1694 /** 1695 * Report to the system that your app is now fully drawn, purely for diagnostic 1696 * purposes (calling it does not impact the visible behavior of the activity). 1697 * This is only used to help instrument application launch times, so that the 1698 * app can report when it is fully in a usable state; without this, the only thing 1699 * the system itself can determine is the point at which the activity's window 1700 * is <em>first</em> drawn and displayed. To participate in app launch time 1701 * measurement, you should always call this method after first launch (when 1702 * {@link #onCreate(android.os.Bundle)} is called), at the point where you have 1703 * entirely drawn your UI and populated with all of the significant data. You 1704 * can safely call this method any time after first launch as well, in which case 1705 * it will simply be ignored. 1706 */ 1707 public void reportFullyDrawn() { 1708 if (mDoReportFullyDrawn) { 1709 mDoReportFullyDrawn = false; 1710 try { 1711 ActivityManagerNative.getDefault().reportActivityFullyDrawn(mToken); 1712 } catch (RemoteException e) { 1713 } 1714 } 1715 } 1716 1717 /** 1718 * Called by the system when the device configuration changes while your 1719 * activity is running. Note that this will <em>only</em> be called if 1720 * you have selected configurations you would like to handle with the 1721 * {@link android.R.attr#configChanges} attribute in your manifest. If 1722 * any configuration change occurs that is not selected to be reported 1723 * by that attribute, then instead of reporting it the system will stop 1724 * and restart the activity (to have it launched with the new 1725 * configuration). 1726 * 1727 * <p>At the time that this function has been called, your Resources 1728 * object will have been updated to return resource values matching the 1729 * new configuration. 1730 * 1731 * @param newConfig The new device configuration. 1732 */ 1733 public void onConfigurationChanged(Configuration newConfig) { 1734 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onConfigurationChanged " + this + ": " + newConfig); 1735 mCalled = true; 1736 1737 mFragments.dispatchConfigurationChanged(newConfig); 1738 1739 if (mWindow != null) { 1740 // Pass the configuration changed event to the window 1741 mWindow.onConfigurationChanged(newConfig); 1742 } 1743 1744 if (mActionBar != null) { 1745 // Do this last; the action bar will need to access 1746 // view changes from above. 1747 mActionBar.onConfigurationChanged(newConfig); 1748 } 1749 } 1750 1751 /** 1752 * If this activity is being destroyed because it can not handle a 1753 * configuration parameter being changed (and thus its 1754 * {@link #onConfigurationChanged(Configuration)} method is 1755 * <em>not</em> being called), then you can use this method to discover 1756 * the set of changes that have occurred while in the process of being 1757 * destroyed. Note that there is no guarantee that these will be 1758 * accurate (other changes could have happened at any time), so you should 1759 * only use this as an optimization hint. 1760 * 1761 * @return Returns a bit field of the configuration parameters that are 1762 * changing, as defined by the {@link android.content.res.Configuration} 1763 * class. 1764 */ 1765 public int getChangingConfigurations() { 1766 return mConfigChangeFlags; 1767 } 1768 1769 /** 1770 * Retrieve the non-configuration instance data that was previously 1771 * returned by {@link #onRetainNonConfigurationInstance()}. This will 1772 * be available from the initial {@link #onCreate} and 1773 * {@link #onStart} calls to the new instance, allowing you to extract 1774 * any useful dynamic state from the previous instance. 1775 * 1776 * <p>Note that the data you retrieve here should <em>only</em> be used 1777 * as an optimization for handling configuration changes. You should always 1778 * be able to handle getting a null pointer back, and an activity must 1779 * still be able to restore itself to its previous state (through the 1780 * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this 1781 * function returns null. 1782 * 1783 * @return Returns the object previously returned by 1784 * {@link #onRetainNonConfigurationInstance()}. 1785 * 1786 * @deprecated Use the new {@link Fragment} API 1787 * {@link Fragment#setRetainInstance(boolean)} instead; this is also 1788 * available on older platforms through the Android compatibility package. 1789 */ 1790 @Nullable 1791 @Deprecated 1792 public Object getLastNonConfigurationInstance() { 1793 return mLastNonConfigurationInstances != null 1794 ? mLastNonConfigurationInstances.activity : null; 1795 } 1796 1797 /** 1798 * Called by the system, as part of destroying an 1799 * activity due to a configuration change, when it is known that a new 1800 * instance will immediately be created for the new configuration. You 1801 * can return any object you like here, including the activity instance 1802 * itself, which can later be retrieved by calling 1803 * {@link #getLastNonConfigurationInstance()} in the new activity 1804 * instance. 1805 * 1806 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1807 * or later, consider instead using a {@link Fragment} with 1808 * {@link Fragment#setRetainInstance(boolean) 1809 * Fragment.setRetainInstance(boolean}.</em> 1810 * 1811 * <p>This function is called purely as an optimization, and you must 1812 * not rely on it being called. When it is called, a number of guarantees 1813 * will be made to help optimize configuration switching: 1814 * <ul> 1815 * <li> The function will be called between {@link #onStop} and 1816 * {@link #onDestroy}. 1817 * <li> A new instance of the activity will <em>always</em> be immediately 1818 * created after this one's {@link #onDestroy()} is called. In particular, 1819 * <em>no</em> messages will be dispatched during this time (when the returned 1820 * object does not have an activity to be associated with). 1821 * <li> The object you return here will <em>always</em> be available from 1822 * the {@link #getLastNonConfigurationInstance()} method of the following 1823 * activity instance as described there. 1824 * </ul> 1825 * 1826 * <p>These guarantees are designed so that an activity can use this API 1827 * to propagate extensive state from the old to new activity instance, from 1828 * loaded bitmaps, to network connections, to evenly actively running 1829 * threads. Note that you should <em>not</em> propagate any data that 1830 * may change based on the configuration, including any data loaded from 1831 * resources such as strings, layouts, or drawables. 1832 * 1833 * <p>The guarantee of no message handling during the switch to the next 1834 * activity simplifies use with active objects. For example if your retained 1835 * state is an {@link android.os.AsyncTask} you are guaranteed that its 1836 * call back functions (like {@link android.os.AsyncTask#onPostExecute}) will 1837 * not be called from the call here until you execute the next instance's 1838 * {@link #onCreate(Bundle)}. (Note however that there is of course no such 1839 * guarantee for {@link android.os.AsyncTask#doInBackground} since that is 1840 * running in a separate thread.) 1841 * 1842 * @return Return any Object holding the desired state to propagate to the 1843 * next activity instance. 1844 * 1845 * @deprecated Use the new {@link Fragment} API 1846 * {@link Fragment#setRetainInstance(boolean)} instead; this is also 1847 * available on older platforms through the Android compatibility package. 1848 */ 1849 public Object onRetainNonConfigurationInstance() { 1850 return null; 1851 } 1852 1853 /** 1854 * Retrieve the non-configuration instance data that was previously 1855 * returned by {@link #onRetainNonConfigurationChildInstances()}. This will 1856 * be available from the initial {@link #onCreate} and 1857 * {@link #onStart} calls to the new instance, allowing you to extract 1858 * any useful dynamic state from the previous instance. 1859 * 1860 * <p>Note that the data you retrieve here should <em>only</em> be used 1861 * as an optimization for handling configuration changes. You should always 1862 * be able to handle getting a null pointer back, and an activity must 1863 * still be able to restore itself to its previous state (through the 1864 * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this 1865 * function returns null. 1866 * 1867 * @return Returns the object previously returned by 1868 * {@link #onRetainNonConfigurationChildInstances()} 1869 */ 1870 @Nullable 1871 HashMap<String, Object> getLastNonConfigurationChildInstances() { 1872 return mLastNonConfigurationInstances != null 1873 ? mLastNonConfigurationInstances.children : null; 1874 } 1875 1876 /** 1877 * This method is similar to {@link #onRetainNonConfigurationInstance()} except that 1878 * it should return either a mapping from child activity id strings to arbitrary objects, 1879 * or null. This method is intended to be used by Activity framework subclasses that control a 1880 * set of child activities, such as ActivityGroup. The same guarantees and restrictions apply 1881 * as for {@link #onRetainNonConfigurationInstance()}. The default implementation returns null. 1882 */ 1883 @Nullable 1884 HashMap<String,Object> onRetainNonConfigurationChildInstances() { 1885 return null; 1886 } 1887 1888 NonConfigurationInstances retainNonConfigurationInstances() { 1889 Object activity = onRetainNonConfigurationInstance(); 1890 HashMap<String, Object> children = onRetainNonConfigurationChildInstances(); 1891 List<Fragment> fragments = mFragments.retainNonConfig(); 1892 ArrayMap<String, LoaderManager> loaders = mFragments.retainLoaderNonConfig(); 1893 if (activity == null && children == null && fragments == null && loaders == null 1894 && mVoiceInteractor == null) { 1895 return null; 1896 } 1897 1898 NonConfigurationInstances nci = new NonConfigurationInstances(); 1899 nci.activity = activity; 1900 nci.children = children; 1901 nci.fragments = fragments; 1902 nci.loaders = loaders; 1903 if (mVoiceInteractor != null) { 1904 mVoiceInteractor.retainInstance(); 1905 nci.voiceInteractor = mVoiceInteractor; 1906 } 1907 return nci; 1908 } 1909 1910 public void onLowMemory() { 1911 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onLowMemory " + this); 1912 mCalled = true; 1913 mFragments.dispatchLowMemory(); 1914 } 1915 1916 public void onTrimMemory(int level) { 1917 if (DEBUG_LIFECYCLE) Slog.v(TAG, "onTrimMemory " + this + ": " + level); 1918 mCalled = true; 1919 mFragments.dispatchTrimMemory(level); 1920 } 1921 1922 /** 1923 * Return the FragmentManager for interacting with fragments associated 1924 * with this activity. 1925 */ 1926 public FragmentManager getFragmentManager() { 1927 return mFragments.getFragmentManager(); 1928 } 1929 1930 /** 1931 * Called when a Fragment is being attached to this activity, immediately 1932 * after the call to its {@link Fragment#onAttach Fragment.onAttach()} 1933 * method and before {@link Fragment#onCreate Fragment.onCreate()}. 1934 */ 1935 public void onAttachFragment(Fragment fragment) { 1936 } 1937 1938 /** 1939 * Wrapper around 1940 * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)} 1941 * that gives the resulting {@link Cursor} to call 1942 * {@link #startManagingCursor} so that the activity will manage its 1943 * lifecycle for you. 1944 * 1945 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1946 * or later, consider instead using {@link LoaderManager} instead, available 1947 * via {@link #getLoaderManager()}.</em> 1948 * 1949 * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on a cursor obtained using 1950 * this method, because the activity will do that for you at the appropriate time. However, if 1951 * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will 1952 * not</em> automatically close the cursor and, in that case, you must call 1953 * {@link Cursor#close()}.</p> 1954 * 1955 * @param uri The URI of the content provider to query. 1956 * @param projection List of columns to return. 1957 * @param selection SQL WHERE clause. 1958 * @param sortOrder SQL ORDER BY clause. 1959 * 1960 * @return The Cursor that was returned by query(). 1961 * 1962 * @see ContentResolver#query(android.net.Uri , String[], String, String[], String) 1963 * @see #startManagingCursor 1964 * @hide 1965 * 1966 * @deprecated Use {@link CursorLoader} instead. 1967 */ 1968 @Deprecated 1969 public final Cursor managedQuery(Uri uri, String[] projection, String selection, 1970 String sortOrder) { 1971 Cursor c = getContentResolver().query(uri, projection, selection, null, sortOrder); 1972 if (c != null) { 1973 startManagingCursor(c); 1974 } 1975 return c; 1976 } 1977 1978 /** 1979 * Wrapper around 1980 * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)} 1981 * that gives the resulting {@link Cursor} to call 1982 * {@link #startManagingCursor} so that the activity will manage its 1983 * lifecycle for you. 1984 * 1985 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 1986 * or later, consider instead using {@link LoaderManager} instead, available 1987 * via {@link #getLoaderManager()}.</em> 1988 * 1989 * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on a cursor obtained using 1990 * this method, because the activity will do that for you at the appropriate time. However, if 1991 * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will 1992 * not</em> automatically close the cursor and, in that case, you must call 1993 * {@link Cursor#close()}.</p> 1994 * 1995 * @param uri The URI of the content provider to query. 1996 * @param projection List of columns to return. 1997 * @param selection SQL WHERE clause. 1998 * @param selectionArgs The arguments to selection, if any ?s are pesent 1999 * @param sortOrder SQL ORDER BY clause. 2000 * 2001 * @return The Cursor that was returned by query(). 2002 * 2003 * @see ContentResolver#query(android.net.Uri , String[], String, String[], String) 2004 * @see #startManagingCursor 2005 * 2006 * @deprecated Use {@link CursorLoader} instead. 2007 */ 2008 @Deprecated 2009 public final Cursor managedQuery(Uri uri, String[] projection, String selection, 2010 String[] selectionArgs, String sortOrder) { 2011 Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); 2012 if (c != null) { 2013 startManagingCursor(c); 2014 } 2015 return c; 2016 } 2017 2018 /** 2019 * This method allows the activity to take care of managing the given 2020 * {@link Cursor}'s lifecycle for you based on the activity's lifecycle. 2021 * That is, when the activity is stopped it will automatically call 2022 * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted 2023 * it will call {@link Cursor#requery} for you. When the activity is 2024 * destroyed, all managed Cursors will be closed automatically. 2025 * 2026 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 2027 * or later, consider instead using {@link LoaderManager} instead, available 2028 * via {@link #getLoaderManager()}.</em> 2029 * 2030 * <p><strong>Warning:</strong> Do not call {@link Cursor#close()} on cursor obtained from 2031 * {@link #managedQuery}, because the activity will do that for you at the appropriate time. 2032 * However, if you call {@link #stopManagingCursor} on a cursor from a managed query, the system 2033 * <em>will not</em> automatically close the cursor and, in that case, you must call 2034 * {@link Cursor#close()}.</p> 2035 * 2036 * @param c The Cursor to be managed. 2037 * 2038 * @see #managedQuery(android.net.Uri , String[], String, String[], String) 2039 * @see #stopManagingCursor 2040 * 2041 * @deprecated Use the new {@link android.content.CursorLoader} class with 2042 * {@link LoaderManager} instead; this is also 2043 * available on older platforms through the Android compatibility package. 2044 */ 2045 @Deprecated 2046 public void startManagingCursor(Cursor c) { 2047 synchronized (mManagedCursors) { 2048 mManagedCursors.add(new ManagedCursor(c)); 2049 } 2050 } 2051 2052 /** 2053 * Given a Cursor that was previously given to 2054 * {@link #startManagingCursor}, stop the activity's management of that 2055 * cursor. 2056 * 2057 * <p><strong>Warning:</strong> After calling this method on a cursor from a managed query, 2058 * the system <em>will not</em> automatically close the cursor and you must call 2059 * {@link Cursor#close()}.</p> 2060 * 2061 * @param c The Cursor that was being managed. 2062 * 2063 * @see #startManagingCursor 2064 * 2065 * @deprecated Use the new {@link android.content.CursorLoader} class with 2066 * {@link LoaderManager} instead; this is also 2067 * available on older platforms through the Android compatibility package. 2068 */ 2069 @Deprecated 2070 public void stopManagingCursor(Cursor c) { 2071 synchronized (mManagedCursors) { 2072 final int N = mManagedCursors.size(); 2073 for (int i=0; i<N; i++) { 2074 ManagedCursor mc = mManagedCursors.get(i); 2075 if (mc.mCursor == c) { 2076 mManagedCursors.remove(i); 2077 break; 2078 } 2079 } 2080 } 2081 } 2082 2083 /** 2084 * @deprecated As of {@link android.os.Build.VERSION_CODES#GINGERBREAD} 2085 * this is a no-op. 2086 * @hide 2087 */ 2088 @Deprecated 2089 public void setPersistent(boolean isPersistent) { 2090 } 2091 2092 /** 2093 * Finds a view that was identified by the id attribute from the XML that 2094 * was processed in {@link #onCreate}. 2095 * 2096 * @return The view if found or null otherwise. 2097 */ 2098 @Nullable 2099 public View findViewById(@IdRes int id) { 2100 return getWindow().findViewById(id); 2101 } 2102 2103 /** 2104 * Retrieve a reference to this activity's ActionBar. 2105 * 2106 * @return The Activity's ActionBar, or null if it does not have one. 2107 */ 2108 @Nullable 2109 public ActionBar getActionBar() { 2110 initWindowDecorActionBar(); 2111 return mActionBar; 2112 } 2113 2114 /** 2115 * Set a {@link android.widget.Toolbar Toolbar} to act as the {@link ActionBar} for this 2116 * Activity window. 2117 * 2118 * <p>When set to a non-null value the {@link #getActionBar()} method will return 2119 * an {@link ActionBar} object that can be used to control the given toolbar as if it were 2120 * a traditional window decor action bar. The toolbar's menu will be populated with the 2121 * Activity's options menu and the navigation button will be wired through the standard 2122 * {@link android.R.id#home home} menu select action.</p> 2123 * 2124 * <p>In order to use a Toolbar within the Activity's window content the application 2125 * must not request the window feature {@link Window#FEATURE_ACTION_BAR FEATURE_ACTION_BAR}.</p> 2126 * 2127 * @param toolbar Toolbar to set as the Activity's action bar 2128 */ 2129 public void setActionBar(@Nullable Toolbar toolbar) { 2130 if (getActionBar() instanceof WindowDecorActionBar) { 2131 throw new IllegalStateException("This Activity already has an action bar supplied " + 2132 "by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " + 2133 "android:windowActionBar to false in your theme to use a Toolbar instead."); 2134 } 2135 // Clear out the MenuInflater to make sure that it is valid for the new Action Bar 2136 mMenuInflater = null; 2137 2138 ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this); 2139 mActionBar = tbab; 2140 mWindow.setCallback(tbab.getWrappedWindowCallback()); 2141 mActionBar.invalidateOptionsMenu(); 2142 } 2143 2144 /** 2145 * Creates a new ActionBar, locates the inflated ActionBarView, 2146 * initializes the ActionBar with the view, and sets mActionBar. 2147 */ 2148 private void initWindowDecorActionBar() { 2149 Window window = getWindow(); 2150 2151 // Initializing the window decor can change window feature flags. 2152 // Make sure that we have the correct set before performing the test below. 2153 window.getDecorView(); 2154 2155 if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) { 2156 return; 2157 } 2158 2159 mActionBar = new WindowDecorActionBar(this); 2160 mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp); 2161 2162 mWindow.setDefaultIcon(mActivityInfo.getIconResource()); 2163 mWindow.setDefaultLogo(mActivityInfo.getLogoResource()); 2164 } 2165 2166 /** 2167 * Set the activity content from a layout resource. The resource will be 2168 * inflated, adding all top-level views to the activity. 2169 * 2170 * @param layoutResID Resource ID to be inflated. 2171 * 2172 * @see #setContentView(android.view.View) 2173 * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) 2174 */ 2175 public void setContentView(@LayoutRes int layoutResID) { 2176 getWindow().setContentView(layoutResID); 2177 initWindowDecorActionBar(); 2178 } 2179 2180 /** 2181 * Set the activity content to an explicit view. This view is placed 2182 * directly into the activity's view hierarchy. It can itself be a complex 2183 * view hierarchy. When calling this method, the layout parameters of the 2184 * specified view are ignored. Both the width and the height of the view are 2185 * set by default to {@link ViewGroup.LayoutParams#MATCH_PARENT}. To use 2186 * your own layout parameters, invoke 2187 * {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)} 2188 * instead. 2189 * 2190 * @param view The desired content to display. 2191 * 2192 * @see #setContentView(int) 2193 * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) 2194 */ 2195 public void setContentView(View view) { 2196 getWindow().setContentView(view); 2197 initWindowDecorActionBar(); 2198 } 2199 2200 /** 2201 * Set the activity content to an explicit view. This view is placed 2202 * directly into the activity's view hierarchy. It can itself be a complex 2203 * view hierarchy. 2204 * 2205 * @param view The desired content to display. 2206 * @param params Layout parameters for the view. 2207 * 2208 * @see #setContentView(android.view.View) 2209 * @see #setContentView(int) 2210 */ 2211 public void setContentView(View view, ViewGroup.LayoutParams params) { 2212 getWindow().setContentView(view, params); 2213 initWindowDecorActionBar(); 2214 } 2215 2216 /** 2217 * Add an additional content view to the activity. Added after any existing 2218 * ones in the activity -- existing views are NOT removed. 2219 * 2220 * @param view The desired content to display. 2221 * @param params Layout parameters for the view. 2222 */ 2223 public void addContentView(View view, ViewGroup.LayoutParams params) { 2224 getWindow().addContentView(view, params); 2225 initWindowDecorActionBar(); 2226 } 2227 2228 /** 2229 * Retrieve the {@link TransitionManager} responsible for default transitions in this window. 2230 * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}. 2231 * 2232 * <p>This method will return non-null after content has been initialized (e.g. by using 2233 * {@link #setContentView}) if {@link Window#FEATURE_CONTENT_TRANSITIONS} has been granted.</p> 2234 * 2235 * @return This window's content TransitionManager or null if none is set. 2236 */ 2237 public TransitionManager getContentTransitionManager() { 2238 return getWindow().getTransitionManager(); 2239 } 2240 2241 /** 2242 * Set the {@link TransitionManager} to use for default transitions in this window. 2243 * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}. 2244 * 2245 * @param tm The TransitionManager to use for scene changes. 2246 */ 2247 public void setContentTransitionManager(TransitionManager tm) { 2248 getWindow().setTransitionManager(tm); 2249 } 2250 2251 /** 2252 * Retrieve the {@link Scene} representing this window's current content. 2253 * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}. 2254 * 2255 * <p>This method will return null if the current content is not represented by a Scene.</p> 2256 * 2257 * @return Current Scene being shown or null 2258 */ 2259 public Scene getContentScene() { 2260 return getWindow().getContentScene(); 2261 } 2262 2263 /** 2264 * Sets whether this activity is finished when touched outside its window's 2265 * bounds. 2266 */ 2267 public void setFinishOnTouchOutside(boolean finish) { 2268 mWindow.setCloseOnTouchOutside(finish); 2269 } 2270 2271 /** @hide */ 2272 @IntDef({ 2273 DEFAULT_KEYS_DISABLE, 2274 DEFAULT_KEYS_DIALER, 2275 DEFAULT_KEYS_SHORTCUT, 2276 DEFAULT_KEYS_SEARCH_LOCAL, 2277 DEFAULT_KEYS_SEARCH_GLOBAL}) 2278 @Retention(RetentionPolicy.SOURCE) 2279 @interface DefaultKeyMode {} 2280 2281 /** 2282 * Use with {@link #setDefaultKeyMode} to turn off default handling of 2283 * keys. 2284 * 2285 * @see #setDefaultKeyMode 2286 */ 2287 static public final int DEFAULT_KEYS_DISABLE = 0; 2288 /** 2289 * Use with {@link #setDefaultKeyMode} to launch the dialer during default 2290 * key handling. 2291 * 2292 * @see #setDefaultKeyMode 2293 */ 2294 static public final int DEFAULT_KEYS_DIALER = 1; 2295 /** 2296 * Use with {@link #setDefaultKeyMode} to execute a menu shortcut in 2297 * default key handling. 2298 * 2299 * <p>That is, the user does not need to hold down the menu key to execute menu shortcuts. 2300 * 2301 * @see #setDefaultKeyMode 2302 */ 2303 static public final int DEFAULT_KEYS_SHORTCUT = 2; 2304 /** 2305 * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes 2306 * will start an application-defined search. (If the application or activity does not 2307 * actually define a search, the the keys will be ignored.) 2308 * 2309 * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details. 2310 * 2311 * @see #setDefaultKeyMode 2312 */ 2313 static public final int DEFAULT_KEYS_SEARCH_LOCAL = 3; 2314 2315 /** 2316 * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes 2317 * will start a global search (typically web search, but some platforms may define alternate 2318 * methods for global search) 2319 * 2320 * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details. 2321 * 2322 * @see #setDefaultKeyMode 2323 */ 2324 static public final int DEFAULT_KEYS_SEARCH_GLOBAL = 4; 2325 2326 /** 2327 * Select the default key handling for this activity. This controls what 2328 * will happen to key events that are not otherwise handled. The default 2329 * mode ({@link #DEFAULT_KEYS_DISABLE}) will simply drop them on the 2330 * floor. Other modes allow you to launch the dialer 2331 * ({@link #DEFAULT_KEYS_DIALER}), execute a shortcut in your options 2332 * menu without requiring the menu key be held down 2333 * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL} 2334 * and {@link #DEFAULT_KEYS_SEARCH_GLOBAL}). 2335 * 2336 * <p>Note that the mode selected here does not impact the default 2337 * handling of system keys, such as the "back" and "menu" keys, and your 2338 * activity and its views always get a first chance to receive and handle 2339 * all application keys. 2340 * 2341 * @param mode The desired default key mode constant. 2342 * 2343 * @see #DEFAULT_KEYS_DISABLE 2344 * @see #DEFAULT_KEYS_DIALER 2345 * @see #DEFAULT_KEYS_SHORTCUT 2346 * @see #DEFAULT_KEYS_SEARCH_LOCAL 2347 * @see #DEFAULT_KEYS_SEARCH_GLOBAL 2348 * @see #onKeyDown 2349 */ 2350 public final void setDefaultKeyMode(@DefaultKeyMode int mode) { 2351 mDefaultKeyMode = mode; 2352 2353 // Some modes use a SpannableStringBuilder to track & dispatch input events 2354 // This list must remain in sync with the switch in onKeyDown() 2355 switch (mode) { 2356 case DEFAULT_KEYS_DISABLE: 2357 case DEFAULT_KEYS_SHORTCUT: 2358 mDefaultKeySsb = null; // not used in these modes 2359 break; 2360 case DEFAULT_KEYS_DIALER: 2361 case DEFAULT_KEYS_SEARCH_LOCAL: 2362 case DEFAULT_KEYS_SEARCH_GLOBAL: 2363 mDefaultKeySsb = new SpannableStringBuilder(); 2364 Selection.setSelection(mDefaultKeySsb,0); 2365 break; 2366 default: 2367 throw new IllegalArgumentException(); 2368 } 2369 } 2370 2371 /** 2372 * Called when a key was pressed down and not handled by any of the views 2373 * inside of the activity. So, for example, key presses while the cursor 2374 * is inside a TextView will not trigger the event (unless it is a navigation 2375 * to another object) because TextView handles its own key presses. 2376 * 2377 * <p>If the focused view didn't want this event, this method is called. 2378 * 2379 * <p>The default implementation takes care of {@link KeyEvent#KEYCODE_BACK} 2380 * by calling {@link #onBackPressed()}, though the behavior varies based 2381 * on the application compatibility mode: for 2382 * {@link android.os.Build.VERSION_CODES#ECLAIR} or later applications, 2383 * it will set up the dispatch to call {@link #onKeyUp} where the action 2384 * will be performed; for earlier applications, it will perform the 2385 * action immediately in on-down, as those versions of the platform 2386 * behaved. 2387 * 2388 * <p>Other additional default key handling may be performed 2389 * if configured with {@link #setDefaultKeyMode}. 2390 * 2391 * @return Return <code>true</code> to prevent this event from being propagated 2392 * further, or <code>false</code> to indicate that you have not handled 2393 * this event and it should continue to be propagated. 2394 * @see #onKeyUp 2395 * @see android.view.KeyEvent 2396 */ 2397 public boolean onKeyDown(int keyCode, KeyEvent event) { 2398 if (keyCode == KeyEvent.KEYCODE_BACK) { 2399 if (getApplicationInfo().targetSdkVersion 2400 >= Build.VERSION_CODES.ECLAIR) { 2401 event.startTracking(); 2402 } else { 2403 onBackPressed(); 2404 } 2405 return true; 2406 } 2407 2408 if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) { 2409 return false; 2410 } else if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) { 2411 Window w = getWindow(); 2412 if (w.hasFeature(Window.FEATURE_OPTIONS_PANEL) && 2413 w.performPanelShortcut(Window.FEATURE_OPTIONS_PANEL, keyCode, event, 2414 Menu.FLAG_ALWAYS_PERFORM_CLOSE)) { 2415 return true; 2416 } 2417 return false; 2418 } else { 2419 // Common code for DEFAULT_KEYS_DIALER & DEFAULT_KEYS_SEARCH_* 2420 boolean clearSpannable = false; 2421 boolean handled; 2422 if ((event.getRepeatCount() != 0) || event.isSystem()) { 2423 clearSpannable = true; 2424 handled = false; 2425 } else { 2426 handled = TextKeyListener.getInstance().onKeyDown( 2427 null, mDefaultKeySsb, keyCode, event); 2428 if (handled && mDefaultKeySsb.length() > 0) { 2429 // something useable has been typed - dispatch it now. 2430 2431 final String str = mDefaultKeySsb.toString(); 2432 clearSpannable = true; 2433 2434 switch (mDefaultKeyMode) { 2435 case DEFAULT_KEYS_DIALER: 2436 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + str)); 2437 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2438 startActivity(intent); 2439 break; 2440 case DEFAULT_KEYS_SEARCH_LOCAL: 2441 startSearch(str, false, null, false); 2442 break; 2443 case DEFAULT_KEYS_SEARCH_GLOBAL: 2444 startSearch(str, false, null, true); 2445 break; 2446 } 2447 } 2448 } 2449 if (clearSpannable) { 2450 mDefaultKeySsb.clear(); 2451 mDefaultKeySsb.clearSpans(); 2452 Selection.setSelection(mDefaultKeySsb,0); 2453 } 2454 return handled; 2455 } 2456 } 2457 2458 /** 2459 * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent) 2460 * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle 2461 * the event). 2462 */ 2463 public boolean onKeyLongPress(int keyCode, KeyEvent event) { 2464 return false; 2465 } 2466 2467 /** 2468 * Called when a key was released and not handled by any of the views 2469 * inside of the activity. So, for example, key presses while the cursor 2470 * is inside a TextView will not trigger the event (unless it is a navigation 2471 * to another object) because TextView handles its own key presses. 2472 * 2473 * <p>The default implementation handles KEYCODE_BACK to stop the activity 2474 * and go back. 2475 * 2476 * @return Return <code>true</code> to prevent this event from being propagated 2477 * further, or <code>false</code> to indicate that you have not handled 2478 * this event and it should continue to be propagated. 2479 * @see #onKeyDown 2480 * @see KeyEvent 2481 */ 2482 public boolean onKeyUp(int keyCode, KeyEvent event) { 2483 if (getApplicationInfo().targetSdkVersion 2484 >= Build.VERSION_CODES.ECLAIR) { 2485 if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() 2486 && !event.isCanceled()) { 2487 onBackPressed(); 2488 return true; 2489 } 2490 } 2491 return false; 2492 } 2493 2494 /** 2495 * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent) 2496 * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle 2497 * the event). 2498 */ 2499 public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { 2500 return false; 2501 } 2502 2503 /** 2504 * Called when the activity has detected the user's press of the back 2505 * key. The default implementation simply finishes the current activity, 2506 * but you can override this to do whatever you want. 2507 */ 2508 public void onBackPressed() { 2509 if (mActionBar != null && mActionBar.collapseActionView()) { 2510 return; 2511 } 2512 2513 if (!mFragments.getFragmentManager().popBackStackImmediate()) { 2514 finishAfterTransition(); 2515 } 2516 } 2517 2518 /** 2519 * Called when a key shortcut event is not handled by any of the views in the Activity. 2520 * Override this method to implement global key shortcuts for the Activity. 2521 * Key shortcuts can also be implemented by setting the 2522 * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items. 2523 * 2524 * @param keyCode The value in event.getKeyCode(). 2525 * @param event Description of the key event. 2526 * @return True if the key shortcut was handled. 2527 */ 2528 public boolean onKeyShortcut(int keyCode, KeyEvent event) { 2529 // Let the Action Bar have a chance at handling the shortcut. 2530 ActionBar actionBar = getActionBar(); 2531 return (actionBar != null && actionBar.onKeyShortcut(keyCode, event)); 2532 } 2533 2534 /** 2535 * Called when a touch screen event was not handled by any of the views 2536 * under it. This is most useful to process touch events that happen 2537 * outside of your window bounds, where there is no view to receive it. 2538 * 2539 * @param event The touch screen event being processed. 2540 * 2541 * @return Return true if you have consumed the event, false if you haven't. 2542 * The default implementation always returns false. 2543 */ 2544 public boolean onTouchEvent(MotionEvent event) { 2545 if (mWindow.shouldCloseOnTouch(this, event)) { 2546 finish(); 2547 return true; 2548 } 2549 2550 return false; 2551 } 2552 2553 /** 2554 * Called when the trackball was moved and not handled by any of the 2555 * views inside of the activity. So, for example, if the trackball moves 2556 * while focus is on a button, you will receive a call here because 2557 * buttons do not normally do anything with trackball events. The call 2558 * here happens <em>before</em> trackball movements are converted to 2559 * DPAD key events, which then get sent back to the view hierarchy, and 2560 * will be processed at the point for things like focus navigation. 2561 * 2562 * @param event The trackball event being processed. 2563 * 2564 * @return Return true if you have consumed the event, false if you haven't. 2565 * The default implementation always returns false. 2566 */ 2567 public boolean onTrackballEvent(MotionEvent event) { 2568 return false; 2569 } 2570 2571 /** 2572 * Called when a generic motion event was not handled by any of the 2573 * views inside of the activity. 2574 * <p> 2575 * Generic motion events describe joystick movements, mouse hovers, track pad 2576 * touches, scroll wheel movements and other input events. The 2577 * {@link MotionEvent#getSource() source} of the motion event specifies 2578 * the class of input that was received. Implementations of this method 2579 * must examine the bits in the source before processing the event. 2580 * The following code example shows how this is done. 2581 * </p><p> 2582 * Generic motion events with source class 2583 * {@link android.view.InputDevice#SOURCE_CLASS_POINTER} 2584 * are delivered to the view under the pointer. All other generic motion events are 2585 * delivered to the focused view. 2586 * </p><p> 2587 * See {@link View#onGenericMotionEvent(MotionEvent)} for an example of how to 2588 * handle this event. 2589 * </p> 2590 * 2591 * @param event The generic motion event being processed. 2592 * 2593 * @return Return true if you have consumed the event, false if you haven't. 2594 * The default implementation always returns false. 2595 */ 2596 public boolean onGenericMotionEvent(MotionEvent event) { 2597 return false; 2598 } 2599 2600 /** 2601 * Called whenever a key, touch, or trackball event is dispatched to the 2602 * activity. Implement this method if you wish to know that the user has 2603 * interacted with the device in some way while your activity is running. 2604 * This callback and {@link #onUserLeaveHint} are intended to help 2605 * activities manage status bar notifications intelligently; specifically, 2606 * for helping activities determine the proper time to cancel a notfication. 2607 * 2608 * <p>All calls to your activity's {@link #onUserLeaveHint} callback will 2609 * be accompanied by calls to {@link #onUserInteraction}. This 2610 * ensures that your activity will be told of relevant user activity such 2611 * as pulling down the notification pane and touching an item there. 2612 * 2613 * <p>Note that this callback will be invoked for the touch down action 2614 * that begins a touch gesture, but may not be invoked for the touch-moved 2615 * and touch-up actions that follow. 2616 * 2617 * @see #onUserLeaveHint() 2618 */ 2619 public void onUserInteraction() { 2620 } 2621 2622 public void onWindowAttributesChanged(WindowManager.LayoutParams params) { 2623 // Update window manager if: we have a view, that view is 2624 // attached to its parent (which will be a RootView), and 2625 // this activity is not embedded. 2626 if (mParent == null) { 2627 View decor = mDecor; 2628 if (decor != null && decor.getParent() != null) { 2629 getWindowManager().updateViewLayout(decor, params); 2630 } 2631 } 2632 } 2633 2634 public void onContentChanged() { 2635 } 2636 2637 /** 2638 * Called when the current {@link Window} of the activity gains or loses 2639 * focus. This is the best indicator of whether this activity is visible 2640 * to the user. The default implementation clears the key tracking 2641 * state, so should always be called. 2642 * 2643 * <p>Note that this provides information about global focus state, which 2644 * is managed independently of activity lifecycles. As such, while focus 2645 * changes will generally have some relation to lifecycle changes (an 2646 * activity that is stopped will not generally get window focus), you 2647 * should not rely on any particular order between the callbacks here and 2648 * those in the other lifecycle methods such as {@link #onResume}. 2649 * 2650 * <p>As a general rule, however, a resumed activity will have window 2651 * focus... unless it has displayed other dialogs or popups that take 2652 * input focus, in which case the activity itself will not have focus 2653 * when the other windows have it. Likewise, the system may display 2654 * system-level windows (such as the status bar notification panel or 2655 * a system alert) which will temporarily take window input focus without 2656 * pausing the foreground activity. 2657 * 2658 * @param hasFocus Whether the window of this activity has focus. 2659 * 2660 * @see #hasWindowFocus() 2661 * @see #onResume 2662 * @see View#onWindowFocusChanged(boolean) 2663 */ 2664 public void onWindowFocusChanged(boolean hasFocus) { 2665 } 2666 2667 /** 2668 * Called when the main window associated with the activity has been 2669 * attached to the window manager. 2670 * See {@link View#onAttachedToWindow() View.onAttachedToWindow()} 2671 * for more information. 2672 * @see View#onAttachedToWindow 2673 */ 2674 public void onAttachedToWindow() { 2675 } 2676 2677 /** 2678 * Called when the main window associated with the activity has been 2679 * detached from the window manager. 2680 * See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()} 2681 * for more information. 2682 * @see View#onDetachedFromWindow 2683 */ 2684 public void onDetachedFromWindow() { 2685 } 2686 2687 /** 2688 * Returns true if this activity's <em>main</em> window currently has window focus. 2689 * Note that this is not the same as the view itself having focus. 2690 * 2691 * @return True if this activity's main window currently has window focus. 2692 * 2693 * @see #onWindowAttributesChanged(android.view.WindowManager.LayoutParams) 2694 */ 2695 public boolean hasWindowFocus() { 2696 Window w = getWindow(); 2697 if (w != null) { 2698 View d = w.getDecorView(); 2699 if (d != null) { 2700 return d.hasWindowFocus(); 2701 } 2702 } 2703 return false; 2704 } 2705 2706 /** 2707 * Called when the main window associated with the activity has been dismissed. 2708 * @hide 2709 */ 2710 @Override 2711 public void onWindowDismissed(boolean finishTask) { 2712 finish(finishTask ? FINISH_TASK_WITH_ACTIVITY : DONT_FINISH_TASK_WITH_ACTIVITY); 2713 } 2714 2715 2716 /** 2717 * Called to move the window and its activity/task to a different stack container. 2718 * For example, a window can move between 2719 * {@link android.app.ActivityManager#FULLSCREEN_WORKSPACE_STACK_ID} stack and 2720 * {@link android.app.ActivityManager#FREEFORM_WORKSPACE_STACK_ID} stack. 2721 * 2722 * @param stackId stack Id to change to. 2723 * @hide 2724 */ 2725 @Override 2726 public void changeWindowStack(int stackId) throws RemoteException { 2727 ActivityManagerNative.getDefault().moveActivityToStack(mToken, stackId); 2728 } 2729 2730 /** Returns the current stack Id for the window. 2731 * @hide 2732 */ 2733 @Override 2734 public int getWindowStackId() throws RemoteException { 2735 return ActivityManagerNative.getDefault().getActivityStackId(mToken); 2736 } 2737 2738 /** 2739 * Returns the bounds of the task that contains this activity. 2740 * 2741 * @return Rect The bounds that contains the activity. 2742 * @hide 2743 */ 2744 @Override 2745 public Rect getActivityBounds() throws RemoteException { 2746 return ActivityManagerNative.getDefault().getActivityBounds(mToken); 2747 } 2748 2749 /** 2750 * Sets the bounds (size and position) of the task or stack that contains this 2751 * activity. 2752 * NOTE: The requested bounds might not the fully honored by the system depending 2753 * on the window placement policy. 2754 * 2755 * @param newBounds The new target bounds of the activity in task or stack. 2756 * @hide 2757 */ 2758 @Override 2759 public void setActivityBounds(Rect newBounds) throws RemoteException { 2760 ActivityManagerNative.getDefault().setActivityBounds(mToken, newBounds); 2761 } 2762 2763 /** 2764 * Activates this activity, hence bringing it to the top and giving it focus. 2765 * Note: This will only work for activities which are located on the freeform desktop. 2766 * @hide 2767 */ 2768 public void activateActivity() throws RemoteException { 2769 ActivityManagerNative.getDefault().activateActivity(mToken); 2770 } 2771 2772 /** 2773 * Called to process key events. You can override this to intercept all 2774 * key events before they are dispatched to the window. Be sure to call 2775 * this implementation for key events that should be handled normally. 2776 * 2777 * @param event The key event. 2778 * 2779 * @return boolean Return true if this event was consumed. 2780 */ 2781 public boolean dispatchKeyEvent(KeyEvent event) { 2782 onUserInteraction(); 2783 2784 // Let action bars open menus in response to the menu key prioritized over 2785 // the window handling it 2786 if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && 2787 mActionBar != null && mActionBar.onMenuKeyEvent(event)) { 2788 return true; 2789 } 2790 2791 Window win = getWindow(); 2792 if (win.superDispatchKeyEvent(event)) { 2793 return true; 2794 } 2795 View decor = mDecor; 2796 if (decor == null) decor = win.getDecorView(); 2797 return event.dispatch(this, decor != null 2798 ? decor.getKeyDispatcherState() : null, this); 2799 } 2800 2801 /** 2802 * Called to process a key shortcut event. 2803 * You can override this to intercept all key shortcut events before they are 2804 * dispatched to the window. Be sure to call this implementation for key shortcut 2805 * events that should be handled normally. 2806 * 2807 * @param event The key shortcut event. 2808 * @return True if this event was consumed. 2809 */ 2810 public boolean dispatchKeyShortcutEvent(KeyEvent event) { 2811 onUserInteraction(); 2812 if (getWindow().superDispatchKeyShortcutEvent(event)) { 2813 return true; 2814 } 2815 return onKeyShortcut(event.getKeyCode(), event); 2816 } 2817 2818 /** 2819 * Called to process touch screen events. You can override this to 2820 * intercept all touch screen events before they are dispatched to the 2821 * window. Be sure to call this implementation for touch screen events 2822 * that should be handled normally. 2823 * 2824 * @param ev The touch screen event. 2825 * 2826 * @return boolean Return true if this event was consumed. 2827 */ 2828 public boolean dispatchTouchEvent(MotionEvent ev) { 2829 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 2830 onUserInteraction(); 2831 } 2832 if (getWindow().superDispatchTouchEvent(ev)) { 2833 return true; 2834 } 2835 return onTouchEvent(ev); 2836 } 2837 2838 /** 2839 * Called to process trackball events. You can override this to 2840 * intercept all trackball events before they are dispatched to the 2841 * window. Be sure to call this implementation for trackball events 2842 * that should be handled normally. 2843 * 2844 * @param ev The trackball event. 2845 * 2846 * @return boolean Return true if this event was consumed. 2847 */ 2848 public boolean dispatchTrackballEvent(MotionEvent ev) { 2849 onUserInteraction(); 2850 if (getWindow().superDispatchTrackballEvent(ev)) { 2851 return true; 2852 } 2853 return onTrackballEvent(ev); 2854 } 2855 2856 /** 2857 * Called to process generic motion events. You can override this to 2858 * intercept all generic motion events before they are dispatched to the 2859 * window. Be sure to call this implementation for generic motion events 2860 * that should be handled normally. 2861 * 2862 * @param ev The generic motion event. 2863 * 2864 * @return boolean Return true if this event was consumed. 2865 */ 2866 public boolean dispatchGenericMotionEvent(MotionEvent ev) { 2867 onUserInteraction(); 2868 if (getWindow().superDispatchGenericMotionEvent(ev)) { 2869 return true; 2870 } 2871 return onGenericMotionEvent(ev); 2872 } 2873 2874 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 2875 event.setClassName(getClass().getName()); 2876 event.setPackageName(getPackageName()); 2877 2878 LayoutParams params = getWindow().getAttributes(); 2879 boolean isFullScreen = (params.width == LayoutParams.MATCH_PARENT) && 2880 (params.height == LayoutParams.MATCH_PARENT); 2881 event.setFullScreen(isFullScreen); 2882 2883 CharSequence title = getTitle(); 2884 if (!TextUtils.isEmpty(title)) { 2885 event.getText().add(title); 2886 } 2887 2888 return true; 2889 } 2890 2891 /** 2892 * Default implementation of 2893 * {@link android.view.Window.Callback#onCreatePanelView} 2894 * for activities. This 2895 * simply returns null so that all panel sub-windows will have the default 2896 * menu behavior. 2897 */ 2898 @Nullable 2899 public View onCreatePanelView(int featureId) { 2900 return null; 2901 } 2902 2903 /** 2904 * Default implementation of 2905 * {@link android.view.Window.Callback#onCreatePanelMenu} 2906 * for activities. This calls through to the new 2907 * {@link #onCreateOptionsMenu} method for the 2908 * {@link android.view.Window#FEATURE_OPTIONS_PANEL} panel, 2909 * so that subclasses of Activity don't need to deal with feature codes. 2910 */ 2911 public boolean onCreatePanelMenu(int featureId, Menu menu) { 2912 if (featureId == Window.FEATURE_OPTIONS_PANEL) { 2913 boolean show = onCreateOptionsMenu(menu); 2914 show |= mFragments.dispatchCreateOptionsMenu(menu, getMenuInflater()); 2915 return show; 2916 } 2917 return false; 2918 } 2919 2920 /** 2921 * Default implementation of 2922 * {@link android.view.Window.Callback#onPreparePanel} 2923 * for activities. This 2924 * calls through to the new {@link #onPrepareOptionsMenu} method for the 2925 * {@link android.view.Window#FEATURE_OPTIONS_PANEL} 2926 * panel, so that subclasses of 2927 * Activity don't need to deal with feature codes. 2928 */ 2929 public boolean onPreparePanel(int featureId, View view, Menu menu) { 2930 if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) { 2931 boolean goforit = onPrepareOptionsMenu(menu); 2932 goforit |= mFragments.dispatchPrepareOptionsMenu(menu); 2933 return goforit; 2934 } 2935 return true; 2936 } 2937 2938 /** 2939 * {@inheritDoc} 2940 * 2941 * @return The default implementation returns true. 2942 */ 2943 public boolean onMenuOpened(int featureId, Menu menu) { 2944 if (featureId == Window.FEATURE_ACTION_BAR) { 2945 initWindowDecorActionBar(); 2946 if (mActionBar != null) { 2947 mActionBar.dispatchMenuVisibilityChanged(true); 2948 } else { 2949 Log.e(TAG, "Tried to open action bar menu with no action bar"); 2950 } 2951 } 2952 return true; 2953 } 2954 2955 /** 2956 * Default implementation of 2957 * {@link android.view.Window.Callback#onMenuItemSelected} 2958 * for activities. This calls through to the new 2959 * {@link #onOptionsItemSelected} method for the 2960 * {@link android.view.Window#FEATURE_OPTIONS_PANEL} 2961 * panel, so that subclasses of 2962 * Activity don't need to deal with feature codes. 2963 */ 2964 public boolean onMenuItemSelected(int featureId, MenuItem item) { 2965 CharSequence titleCondensed = item.getTitleCondensed(); 2966 2967 switch (featureId) { 2968 case Window.FEATURE_OPTIONS_PANEL: 2969 // Put event logging here so it gets called even if subclass 2970 // doesn't call through to superclass's implmeentation of each 2971 // of these methods below 2972 if(titleCondensed != null) { 2973 EventLog.writeEvent(50000, 0, titleCondensed.toString()); 2974 } 2975 if (onOptionsItemSelected(item)) { 2976 return true; 2977 } 2978 if (mFragments.dispatchOptionsItemSelected(item)) { 2979 return true; 2980 } 2981 if (item.getItemId() == android.R.id.home && mActionBar != null && 2982 (mActionBar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) { 2983 if (mParent == null) { 2984 return onNavigateUp(); 2985 } else { 2986 return mParent.onNavigateUpFromChild(this); 2987 } 2988 } 2989 return false; 2990 2991 case Window.FEATURE_CONTEXT_MENU: 2992 if(titleCondensed != null) { 2993 EventLog.writeEvent(50000, 1, titleCondensed.toString()); 2994 } 2995 if (onContextItemSelected(item)) { 2996 return true; 2997 } 2998 return mFragments.dispatchContextItemSelected(item); 2999 3000 default: 3001 return false; 3002 } 3003 } 3004 3005 /** 3006 * Default implementation of 3007 * {@link android.view.Window.Callback#onPanelClosed(int, Menu)} for 3008 * activities. This calls through to {@link #onOptionsMenuClosed(Menu)} 3009 * method for the {@link android.view.Window#FEATURE_OPTIONS_PANEL} panel, 3010 * so that subclasses of Activity don't need to deal with feature codes. 3011 * For context menus ({@link Window#FEATURE_CONTEXT_MENU}), the 3012 * {@link #onContextMenuClosed(Menu)} will be called. 3013 */ 3014 public void onPanelClosed(int featureId, Menu menu) { 3015 switch (featureId) { 3016 case Window.FEATURE_OPTIONS_PANEL: 3017 mFragments.dispatchOptionsMenuClosed(menu); 3018 onOptionsMenuClosed(menu); 3019 break; 3020 3021 case Window.FEATURE_CONTEXT_MENU: 3022 onContextMenuClosed(menu); 3023 break; 3024 3025 case Window.FEATURE_ACTION_BAR: 3026 initWindowDecorActionBar(); 3027 mActionBar.dispatchMenuVisibilityChanged(false); 3028 break; 3029 } 3030 } 3031 3032 /** 3033 * Declare that the options menu has changed, so should be recreated. 3034 * The {@link #onCreateOptionsMenu(Menu)} method will be called the next 3035 * time it needs to be displayed. 3036 */ 3037 public void invalidateOptionsMenu() { 3038 if (mWindow.hasFeature(Window.FEATURE_OPTIONS_PANEL) && 3039 (mActionBar == null || !mActionBar.invalidateOptionsMenu())) { 3040 mWindow.invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL); 3041 } 3042 } 3043 3044 /** 3045 * Initialize the contents of the Activity's standard options menu. You 3046 * should place your menu items in to <var>menu</var>. 3047 * 3048 * <p>This is only called once, the first time the options menu is 3049 * displayed. To update the menu every time it is displayed, see 3050 * {@link #onPrepareOptionsMenu}. 3051 * 3052 * <p>The default implementation populates the menu with standard system 3053 * menu items. These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that 3054 * they will be correctly ordered with application-defined menu items. 3055 * Deriving classes should always call through to the base implementation. 3056 * 3057 * <p>You can safely hold on to <var>menu</var> (and any items created 3058 * from it), making modifications to it as desired, until the next 3059 * time onCreateOptionsMenu() is called. 3060 * 3061 * <p>When you add items to the menu, you can implement the Activity's 3062 * {@link #onOptionsItemSelected} method to handle them there. 3063 * 3064 * @param menu The options menu in which you place your items. 3065 * 3066 * @return You must return true for the menu to be displayed; 3067 * if you return false it will not be shown. 3068 * 3069 * @see #onPrepareOptionsMenu 3070 * @see #onOptionsItemSelected 3071 */ 3072 public boolean onCreateOptionsMenu(Menu menu) { 3073 if (mParent != null) { 3074 return mParent.onCreateOptionsMenu(menu); 3075 } 3076 return true; 3077 } 3078 3079 /** 3080 * Prepare the Screen's standard options menu to be displayed. This is 3081 * called right before the menu is shown, every time it is shown. You can 3082 * use this method to efficiently enable/disable items or otherwise 3083 * dynamically modify the contents. 3084 * 3085 * <p>The default implementation updates the system menu items based on the 3086 * activity's state. Deriving classes should always call through to the 3087 * base class implementation. 3088 * 3089 * @param menu The options menu as last shown or first initialized by 3090 * onCreateOptionsMenu(). 3091 * 3092 * @return You must return true for the menu to be displayed; 3093 * if you return false it will not be shown. 3094 * 3095 * @see #onCreateOptionsMenu 3096 */ 3097 public boolean onPrepareOptionsMenu(Menu menu) { 3098 if (mParent != null) { 3099 return mParent.onPrepareOptionsMenu(menu); 3100 } 3101 return true; 3102 } 3103 3104 /** 3105 * This hook is called whenever an item in your options menu is selected. 3106 * The default implementation simply returns false to have the normal 3107 * processing happen (calling the item's Runnable or sending a message to 3108 * its Handler as appropriate). You can use this method for any items 3109 * for which you would like to do processing without those other 3110 * facilities. 3111 * 3112 * <p>Derived classes should call through to the base class for it to 3113 * perform the default menu handling.</p> 3114 * 3115 * @param item The menu item that was selected. 3116 * 3117 * @return boolean Return false to allow normal menu processing to 3118 * proceed, true to consume it here. 3119 * 3120 * @see #onCreateOptionsMenu 3121 */ 3122 public boolean onOptionsItemSelected(MenuItem item) { 3123 if (mParent != null) { 3124 return mParent.onOptionsItemSelected(item); 3125 } 3126 return false; 3127 } 3128 3129 /** 3130 * This method is called whenever the user chooses to navigate Up within your application's 3131 * activity hierarchy from the action bar. 3132 * 3133 * <p>If the attribute {@link android.R.attr#parentActivityName parentActivityName} 3134 * was specified in the manifest for this activity or an activity-alias to it, 3135 * default Up navigation will be handled automatically. If any activity 3136 * along the parent chain requires extra Intent arguments, the Activity subclass 3137 * should override the method {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)} 3138 * to supply those arguments.</p> 3139 * 3140 * <p>See <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a> 3141 * from the developer guide and <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> 3142 * from the design guide for more information about navigating within your app.</p> 3143 * 3144 * <p>See the {@link TaskStackBuilder} class and the Activity methods 3145 * {@link #getParentActivityIntent()}, {@link #shouldUpRecreateTask(Intent)}, and 3146 * {@link #navigateUpTo(Intent)} for help implementing custom Up navigation. 3147 * The AppNavigation sample application in the Android SDK is also available for reference.</p> 3148 * 3149 * @return true if Up navigation completed successfully and this Activity was finished, 3150 * false otherwise. 3151 */ 3152 public boolean onNavigateUp() { 3153 // Automatically handle hierarchical Up navigation if the proper 3154 // metadata is available. 3155 Intent upIntent = getParentActivityIntent(); 3156 if (upIntent != null) { 3157 if (mActivityInfo.taskAffinity == null) { 3158 // Activities with a null affinity are special; they really shouldn't 3159 // specify a parent activity intent in the first place. Just finish 3160 // the current activity and call it a day. 3161 finish(); 3162 } else if (shouldUpRecreateTask(upIntent)) { 3163 TaskStackBuilder b = TaskStackBuilder.create(this); 3164 onCreateNavigateUpTaskStack(b); 3165 onPrepareNavigateUpTaskStack(b); 3166 b.startActivities(); 3167 3168 // We can't finishAffinity if we have a result. 3169 // Fall back and simply finish the current activity instead. 3170 if (mResultCode != RESULT_CANCELED || mResultData != null) { 3171 // Tell the developer what's going on to avoid hair-pulling. 3172 Log.i(TAG, "onNavigateUp only finishing topmost activity to return a result"); 3173 finish(); 3174 } else { 3175 finishAffinity(); 3176 } 3177 } else { 3178 navigateUpTo(upIntent); 3179 } 3180 return true; 3181 } 3182 return false; 3183 } 3184 3185 /** 3186 * This is called when a child activity of this one attempts to navigate up. 3187 * The default implementation simply calls onNavigateUp() on this activity (the parent). 3188 * 3189 * @param child The activity making the call. 3190 */ 3191 public boolean onNavigateUpFromChild(Activity child) { 3192 return onNavigateUp(); 3193 } 3194 3195 /** 3196 * Define the synthetic task stack that will be generated during Up navigation from 3197 * a different task. 3198 * 3199 * <p>The default implementation of this method adds the parent chain of this activity 3200 * as specified in the manifest to the supplied {@link TaskStackBuilder}. Applications 3201 * may choose to override this method to construct the desired task stack in a different 3202 * way.</p> 3203 * 3204 * <p>This method will be invoked by the default implementation of {@link #onNavigateUp()} 3205 * if {@link #shouldUpRecreateTask(Intent)} returns true when supplied with the intent 3206 * returned by {@link #getParentActivityIntent()}.</p> 3207 * 3208 * <p>Applications that wish to supply extra Intent parameters to the parent stack defined 3209 * by the manifest should override {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)}.</p> 3210 * 3211 * @param builder An empty TaskStackBuilder - the application should add intents representing 3212 * the desired task stack 3213 */ 3214 public void onCreateNavigateUpTaskStack(TaskStackBuilder builder) { 3215 builder.addParentStack(this); 3216 } 3217 3218 /** 3219 * Prepare the synthetic task stack that will be generated during Up navigation 3220 * from a different task. 3221 * 3222 * <p>This method receives the {@link TaskStackBuilder} with the constructed series of 3223 * Intents as generated by {@link #onCreateNavigateUpTaskStack(TaskStackBuilder)}. 3224 * If any extra data should be added to these intents before launching the new task, 3225 * the application should override this method and add that data here.</p> 3226 * 3227 * @param builder A TaskStackBuilder that has been populated with Intents by 3228 * onCreateNavigateUpTaskStack. 3229 */ 3230 public void onPrepareNavigateUpTaskStack(TaskStackBuilder builder) { 3231 } 3232 3233 /** 3234 * This hook is called whenever the options menu is being closed (either by the user canceling 3235 * the menu with the back/menu button, or when an item is selected). 3236 * 3237 * @param menu The options menu as last shown or first initialized by 3238 * onCreateOptionsMenu(). 3239 */ 3240 public void onOptionsMenuClosed(Menu menu) { 3241 if (mParent != null) { 3242 mParent.onOptionsMenuClosed(menu); 3243 } 3244 } 3245 3246 /** 3247 * Programmatically opens the options menu. If the options menu is already 3248 * open, this method does nothing. 3249 */ 3250 public void openOptionsMenu() { 3251 if (mWindow.hasFeature(Window.FEATURE_OPTIONS_PANEL) && 3252 (mActionBar == null || !mActionBar.openOptionsMenu())) { 3253 mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null); 3254 } 3255 } 3256 3257 /** 3258 * Progammatically closes the options menu. If the options menu is already 3259 * closed, this method does nothing. 3260 */ 3261 public void closeOptionsMenu() { 3262 if (mWindow.hasFeature(Window.FEATURE_OPTIONS_PANEL)) { 3263 mWindow.closePanel(Window.FEATURE_OPTIONS_PANEL); 3264 } 3265 } 3266 3267 /** 3268 * Called when a context menu for the {@code view} is about to be shown. 3269 * Unlike {@link #onCreateOptionsMenu(Menu)}, this will be called every 3270 * time the context menu is about to be shown and should be populated for 3271 * the view (or item inside the view for {@link AdapterView} subclasses, 3272 * this can be found in the {@code menuInfo})). 3273 * <p> 3274 * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an 3275 * item has been selected. 3276 * <p> 3277 * It is not safe to hold onto the context menu after this method returns. 3278 * 3279 */ 3280 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 3281 } 3282 3283 /** 3284 * Registers a context menu to be shown for the given view (multiple views 3285 * can show the context menu). This method will set the 3286 * {@link OnCreateContextMenuListener} on the view to this activity, so 3287 * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be 3288 * called when it is time to show the context menu. 3289 * 3290 * @see #unregisterForContextMenu(View) 3291 * @param view The view that should show a context menu. 3292 */ 3293 public void registerForContextMenu(View view) { 3294 view.setOnCreateContextMenuListener(this); 3295 } 3296 3297 /** 3298 * Prevents a context menu to be shown for the given view. This method will remove the 3299 * {@link OnCreateContextMenuListener} on the view. 3300 * 3301 * @see #registerForContextMenu(View) 3302 * @param view The view that should stop showing a context menu. 3303 */ 3304 public void unregisterForContextMenu(View view) { 3305 view.setOnCreateContextMenuListener(null); 3306 } 3307 3308 /** 3309 * Programmatically opens the context menu for a particular {@code view}. 3310 * The {@code view} should have been added via 3311 * {@link #registerForContextMenu(View)}. 3312 * 3313 * @param view The view to show the context menu for. 3314 */ 3315 public void openContextMenu(View view) { 3316 view.showContextMenu(); 3317 } 3318 3319 /** 3320 * Programmatically closes the most recently opened context menu, if showing. 3321 */ 3322 public void closeContextMenu() { 3323 if (mWindow.hasFeature(Window.FEATURE_CONTEXT_MENU)) { 3324 mWindow.closePanel(Window.FEATURE_CONTEXT_MENU); 3325 } 3326 } 3327 3328 /** 3329 * This hook is called whenever an item in a context menu is selected. The 3330 * default implementation simply returns false to have the normal processing 3331 * happen (calling the item's Runnable or sending a message to its Handler 3332 * as appropriate). You can use this method for any items for which you 3333 * would like to do processing without those other facilities. 3334 * <p> 3335 * Use {@link MenuItem#getMenuInfo()} to get extra information set by the 3336 * View that added this menu item. 3337 * <p> 3338 * Derived classes should call through to the base class for it to perform 3339 * the default menu handling. 3340 * 3341 * @param item The context menu item that was selected. 3342 * @return boolean Return false to allow normal context menu processing to 3343 * proceed, true to consume it here. 3344 */ 3345 public boolean onContextItemSelected(MenuItem item) { 3346 if (mParent != null) { 3347 return mParent.onContextItemSelected(item); 3348 } 3349 return false; 3350 } 3351 3352 /** 3353 * This hook is called whenever the context menu is being closed (either by 3354 * the user canceling the menu with the back/menu button, or when an item is 3355 * selected). 3356 * 3357 * @param menu The context menu that is being closed. 3358 */ 3359 public void onContextMenuClosed(Menu menu) { 3360 if (mParent != null) { 3361 mParent.onContextMenuClosed(menu); 3362 } 3363 } 3364 3365 /** 3366 * @deprecated Old no-arguments version of {@link #onCreateDialog(int, Bundle)}. 3367 */ 3368 @Deprecated 3369 protected Dialog onCreateDialog(int id) { 3370 return null; 3371 } 3372 3373 /** 3374 * Callback for creating dialogs that are managed (saved and restored) for you 3375 * by the activity. The default implementation calls through to 3376 * {@link #onCreateDialog(int)} for compatibility. 3377 * 3378 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 3379 * or later, consider instead using a {@link DialogFragment} instead.</em> 3380 * 3381 * <p>If you use {@link #showDialog(int)}, the activity will call through to 3382 * this method the first time, and hang onto it thereafter. Any dialog 3383 * that is created by this method will automatically be saved and restored 3384 * for you, including whether it is showing. 3385 * 3386 * <p>If you would like the activity to manage saving and restoring dialogs 3387 * for you, you should override this method and handle any ids that are 3388 * passed to {@link #showDialog}. 3389 * 3390 * <p>If you would like an opportunity to prepare your dialog before it is shown, 3391 * override {@link #onPrepareDialog(int, Dialog, Bundle)}. 3392 * 3393 * @param id The id of the dialog. 3394 * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}. 3395 * @return The dialog. If you return null, the dialog will not be created. 3396 * 3397 * @see #onPrepareDialog(int, Dialog, Bundle) 3398 * @see #showDialog(int, Bundle) 3399 * @see #dismissDialog(int) 3400 * @see #removeDialog(int) 3401 * 3402 * @deprecated Use the new {@link DialogFragment} class with 3403 * {@link FragmentManager} instead; this is also 3404 * available on older platforms through the Android compatibility package. 3405 */ 3406 @Nullable 3407 @Deprecated 3408 protected Dialog onCreateDialog(int id, Bundle args) { 3409 return onCreateDialog(id); 3410 } 3411 3412 /** 3413 * @deprecated Old no-arguments version of 3414 * {@link #onPrepareDialog(int, Dialog, Bundle)}. 3415 */ 3416 @Deprecated 3417 protected void onPrepareDialog(int id, Dialog dialog) { 3418 dialog.setOwnerActivity(this); 3419 } 3420 3421 /** 3422 * Provides an opportunity to prepare a managed dialog before it is being 3423 * shown. The default implementation calls through to 3424 * {@link #onPrepareDialog(int, Dialog)} for compatibility. 3425 * 3426 * <p> 3427 * Override this if you need to update a managed dialog based on the state 3428 * of the application each time it is shown. For example, a time picker 3429 * dialog might want to be updated with the current time. You should call 3430 * through to the superclass's implementation. The default implementation 3431 * will set this Activity as the owner activity on the Dialog. 3432 * 3433 * @param id The id of the managed dialog. 3434 * @param dialog The dialog. 3435 * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}. 3436 * @see #onCreateDialog(int, Bundle) 3437 * @see #showDialog(int) 3438 * @see #dismissDialog(int) 3439 * @see #removeDialog(int) 3440 * 3441 * @deprecated Use the new {@link DialogFragment} class with 3442 * {@link FragmentManager} instead; this is also 3443 * available on older platforms through the Android compatibility package. 3444 */ 3445 @Deprecated 3446 protected void onPrepareDialog(int id, Dialog dialog, Bundle args) { 3447 onPrepareDialog(id, dialog); 3448 } 3449 3450 /** 3451 * Simple version of {@link #showDialog(int, Bundle)} that does not 3452 * take any arguments. Simply calls {@link #showDialog(int, Bundle)} 3453 * with null arguments. 3454 * 3455 * @deprecated Use the new {@link DialogFragment} class with 3456 * {@link FragmentManager} instead; this is also 3457 * available on older platforms through the Android compatibility package. 3458 */ 3459 @Deprecated 3460 public final void showDialog(int id) { 3461 showDialog(id, null); 3462 } 3463 3464 /** 3465 * Show a dialog managed by this activity. A call to {@link #onCreateDialog(int, Bundle)} 3466 * will be made with the same id the first time this is called for a given 3467 * id. From thereafter, the dialog will be automatically saved and restored. 3468 * 3469 * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB} 3470 * or later, consider instead using a {@link DialogFragment} instead.</em> 3471 * 3472 * <p>Each time a dialog is shown, {@link #onPrepareDialog(int, Dialog, Bundle)} will 3473 * be made to provide an opportunity to do any timely preparation. 3474 * 3475 * @param id The id of the managed dialog. 3476 * @param args Arguments to pass through to the dialog. These will be saved 3477 * and restored for you. Note that if the dialog is already created, 3478 * {@link #onCreateDialog(int, Bundle)} will not be called with the new 3479 * arguments but {@link #onPrepareDialog(int, Dialog, Bundle)} will be. 3480 * If you need to rebuild the dialog, call {@link #removeDialog(int)} first. 3481 * @return Returns true if the Dialog was created; false is returned if 3482 * it is not created because {@link #onCreateDialog(int, Bundle)} returns false. 3483 * 3484 * @see Dialog 3485 * @see #onCreateDialog(int, Bundle) 3486 * @see #onPrepareDialog(int, Dialog, Bundle) 3487 * @see #dismissDialog(int) 3488 * @see #removeDialog(int) 3489 * 3490 * @deprecated Use the new {@link DialogFragment} class with 3491 * {@link FragmentManager} instead; this is also 3492 * available on older platforms through the Android compatibility package. 3493 */ 3494 @Nullable 3495 @Deprecated 3496 public final boolean showDialog(int id, Bundle args) { 3497 if (mManagedDialogs == null) { 3498 mManagedDialogs = new SparseArray<ManagedDialog>(); 3499 } 3500 ManagedDialog md = mManagedDialogs.get(id); 3501 if (md == null) { 3502 md = new ManagedDialog(); 3503 md.mDialog = createDialog(id, null, args); 3504 if (md.mDialog == null) { 3505 return false; 3506 } 3507 mManagedDialogs.put(id, md); 3508 } 3509 3510 md.mArgs = args; 3511 onPrepareDialog(id, md.mDialog, args); 3512 md.mDialog.show(); 3513 return true; 3514 } 3515 3516 /** 3517 * Dismiss a dialog that was previously shown via {@link #showDialog(int)}. 3518 * 3519 * @param id The id of the managed dialog. 3520 * 3521 * @throws IllegalArgumentException if the id was not previously shown via 3522 * {@link #showDialog(int)}. 3523 * 3524 * @see #onCreateDialog(int, Bundle) 3525 * @see #onPrepareDialog(int, Dialog, Bundle) 3526 * @see #showDialog(int) 3527 * @see #removeDialog(int) 3528 * 3529 * @deprecated Use the new {@link DialogFragment} class with 3530 * {@link FragmentManager} instead; this is also 3531 * available on older platforms through the Android compatibility package. 3532 */ 3533 @Deprecated 3534 public final void dismissDialog(int id) { 3535 if (mManagedDialogs == null) { 3536 throw missingDialog(id); 3537 } 3538 3539 final ManagedDialog md = mManagedDialogs.get(id); 3540 if (md == null) { 3541 throw missingDialog(id); 3542 } 3543 md.mDialog.dismiss(); 3544 } 3545 3546 /** 3547 * Creates an exception to throw if a user passed in a dialog id that is 3548 * unexpected. 3549 */ 3550 private IllegalArgumentException missingDialog(int id) { 3551 return new IllegalArgumentException("no dialog with id " + id + " was ever " 3552 + "shown via Activity#showDialog"); 3553 } 3554 3555 /** 3556 * Removes any internal references to a dialog managed by this Activity. 3557 * If the dialog is showing, it will dismiss it as part of the clean up. 3558 * 3559 * <p>This can be useful if you know that you will never show a dialog again and 3560 * want to avoid the overhead of saving and restoring it in the future. 3561 * 3562 * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, this function 3563 * will not throw an exception if you try to remove an ID that does not 3564 * currently have an associated dialog.</p> 3565 * 3566 * @param id The id of the managed dialog. 3567 * 3568 * @see #onCreateDialog(int, Bundle) 3569 * @see #onPrepareDialog(int, Dialog, Bundle) 3570 * @see #showDialog(int) 3571 * @see #dismissDialog(int) 3572 * 3573 * @deprecated Use the new {@link DialogFragment} class with 3574 * {@link FragmentManager} instead; this is also 3575 * available on older platforms through the Android compatibility package. 3576 */ 3577 @Deprecated 3578 public final void removeDialog(int id) { 3579 if (mManagedDialogs != null) { 3580 final ManagedDialog md = mManagedDialogs.get(id); 3581 if (md != null) { 3582 md.mDialog.dismiss(); 3583 mManagedDialogs.remove(id); 3584 } 3585 } 3586 } 3587 3588 /** 3589 * This hook is called when the user signals the desire to start a search. 3590 * 3591 * <p>You can use this function as a simple way to launch the search UI, in response to a 3592 * menu item, search button, or other widgets within your activity. Unless overidden, 3593 * calling this function is the same as calling 3594 * {@link #startSearch startSearch(null, false, null, false)}, which launches 3595 * search for the current activity as specified in its manifest, see {@link SearchManager}. 3596 * 3597 * <p>You can override this function to force global search, e.g. in response to a dedicated 3598 * search key, or to block search entirely (by simply returning false). 3599 * 3600 * <p>Note: when running in a {@link Configuration#UI_MODE_TYPE_TELEVISION}, the default 3601 * implementation changes to simply return false and you must supply your own custom 3602 * implementation if you want to support search.</p> 3603 * 3604 * @param searchEvent The {@link SearchEvent} that signaled this search. 3605 * @return Returns {@code true} if search launched, and {@code false} if the activity does 3606 * not respond to search. The default implementation always returns {@code true}, except 3607 * when in {@link Configuration#UI_MODE_TYPE_TELEVISION} mode where it returns false. 3608 * 3609 * @see android.app.SearchManager 3610 */ 3611 public boolean onSearchRequested(@Nullable SearchEvent searchEvent) { 3612 mSearchEvent = searchEvent; 3613 boolean result = onSearchRequested(); 3614 mSearchEvent = null; 3615 return result; 3616 } 3617 3618 /** 3619 * @see #onSearchRequested(SearchEvent) 3620 */ 3621 public boolean onSearchRequested() { 3622 if ((getResources().getConfiguration().uiMode&Configuration.UI_MODE_TYPE_MASK) 3623 != Configuration.UI_MODE_TYPE_TELEVISION) { 3624 startSearch(null, false, null, false); 3625 return true; 3626 } else { 3627 return false; 3628 } 3629 } 3630 3631 /** 3632 * During the onSearchRequested() callbacks, this function will return the 3633 * {@link SearchEvent} that triggered the callback, if it exists. 3634 * 3635 * @return SearchEvent The SearchEvent that triggered the {@link 3636 * #onSearchRequested} callback. 3637 */ 3638 public final SearchEvent getSearchEvent() { 3639 return mSearchEvent; 3640 } 3641 3642 /** 3643 * This hook is called to launch the search UI. 3644 * 3645 * <p>It is typically called from onSearchRequested(), either directly from 3646 * Activity.onSearchRequested() or from an overridden version in any given 3647 * Activity. If your goal is simply to activate search, it is preferred to call 3648 * onSearchRequested(), which may have been overridden elsewhere in your Activity. If your goal 3649 * is to inject specific data such as context data, it is preferred to <i>override</i> 3650 * onSearchRequested(), so that any callers to it will benefit from the override. 3651 * 3652 * @param initialQuery Any non-null non-empty string will be inserted as 3653 * pre-entered text in the search query box. 3654 * @param selectInitialQuery If true, the initial query will be preselected, which means that 3655 * any further typing will replace it. This is useful for cases where an entire pre-formed 3656 * query is being inserted. If false, the selection point will be placed at the end of the 3657 * inserted query. This is useful when the inserted query is text that the user entered, 3658 * and the user would expect to be able to keep typing. <i>This parameter is only meaningful 3659 * if initialQuery is a non-empty string.</i> 3660 * @param appSearchData An application can insert application-specific 3661 * context here, in order to improve quality or specificity of its own 3662 * searches. This data will be returned with SEARCH intent(s). Null if 3663 * no extra data is required. 3664 * @param globalSearch If false, this will only launch the search that has been specifically 3665 * defined by the application (which is usually defined as a local search). If no default 3666 * search is defined in the current application or activity, global search will be launched. 3667 * If true, this will always launch a platform-global (e.g. web-based) search instead. 3668 * 3669 * @see android.app.SearchManager 3670 * @see #onSearchRequested 3671 */ 3672 public void startSearch(@Nullable String initialQuery, boolean selectInitialQuery, 3673 @Nullable Bundle appSearchData, boolean globalSearch) { 3674 ensureSearchManager(); 3675 mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(), 3676 appSearchData, globalSearch); 3677 } 3678 3679 /** 3680 * Similar to {@link #startSearch}, but actually fires off the search query after invoking 3681 * the search dialog. Made available for testing purposes. 3682 * 3683 * @param query The query to trigger. If empty, the request will be ignored. 3684 * @param appSearchData An application can insert application-specific 3685 * context here, in order to improve quality or specificity of its own 3686 * searches. This data will be returned with SEARCH intent(s). Null if 3687 * no extra data is required. 3688 */ 3689 public void triggerSearch(String query, @Nullable Bundle appSearchData) { 3690 ensureSearchManager(); 3691 mSearchManager.triggerSearch(query, getComponentName(), appSearchData); 3692 } 3693 3694 /** 3695 * Request that key events come to this activity. Use this if your 3696 * activity has no views with focus, but the activity still wants 3697 * a chance to process key events. 3698 * 3699 * @see android.view.Window#takeKeyEvents 3700 */ 3701 public void takeKeyEvents(boolean get) { 3702 getWindow().takeKeyEvents(get); 3703 } 3704 3705 /** 3706 * Enable extended window features. This is a convenience for calling 3707 * {@link android.view.Window#requestFeature getWindow().requestFeature()}. 3708 * 3709 * @param featureId The desired feature as defined in 3710 * {@link android.view.Window}. 3711 * @return Returns true if the requested feature is supported and now 3712 * enabled. 3713 * 3714 * @see android.view.Window#requestFeature 3715 */ 3716 public final boolean requestWindowFeature(int featureId) { 3717 return getWindow().requestFeature(featureId); 3718 } 3719 3720 /** 3721 * Convenience for calling 3722 * {@link android.view.Window#setFeatureDrawableResource}. 3723 */ 3724 public final void setFeatureDrawableResource(int featureId, @DrawableRes int resId) { 3725 getWindow().setFeatureDrawableResource(featureId, resId); 3726 } 3727 3728 /** 3729 * Convenience for calling 3730 * {@link android.view.Window#setFeatureDrawableUri}. 3731 */ 3732 public final void setFeatureDrawableUri(int featureId, Uri uri) { 3733 getWindow().setFeatureDrawableUri(featureId, uri); 3734 } 3735 3736 /** 3737 * Convenience for calling 3738 * {@link android.view.Window#setFeatureDrawable(int, Drawable)}. 3739 */ 3740 public final void setFeatureDrawable(int featureId, Drawable drawable) { 3741 getWindow().setFeatureDrawable(featureId, drawable); 3742 } 3743 3744 /** 3745 * Convenience for calling 3746 * {@link android.view.Window#setFeatureDrawableAlpha}. 3747 */ 3748 public final void setFeatureDrawableAlpha(int featureId, int alpha) { 3749 getWindow().setFeatureDrawableAlpha(featureId, alpha); 3750 } 3751 3752 /** 3753 * Convenience for calling 3754 * {@link android.view.Window#getLayoutInflater}. 3755 */ 3756 @NonNull 3757 public LayoutInflater getLayoutInflater() { 3758 return getWindow().getLayoutInflater(); 3759 } 3760 3761 /** 3762 * Returns a {@link MenuInflater} with this context. 3763 */ 3764 @NonNull 3765 public MenuInflater getMenuInflater() { 3766 // Make sure that action views can get an appropriate theme. 3767 if (mMenuInflater == null) { 3768 initWindowDecorActionBar(); 3769 if (mActionBar != null) { 3770 mMenuInflater = new MenuInflater(mActionBar.getThemedContext(), this); 3771 } else { 3772 mMenuInflater = new MenuInflater(this); 3773 } 3774 } 3775 return mMenuInflater; 3776 } 3777 3778 @Override 3779 protected void onApplyThemeResource(Resources.Theme theme, @StyleRes int resid, 3780 boolean first) { 3781 if (mParent == null) { 3782 super.onApplyThemeResource(theme, resid, first); 3783 } else { 3784 try { 3785 theme.setTo(mParent.getTheme()); 3786 } catch (Exception e) { 3787 // Empty 3788 } 3789 theme.applyStyle(resid, false); 3790 } 3791 3792 // Get the primary color and update the TaskDescription for this activity 3793 if (theme != null) { 3794 TypedArray a = theme.obtainStyledAttributes(com.android.internal.R.styleable.Theme); 3795 int colorPrimary = a.getColor(com.android.internal.R.styleable.Theme_colorPrimary, 0); 3796 a.recycle(); 3797 if (colorPrimary != 0) { 3798 ActivityManager.TaskDescription v = new ActivityManager.TaskDescription(null, null, 3799 colorPrimary); 3800 setTaskDescription(v); 3801 } 3802 } 3803 } 3804 3805 /** 3806 * Requests permissions to be granted to this application. These permissions 3807 * must be requested in your manifest, they should not be granted to your app, 3808 * and they should have protection level {@link android.content.pm.PermissionInfo 3809 * #PROTECTION_DANGEROUS dangerous}, regardless whether they are declared by 3810 * the platform or a third-party app. 3811 * <p> 3812 * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL} 3813 * are granted at install time if requested in the manifest. Signature permissions 3814 * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at 3815 * install time if requested in the manifest and the signature of your app matches 3816 * the signature of the app declaring the permissions. 3817 * </p> 3818 * <p> 3819 * If your app does not have the requested permissions the user will be presented 3820 * with UI for accepting them. After the user has accepted or rejected the 3821 * requested permissions you will receive a callback on {@link 3822 * #onRequestPermissionsResult(int, String[], int[])} reporting whether the 3823 * permissions were granted or not. 3824 * </p> 3825 * <p> 3826 * Note that requesting a permission does not guarantee it will be granted and 3827 * your app should be able to run without having this permission. 3828 * </p> 3829 * <p> 3830 * This method may start an activity allowing the user to choose which permissions 3831 * to grant and which to reject. Hence, you should be prepared that your activity 3832 * may be paused and resumed. Further, granting some permissions may require 3833 * a restart of you application. In such a case, the system will recreate the 3834 * activity stack before delivering the result to {@link 3835 * #onRequestPermissionsResult(int, String[], int[])}. 3836 * </p> 3837 * <p> 3838 * When checking whether you have a permission you should use {@link 3839 * #checkSelfPermission(String)}. 3840 * </p> 3841 * <p> 3842 * Calling this API for permissions already granted to your app would show UI 3843 * to the user to decide whether the app can still hold these permissions. This 3844 * can be useful if the way your app uses data guarded by the permissions 3845 * changes significantly. 3846 * </p> 3847 * <p> 3848 * You cannot request a permission if your activity sets {@link 3849 * android.R.styleable#AndroidManifestActivity_noHistory noHistory} to 3850 * <code>true</code> because in this case the activity would not receive 3851 * result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}. 3852 * </p> 3853 * <p> 3854 * A sample permissions request looks like this: 3855 * </p> 3856 * <code><pre><p> 3857 * private void showContacts() { 3858 * if (checkSelfPermission(Manifest.permission.READ_CONTACTS) 3859 * != PackageManager.PERMISSION_GRANTED) { 3860 * requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, 3861 * PERMISSIONS_REQUEST_READ_CONTACTS); 3862 * } else { 3863 * doShowContacts(); 3864 * } 3865 * } 3866 * 3867 * {@literal @}Override 3868 * public void onRequestPermissionsResult(int requestCode, String[] permissions, 3869 * int[] grantResults) { 3870 * if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS 3871 * && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 3872 * showContacts(); 3873 * } 3874 * } 3875 * </code></pre></p> 3876 * 3877 * @param permissions The requested permissions. 3878 * @param requestCode Application specific request code to match with a result 3879 * reported to {@link #onRequestPermissionsResult(int, String[], int[])}. 3880 * Should be >= 0. 3881 * 3882 * @see #onRequestPermissionsResult(int, String[], int[]) 3883 * @see #checkSelfPermission(String) 3884 * @see #shouldShowRequestPermissionRationale(String) 3885 */ 3886 public final void requestPermissions(@NonNull String[] permissions, int requestCode) { 3887 Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions); 3888 startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null); 3889 } 3890 3891 /** 3892 * Callback for the result from requesting permissions. This method 3893 * is invoked for every call on {@link #requestPermissions(String[], int)}. 3894 * <p> 3895 * <strong>Note:</strong> It is possible that the permissions request interaction 3896 * with the user is interrupted. In this case you will receive empty permissions 3897 * and results arrays which should be treated as a cancellation. 3898 * </p> 3899 * 3900 * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}. 3901 * @param permissions The requested permissions. Never null. 3902 * @param grantResults The grant results for the corresponding permissions 3903 * which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED} 3904 * or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null. 3905 * 3906 * @see #requestPermissions(String[], int) 3907 */ 3908 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 3909 @NonNull int[] grantResults) { 3910 /* callback - no nothing */ 3911 } 3912 3913 /** 3914 * Gets whether you should show UI with rationale for requesting a permission. 3915 * You should do this only if you do not have the permission and the context in 3916 * which the permission is requested does not clearly communicate to the user 3917 * what would be the benefit from granting this permission. 3918 * <p> 3919 * For example, if you write a camera app, requesting the camera permission 3920 * would be expected by the user and no rationale for why it is requested is 3921 * needed. If however, the app needs location for tagging photos then a non-tech 3922 * savvy user may wonder how location is related to taking photos. In this case 3923 * you may choose to show UI with rationale of requesting this permission. 3924 * </p> 3925 * 3926 * @param permission A permission your app wants to request. 3927 * @return Whether you can show permission rationale UI. 3928 * 3929 * @see #checkSelfPermission(String) 3930 * @see #requestPermissions(String[], int) 3931 * @see #onRequestPermissionsResult(int, String[], int[]) 3932 */ 3933 public boolean shouldShowRequestPermissionRationale(@NonNull String permission) { 3934 return getPackageManager().shouldShowRequestPermissionRationale(permission); 3935 } 3936 3937 /** 3938 * Same as calling {@link #startActivityForResult(Intent, int, Bundle)} 3939 * with no options. 3940 * 3941 * @param intent The intent to start. 3942 * @param requestCode If >= 0, this code will be returned in 3943 * onActivityResult() when the activity exits. 3944 * 3945 * @throws android.content.ActivityNotFoundException 3946 * 3947 * @see #startActivity 3948 */ 3949 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) { 3950 startActivityForResult(intent, requestCode, null); 3951 } 3952 3953 /** 3954 * Launch an activity for which you would like a result when it finished. 3955 * When this activity exits, your 3956 * onActivityResult() method will be called with the given requestCode. 3957 * Using a negative requestCode is the same as calling 3958 * {@link #startActivity} (the activity is not launched as a sub-activity). 3959 * 3960 * <p>Note that this method should only be used with Intent protocols 3961 * that are defined to return a result. In other protocols (such as 3962 * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may 3963 * not get the result when you expect. For example, if the activity you 3964 * are launching uses the singleTask launch mode, it will not run in your 3965 * task and thus you will immediately receive a cancel result. 3966 * 3967 * <p>As a special case, if you call startActivityForResult() with a requestCode 3968 * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your 3969 * activity, then your window will not be displayed until a result is 3970 * returned back from the started activity. This is to avoid visible 3971 * flickering when redirecting to another activity. 3972 * 3973 * <p>This method throws {@link android.content.ActivityNotFoundException} 3974 * if there was no Activity found to run the given Intent. 3975 * 3976 * @param intent The intent to start. 3977 * @param requestCode If >= 0, this code will be returned in 3978 * onActivityResult() when the activity exits. 3979 * @param options Additional options for how the Activity should be started. 3980 * See {@link android.content.Context#startActivity(Intent, Bundle) 3981 * Context.startActivity(Intent, Bundle)} for more details. 3982 * 3983 * @throws android.content.ActivityNotFoundException 3984 * 3985 * @see #startActivity 3986 */ 3987 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, 3988 @Nullable Bundle options) { 3989 if (mParent == null) { 3990 Instrumentation.ActivityResult ar = 3991 mInstrumentation.execStartActivity( 3992 this, mMainThread.getApplicationThread(), mToken, this, 3993 intent, requestCode, options); 3994 if (ar != null) { 3995 mMainThread.sendActivityResult( 3996 mToken, mEmbeddedID, requestCode, ar.getResultCode(), 3997 ar.getResultData()); 3998 } 3999 if (requestCode >= 0) { 4000 // If this start is requesting a result, we can avoid making 4001 // the activity visible until the result is received. Setting 4002 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 4003 // activity hidden during this time, to avoid flickering. 4004 // This can only be done when a result is requested because 4005 // that guarantees we will get information back when the 4006 // activity is finished, no matter what happens to it. 4007 mStartedActivity = true; 4008 } 4009 4010 cancelInputsAndStartExitTransition(options); 4011 // TODO Consider clearing/flushing other event sources and events for child windows. 4012 } else { 4013 if (options != null) { 4014 mParent.startActivityFromChild(this, intent, requestCode, options); 4015 } else { 4016 // Note we want to go through this method for compatibility with 4017 // existing applications that may have overridden it. 4018 mParent.startActivityFromChild(this, intent, requestCode); 4019 } 4020 } 4021 } 4022 4023 /** 4024 * Cancels pending inputs and if an Activity Transition is to be run, starts the transition. 4025 * 4026 * @param options The ActivityOptions bundle used to start an Activity. 4027 */ 4028 private void cancelInputsAndStartExitTransition(Bundle options) { 4029 final View decor = mWindow != null ? mWindow.peekDecorView() : null; 4030 if (decor != null) { 4031 decor.cancelPendingInputEvents(); 4032 } 4033 if (options != null && !isTopOfTask()) { 4034 mActivityTransitionState.startExitOutTransition(this, options); 4035 } 4036 } 4037 4038 /** 4039 * @hide Implement to provide correct calling token. 4040 */ 4041 public void startActivityForResultAsUser(Intent intent, int requestCode, UserHandle user) { 4042 startActivityForResultAsUser(intent, requestCode, null, user); 4043 } 4044 4045 /** 4046 * @hide Implement to provide correct calling token. 4047 */ 4048 public void startActivityForResultAsUser(Intent intent, int requestCode, 4049 @Nullable Bundle options, UserHandle user) { 4050 if (mParent != null) { 4051 throw new RuntimeException("Can't be called from a child"); 4052 } 4053 Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( 4054 this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, 4055 options, user); 4056 if (ar != null) { 4057 mMainThread.sendActivityResult( 4058 mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); 4059 } 4060 if (requestCode >= 0) { 4061 // If this start is requesting a result, we can avoid making 4062 // the activity visible until the result is received. Setting 4063 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 4064 // activity hidden during this time, to avoid flickering. 4065 // This can only be done when a result is requested because 4066 // that guarantees we will get information back when the 4067 // activity is finished, no matter what happens to it. 4068 mStartedActivity = true; 4069 } 4070 4071 cancelInputsAndStartExitTransition(options); 4072 } 4073 4074 /** 4075 * @hide Implement to provide correct calling token. 4076 */ 4077 public void startActivityAsUser(Intent intent, UserHandle user) { 4078 startActivityAsUser(intent, null, user); 4079 } 4080 4081 /** 4082 * @hide Implement to provide correct calling token. 4083 */ 4084 public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) { 4085 if (mParent != null) { 4086 throw new RuntimeException("Can't be called from a child"); 4087 } 4088 Instrumentation.ActivityResult ar = 4089 mInstrumentation.execStartActivity( 4090 this, mMainThread.getApplicationThread(), mToken, this, 4091 intent, -1, options, user); 4092 if (ar != null) { 4093 mMainThread.sendActivityResult( 4094 mToken, mEmbeddedID, -1, ar.getResultCode(), 4095 ar.getResultData()); 4096 } 4097 cancelInputsAndStartExitTransition(options); 4098 } 4099 4100 /** 4101 * Start a new activity as if it was started by the activity that started our 4102 * current activity. This is for the resolver and chooser activities, which operate 4103 * as intermediaries that dispatch their intent to the target the user selects -- to 4104 * do this, they must perform all security checks including permission grants as if 4105 * their launch had come from the original activity. 4106 * @param intent The Intent to start. 4107 * @param options ActivityOptions or null. 4108 * @param ignoreTargetSecurity If true, the activity manager will not check whether the 4109 * caller it is doing the start is, is actually allowed to start the target activity. 4110 * If you set this to true, you must set an explicit component in the Intent and do any 4111 * appropriate security checks yourself. 4112 * @param userId The user the new activity should run as. 4113 * @hide 4114 */ 4115 public void startActivityAsCaller(Intent intent, @Nullable Bundle options, 4116 boolean ignoreTargetSecurity, int userId) { 4117 if (mParent != null) { 4118 throw new RuntimeException("Can't be called from a child"); 4119 } 4120 Instrumentation.ActivityResult ar = 4121 mInstrumentation.execStartActivityAsCaller( 4122 this, mMainThread.getApplicationThread(), mToken, this, 4123 intent, -1, options, ignoreTargetSecurity, userId); 4124 if (ar != null) { 4125 mMainThread.sendActivityResult( 4126 mToken, mEmbeddedID, -1, ar.getResultCode(), 4127 ar.getResultData()); 4128 } 4129 cancelInputsAndStartExitTransition(options); 4130 } 4131 4132 /** 4133 * Same as calling {@link #startIntentSenderForResult(IntentSender, int, 4134 * Intent, int, int, int, Bundle)} with no options. 4135 * 4136 * @param intent The IntentSender to launch. 4137 * @param requestCode If >= 0, this code will be returned in 4138 * onActivityResult() when the activity exits. 4139 * @param fillInIntent If non-null, this will be provided as the 4140 * intent parameter to {@link IntentSender#sendIntent}. 4141 * @param flagsMask Intent flags in the original IntentSender that you 4142 * would like to change. 4143 * @param flagsValues Desired values for any bits set in 4144 * <var>flagsMask</var> 4145 * @param extraFlags Always set to 0. 4146 */ 4147 public void startIntentSenderForResult(IntentSender intent, int requestCode, 4148 @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 4149 throws IntentSender.SendIntentException { 4150 startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask, 4151 flagsValues, extraFlags, null); 4152 } 4153 4154 /** 4155 * Like {@link #startActivityForResult(Intent, int)}, but allowing you 4156 * to use a IntentSender to describe the activity to be started. If 4157 * the IntentSender is for an activity, that activity will be started 4158 * as if you had called the regular {@link #startActivityForResult(Intent, int)} 4159 * here; otherwise, its associated action will be executed (such as 4160 * sending a broadcast) as if you had called 4161 * {@link IntentSender#sendIntent IntentSender.sendIntent} on it. 4162 * 4163 * @param intent The IntentSender to launch. 4164 * @param requestCode If >= 0, this code will be returned in 4165 * onActivityResult() when the activity exits. 4166 * @param fillInIntent If non-null, this will be provided as the 4167 * intent parameter to {@link IntentSender#sendIntent}. 4168 * @param flagsMask Intent flags in the original IntentSender that you 4169 * would like to change. 4170 * @param flagsValues Desired values for any bits set in 4171 * <var>flagsMask</var> 4172 * @param extraFlags Always set to 0. 4173 * @param options Additional options for how the Activity should be started. 4174 * See {@link android.content.Context#startActivity(Intent, Bundle) 4175 * Context.startActivity(Intent, Bundle)} for more details. If options 4176 * have also been supplied by the IntentSender, options given here will 4177 * override any that conflict with those given by the IntentSender. 4178 */ 4179 public void startIntentSenderForResult(IntentSender intent, int requestCode, 4180 @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, 4181 Bundle options) throws IntentSender.SendIntentException { 4182 if (mParent == null) { 4183 startIntentSenderForResultInner(intent, requestCode, fillInIntent, 4184 flagsMask, flagsValues, this, options); 4185 } else if (options != null) { 4186 mParent.startIntentSenderFromChild(this, intent, requestCode, 4187 fillInIntent, flagsMask, flagsValues, extraFlags, options); 4188 } else { 4189 // Note we want to go through this call for compatibility with 4190 // existing applications that may have overridden the method. 4191 mParent.startIntentSenderFromChild(this, intent, requestCode, 4192 fillInIntent, flagsMask, flagsValues, extraFlags); 4193 } 4194 } 4195 4196 private void startIntentSenderForResultInner(IntentSender intent, int requestCode, 4197 Intent fillInIntent, int flagsMask, int flagsValues, Activity activity, 4198 Bundle options) 4199 throws IntentSender.SendIntentException { 4200 try { 4201 String resolvedType = null; 4202 if (fillInIntent != null) { 4203 fillInIntent.migrateExtraStreamToClipData(); 4204 fillInIntent.prepareToLeaveProcess(); 4205 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); 4206 } 4207 int result = ActivityManagerNative.getDefault() 4208 .startActivityIntentSender(mMainThread.getApplicationThread(), intent, 4209 fillInIntent, resolvedType, mToken, activity.mEmbeddedID, 4210 requestCode, flagsMask, flagsValues, options); 4211 if (result == ActivityManager.START_CANCELED) { 4212 throw new IntentSender.SendIntentException(); 4213 } 4214 Instrumentation.checkStartActivityResult(result, null); 4215 } catch (RemoteException e) { 4216 } 4217 if (requestCode >= 0) { 4218 // If this start is requesting a result, we can avoid making 4219 // the activity visible until the result is received. Setting 4220 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 4221 // activity hidden during this time, to avoid flickering. 4222 // This can only be done when a result is requested because 4223 // that guarantees we will get information back when the 4224 // activity is finished, no matter what happens to it. 4225 mStartedActivity = true; 4226 } 4227 } 4228 4229 /** 4230 * Same as {@link #startActivity(Intent, Bundle)} with no options 4231 * specified. 4232 * 4233 * @param intent The intent to start. 4234 * 4235 * @throws android.content.ActivityNotFoundException 4236 * 4237 * @see {@link #startActivity(Intent, Bundle)} 4238 * @see #startActivityForResult 4239 */ 4240 @Override 4241 public void startActivity(Intent intent) { 4242 this.startActivity(intent, null); 4243 } 4244 4245 /** 4246 * Launch a new activity. You will not receive any information about when 4247 * the activity exits. This implementation overrides the base version, 4248 * providing information about 4249 * the activity performing the launch. Because of this additional 4250 * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not 4251 * required; if not specified, the new activity will be added to the 4252 * task of the caller. 4253 * 4254 * <p>This method throws {@link android.content.ActivityNotFoundException} 4255 * if there was no Activity found to run the given Intent. 4256 * 4257 * @param intent The intent to start. 4258 * @param options Additional options for how the Activity should be started. 4259 * See {@link android.content.Context#startActivity(Intent, Bundle) 4260 * Context.startActivity(Intent, Bundle)} for more details. 4261 * 4262 * @throws android.content.ActivityNotFoundException 4263 * 4264 * @see {@link #startActivity(Intent)} 4265 * @see #startActivityForResult 4266 */ 4267 @Override 4268 public void startActivity(Intent intent, @Nullable Bundle options) { 4269 if (options != null) { 4270 startActivityForResult(intent, -1, options); 4271 } else { 4272 // Note we want to go through this call for compatibility with 4273 // applications that may have overridden the method. 4274 startActivityForResult(intent, -1); 4275 } 4276 } 4277 4278 /** 4279 * Same as {@link #startActivities(Intent[], Bundle)} with no options 4280 * specified. 4281 * 4282 * @param intents The intents to start. 4283 * 4284 * @throws android.content.ActivityNotFoundException 4285 * 4286 * @see {@link #startActivities(Intent[], Bundle)} 4287 * @see #startActivityForResult 4288 */ 4289 @Override 4290 public void startActivities(Intent[] intents) { 4291 startActivities(intents, null); 4292 } 4293 4294 /** 4295 * Launch a new activity. You will not receive any information about when 4296 * the activity exits. This implementation overrides the base version, 4297 * providing information about 4298 * the activity performing the launch. Because of this additional 4299 * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not 4300 * required; if not specified, the new activity will be added to the 4301 * task of the caller. 4302 * 4303 * <p>This method throws {@link android.content.ActivityNotFoundException} 4304 * if there was no Activity found to run the given Intent. 4305 * 4306 * @param intents The intents to start. 4307 * @param options Additional options for how the Activity should be started. 4308 * See {@link android.content.Context#startActivity(Intent, Bundle) 4309 * Context.startActivity(Intent, Bundle)} for more details. 4310 * 4311 * @throws android.content.ActivityNotFoundException 4312 * 4313 * @see {@link #startActivities(Intent[])} 4314 * @see #startActivityForResult 4315 */ 4316 @Override 4317 public void startActivities(Intent[] intents, @Nullable Bundle options) { 4318 mInstrumentation.execStartActivities(this, mMainThread.getApplicationThread(), 4319 mToken, this, intents, options); 4320 } 4321 4322 /** 4323 * Same as calling {@link #startIntentSender(IntentSender, Intent, int, int, int, Bundle)} 4324 * with no options. 4325 * 4326 * @param intent The IntentSender to launch. 4327 * @param fillInIntent If non-null, this will be provided as the 4328 * intent parameter to {@link IntentSender#sendIntent}. 4329 * @param flagsMask Intent flags in the original IntentSender that you 4330 * would like to change. 4331 * @param flagsValues Desired values for any bits set in 4332 * <var>flagsMask</var> 4333 * @param extraFlags Always set to 0. 4334 */ 4335 public void startIntentSender(IntentSender intent, 4336 @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 4337 throws IntentSender.SendIntentException { 4338 startIntentSender(intent, fillInIntent, flagsMask, flagsValues, 4339 extraFlags, null); 4340 } 4341 4342 /** 4343 * Like {@link #startActivity(Intent, Bundle)}, but taking a IntentSender 4344 * to start; see 4345 * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int, Bundle)} 4346 * for more information. 4347 * 4348 * @param intent The IntentSender to launch. 4349 * @param fillInIntent If non-null, this will be provided as the 4350 * intent parameter to {@link IntentSender#sendIntent}. 4351 * @param flagsMask Intent flags in the original IntentSender that you 4352 * would like to change. 4353 * @param flagsValues Desired values for any bits set in 4354 * <var>flagsMask</var> 4355 * @param extraFlags Always set to 0. 4356 * @param options Additional options for how the Activity should be started. 4357 * See {@link android.content.Context#startActivity(Intent, Bundle) 4358 * Context.startActivity(Intent, Bundle)} for more details. If options 4359 * have also been supplied by the IntentSender, options given here will 4360 * override any that conflict with those given by the IntentSender. 4361 */ 4362 public void startIntentSender(IntentSender intent, 4363 @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, 4364 Bundle options) throws IntentSender.SendIntentException { 4365 if (options != null) { 4366 startIntentSenderForResult(intent, -1, fillInIntent, flagsMask, 4367 flagsValues, extraFlags, options); 4368 } else { 4369 // Note we want to go through this call for compatibility with 4370 // applications that may have overridden the method. 4371 startIntentSenderForResult(intent, -1, fillInIntent, flagsMask, 4372 flagsValues, extraFlags); 4373 } 4374 } 4375 4376 /** 4377 * Same as calling {@link #startActivityIfNeeded(Intent, int, Bundle)} 4378 * with no options. 4379 * 4380 * @param intent The intent to start. 4381 * @param requestCode If >= 0, this code will be returned in 4382 * onActivityResult() when the activity exits, as described in 4383 * {@link #startActivityForResult}. 4384 * 4385 * @return If a new activity was launched then true is returned; otherwise 4386 * false is returned and you must handle the Intent yourself. 4387 * 4388 * @see #startActivity 4389 * @see #startActivityForResult 4390 */ 4391 public boolean startActivityIfNeeded(@RequiresPermission @NonNull Intent intent, 4392 int requestCode) { 4393 return startActivityIfNeeded(intent, requestCode, null); 4394 } 4395 4396 /** 4397 * A special variation to launch an activity only if a new activity 4398 * instance is needed to handle the given Intent. In other words, this is 4399 * just like {@link #startActivityForResult(Intent, int)} except: if you are 4400 * using the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag, or 4401 * singleTask or singleTop 4402 * {@link android.R.styleable#AndroidManifestActivity_launchMode launchMode}, 4403 * and the activity 4404 * that handles <var>intent</var> is the same as your currently running 4405 * activity, then a new instance is not needed. In this case, instead of 4406 * the normal behavior of calling {@link #onNewIntent} this function will 4407 * return and you can handle the Intent yourself. 4408 * 4409 * <p>This function can only be called from a top-level activity; if it is 4410 * called from a child activity, a runtime exception will be thrown. 4411 * 4412 * @param intent The intent to start. 4413 * @param requestCode If >= 0, this code will be returned in 4414 * onActivityResult() when the activity exits, as described in 4415 * {@link #startActivityForResult}. 4416 * @param options Additional options for how the Activity should be started. 4417 * See {@link android.content.Context#startActivity(Intent, Bundle) 4418 * Context.startActivity(Intent, Bundle)} for more details. 4419 * 4420 * @return If a new activity was launched then true is returned; otherwise 4421 * false is returned and you must handle the Intent yourself. 4422 * 4423 * @see #startActivity 4424 * @see #startActivityForResult 4425 */ 4426 public boolean startActivityIfNeeded(@RequiresPermission @NonNull Intent intent, 4427 int requestCode, @Nullable Bundle options) { 4428 if (mParent == null) { 4429 int result = ActivityManager.START_RETURN_INTENT_TO_CALLER; 4430 try { 4431 Uri referrer = onProvideReferrer(); 4432 if (referrer != null) { 4433 intent.putExtra(Intent.EXTRA_REFERRER, referrer); 4434 } 4435 intent.migrateExtraStreamToClipData(); 4436 intent.prepareToLeaveProcess(); 4437 result = ActivityManagerNative.getDefault() 4438 .startActivity(mMainThread.getApplicationThread(), getBasePackageName(), 4439 intent, intent.resolveTypeIfNeeded(getContentResolver()), mToken, 4440 mEmbeddedID, requestCode, ActivityManager.START_FLAG_ONLY_IF_NEEDED, 4441 null, options); 4442 } catch (RemoteException e) { 4443 // Empty 4444 } 4445 4446 Instrumentation.checkStartActivityResult(result, intent); 4447 4448 if (requestCode >= 0) { 4449 // If this start is requesting a result, we can avoid making 4450 // the activity visible until the result is received. Setting 4451 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 4452 // activity hidden during this time, to avoid flickering. 4453 // This can only be done when a result is requested because 4454 // that guarantees we will get information back when the 4455 // activity is finished, no matter what happens to it. 4456 mStartedActivity = true; 4457 } 4458 return result != ActivityManager.START_RETURN_INTENT_TO_CALLER; 4459 } 4460 4461 throw new UnsupportedOperationException( 4462 "startActivityIfNeeded can only be called from a top-level activity"); 4463 } 4464 4465 /** 4466 * Same as calling {@link #startNextMatchingActivity(Intent, Bundle)} with 4467 * no options. 4468 * 4469 * @param intent The intent to dispatch to the next activity. For 4470 * correct behavior, this must be the same as the Intent that started 4471 * your own activity; the only changes you can make are to the extras 4472 * inside of it. 4473 * 4474 * @return Returns a boolean indicating whether there was another Activity 4475 * to start: true if there was a next activity to start, false if there 4476 * wasn't. In general, if true is returned you will then want to call 4477 * finish() on yourself. 4478 */ 4479 public boolean startNextMatchingActivity(@RequiresPermission @NonNull Intent intent) { 4480 return startNextMatchingActivity(intent, null); 4481 } 4482 4483 /** 4484 * Special version of starting an activity, for use when you are replacing 4485 * other activity components. You can use this to hand the Intent off 4486 * to the next Activity that can handle it. You typically call this in 4487 * {@link #onCreate} with the Intent returned by {@link #getIntent}. 4488 * 4489 * @param intent The intent to dispatch to the next activity. For 4490 * correct behavior, this must be the same as the Intent that started 4491 * your own activity; the only changes you can make are to the extras 4492 * inside of it. 4493 * @param options Additional options for how the Activity should be started. 4494 * See {@link android.content.Context#startActivity(Intent, Bundle) 4495 * Context.startActivity(Intent, Bundle)} for more details. 4496 * 4497 * @return Returns a boolean indicating whether there was another Activity 4498 * to start: true if there was a next activity to start, false if there 4499 * wasn't. In general, if true is returned you will then want to call 4500 * finish() on yourself. 4501 */ 4502 public boolean startNextMatchingActivity(@RequiresPermission @NonNull Intent intent, 4503 @Nullable Bundle options) { 4504 if (mParent == null) { 4505 try { 4506 intent.migrateExtraStreamToClipData(); 4507 intent.prepareToLeaveProcess(); 4508 return ActivityManagerNative.getDefault() 4509 .startNextMatchingActivity(mToken, intent, options); 4510 } catch (RemoteException e) { 4511 // Empty 4512 } 4513 return false; 4514 } 4515 4516 throw new UnsupportedOperationException( 4517 "startNextMatchingActivity can only be called from a top-level activity"); 4518 } 4519 4520 /** 4521 * Same as calling {@link #startActivityFromChild(Activity, Intent, int, Bundle)} 4522 * with no options. 4523 * 4524 * @param child The activity making the call. 4525 * @param intent The intent to start. 4526 * @param requestCode Reply request code. < 0 if reply is not requested. 4527 * 4528 * @throws android.content.ActivityNotFoundException 4529 * 4530 * @see #startActivity 4531 * @see #startActivityForResult 4532 */ 4533 public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent, 4534 int requestCode) { 4535 startActivityFromChild(child, intent, requestCode, null); 4536 } 4537 4538 /** 4539 * This is called when a child activity of this one calls its 4540 * {@link #startActivity} or {@link #startActivityForResult} method. 4541 * 4542 * <p>This method throws {@link android.content.ActivityNotFoundException} 4543 * if there was no Activity found to run the given Intent. 4544 * 4545 * @param child The activity making the call. 4546 * @param intent The intent to start. 4547 * @param requestCode Reply request code. < 0 if reply is not requested. 4548 * @param options Additional options for how the Activity should be started. 4549 * See {@link android.content.Context#startActivity(Intent, Bundle) 4550 * Context.startActivity(Intent, Bundle)} for more details. 4551 * 4552 * @throws android.content.ActivityNotFoundException 4553 * 4554 * @see #startActivity 4555 * @see #startActivityForResult 4556 */ 4557 public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent, 4558 int requestCode, @Nullable Bundle options) { 4559 Instrumentation.ActivityResult ar = 4560 mInstrumentation.execStartActivity( 4561 this, mMainThread.getApplicationThread(), mToken, child, 4562 intent, requestCode, options); 4563 if (ar != null) { 4564 mMainThread.sendActivityResult( 4565 mToken, child.mEmbeddedID, requestCode, 4566 ar.getResultCode(), ar.getResultData()); 4567 } 4568 cancelInputsAndStartExitTransition(options); 4569 } 4570 4571 /** 4572 * Same as calling {@link #startActivityFromFragment(Fragment, Intent, int, Bundle)} 4573 * with no options. 4574 * 4575 * @param fragment The fragment making the call. 4576 * @param intent The intent to start. 4577 * @param requestCode Reply request code. < 0 if reply is not requested. 4578 * 4579 * @throws android.content.ActivityNotFoundException 4580 * 4581 * @see Fragment#startActivity 4582 * @see Fragment#startActivityForResult 4583 */ 4584 public void startActivityFromFragment(@NonNull Fragment fragment, 4585 @RequiresPermission Intent intent, int requestCode) { 4586 startActivityFromFragment(fragment, intent, requestCode, null); 4587 } 4588 4589 /** 4590 * This is called when a Fragment in this activity calls its 4591 * {@link Fragment#startActivity} or {@link Fragment#startActivityForResult} 4592 * method. 4593 * 4594 * <p>This method throws {@link android.content.ActivityNotFoundException} 4595 * if there was no Activity found to run the given Intent. 4596 * 4597 * @param fragment The fragment making the call. 4598 * @param intent The intent to start. 4599 * @param requestCode Reply request code. < 0 if reply is not requested. 4600 * @param options Additional options for how the Activity should be started. 4601 * See {@link android.content.Context#startActivity(Intent, Bundle) 4602 * Context.startActivity(Intent, Bundle)} for more details. 4603 * 4604 * @throws android.content.ActivityNotFoundException 4605 * 4606 * @see Fragment#startActivity 4607 * @see Fragment#startActivityForResult 4608 */ 4609 public void startActivityFromFragment(@NonNull Fragment fragment, 4610 @RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { 4611 startActivityForResult(fragment.mWho, intent, requestCode, options); 4612 } 4613 4614 /** 4615 * @hide 4616 */ 4617 @Override 4618 public void startActivityForResult( 4619 String who, Intent intent, int requestCode, @Nullable Bundle options) { 4620 Uri referrer = onProvideReferrer(); 4621 if (referrer != null) { 4622 intent.putExtra(Intent.EXTRA_REFERRER, referrer); 4623 } 4624 Instrumentation.ActivityResult ar = 4625 mInstrumentation.execStartActivity( 4626 this, mMainThread.getApplicationThread(), mToken, who, 4627 intent, requestCode, options); 4628 if (ar != null) { 4629 mMainThread.sendActivityResult( 4630 mToken, who, requestCode, 4631 ar.getResultCode(), ar.getResultData()); 4632 } 4633 cancelInputsAndStartExitTransition(options); 4634 } 4635 4636 /** 4637 * @hide 4638 */ 4639 @Override 4640 public boolean canStartActivityForResult() { 4641 return true; 4642 } 4643 4644 /** 4645 * Same as calling {@link #startIntentSenderFromChild(Activity, IntentSender, 4646 * int, Intent, int, int, int, Bundle)} with no options. 4647 */ 4648 public void startIntentSenderFromChild(Activity child, IntentSender intent, 4649 int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, 4650 int extraFlags) 4651 throws IntentSender.SendIntentException { 4652 startIntentSenderFromChild(child, intent, requestCode, fillInIntent, 4653 flagsMask, flagsValues, extraFlags, null); 4654 } 4655 4656 /** 4657 * Like {@link #startActivityFromChild(Activity, Intent, int)}, but 4658 * taking a IntentSender; see 4659 * {@link #startIntentSenderForResult(IntentSender, int, Intent, int, int, int)} 4660 * for more information. 4661 */ 4662 public void startIntentSenderFromChild(Activity child, IntentSender intent, 4663 int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, 4664 int extraFlags, @Nullable Bundle options) 4665 throws IntentSender.SendIntentException { 4666 startIntentSenderForResultInner(intent, requestCode, fillInIntent, 4667 flagsMask, flagsValues, child, options); 4668 } 4669 4670 /** 4671 * Call immediately after one of the flavors of {@link #startActivity(Intent)} 4672 * or {@link #finish} to specify an explicit transition animation to 4673 * perform next. 4674 * 4675 * <p>As of {@link android.os.Build.VERSION_CODES#JELLY_BEAN} an alternative 4676 * to using this with starting activities is to supply the desired animation 4677 * information through a {@link ActivityOptions} bundle to 4678 * {@link #startActivity(Intent, Bundle) or a related function. This allows 4679 * you to specify a custom animation even when starting an activity from 4680 * outside the context of the current top activity. 4681 * 4682 * @param enterAnim A resource ID of the animation resource to use for 4683 * the incoming activity. Use 0 for no animation. 4684 * @param exitAnim A resource ID of the animation resource to use for 4685 * the outgoing activity. Use 0 for no animation. 4686 */ 4687 public void overridePendingTransition(int enterAnim, int exitAnim) { 4688 try { 4689 ActivityManagerNative.getDefault().overridePendingTransition( 4690 mToken, getPackageName(), enterAnim, exitAnim); 4691 } catch (RemoteException e) { 4692 } 4693 } 4694 4695 /** 4696 * Call this to set the result that your activity will return to its 4697 * caller. 4698 * 4699 * @param resultCode The result code to propagate back to the originating 4700 * activity, often RESULT_CANCELED or RESULT_OK 4701 * 4702 * @see #RESULT_CANCELED 4703 * @see #RESULT_OK 4704 * @see #RESULT_FIRST_USER 4705 * @see #setResult(int, Intent) 4706 */ 4707 public final void setResult(int resultCode) { 4708 synchronized (this) { 4709 mResultCode = resultCode; 4710 mResultData = null; 4711 } 4712 } 4713 4714 /** 4715 * Call this to set the result that your activity will return to its 4716 * caller. 4717 * 4718 * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, the Intent 4719 * you supply here can have {@link Intent#FLAG_GRANT_READ_URI_PERMISSION 4720 * Intent.FLAG_GRANT_READ_URI_PERMISSION} and/or {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION 4721 * Intent.FLAG_GRANT_WRITE_URI_PERMISSION} set. This will grant the 4722 * Activity receiving the result access to the specific URIs in the Intent. 4723 * Access will remain until the Activity has finished (it will remain across the hosting 4724 * process being killed and other temporary destruction) and will be added 4725 * to any existing set of URI permissions it already holds. 4726 * 4727 * @param resultCode The result code to propagate back to the originating 4728 * activity, often RESULT_CANCELED or RESULT_OK 4729 * @param data The data to propagate back to the originating activity. 4730 * 4731 * @see #RESULT_CANCELED 4732 * @see #RESULT_OK 4733 * @see #RESULT_FIRST_USER 4734 * @see #setResult(int) 4735 */ 4736 public final void setResult(int resultCode, Intent data) { 4737 synchronized (this) { 4738 mResultCode = resultCode; 4739 mResultData = data; 4740 } 4741 } 4742 4743 /** 4744 * Return information about who launched this activity. If the launching Intent 4745 * contains an {@link android.content.Intent#EXTRA_REFERRER Intent.EXTRA_REFERRER}, 4746 * that will be returned as-is; otherwise, if known, an 4747 * {@link Intent#URI_ANDROID_APP_SCHEME android-app:} referrer URI containing the 4748 * package name that started the Intent will be returned. This may return null if no 4749 * referrer can be identified -- it is neither explicitly specified, nor is it known which 4750 * application package was involved. 4751 * 4752 * <p>If called while inside the handling of {@link #onNewIntent}, this function will 4753 * return the referrer that submitted that new intent to the activity. Otherwise, it 4754 * always returns the referrer of the original Intent.</p> 4755 * 4756 * <p>Note that this is <em>not</em> a security feature -- you can not trust the 4757 * referrer information, applications can spoof it.</p> 4758 */ 4759 @Nullable 4760 public Uri getReferrer() { 4761 Intent intent = getIntent(); 4762 Uri referrer = intent.getParcelableExtra(Intent.EXTRA_REFERRER); 4763 if (referrer != null) { 4764 return referrer; 4765 } 4766 String referrerName = intent.getStringExtra(Intent.EXTRA_REFERRER_NAME); 4767 if (referrerName != null) { 4768 return Uri.parse(referrerName); 4769 } 4770 if (mReferrer != null) { 4771 return new Uri.Builder().scheme("android-app").authority(mReferrer).build(); 4772 } 4773 return null; 4774 } 4775 4776 /** 4777 * Override to generate the desired referrer for the content currently being shown 4778 * by the app. The default implementation returns null, meaning the referrer will simply 4779 * be the android-app: of the package name of this activity. Return a non-null Uri to 4780 * have that supplied as the {@link Intent#EXTRA_REFERRER} of any activities started from it. 4781 */ 4782 public Uri onProvideReferrer() { 4783 return null; 4784 } 4785 4786 /** 4787 * Return the name of the package that invoked this activity. This is who 4788 * the data in {@link #setResult setResult()} will be sent to. You can 4789 * use this information to validate that the recipient is allowed to 4790 * receive the data. 4791 * 4792 * <p class="note">Note: if the calling activity is not expecting a result (that is it 4793 * did not use the {@link #startActivityForResult} 4794 * form that includes a request code), then the calling package will be 4795 * null.</p> 4796 * 4797 * <p class="note">Note: prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 4798 * the result from this method was unstable. If the process hosting the calling 4799 * package was no longer running, it would return null instead of the proper package 4800 * name. You can use {@link #getCallingActivity()} and retrieve the package name 4801 * from that instead.</p> 4802 * 4803 * @return The package of the activity that will receive your 4804 * reply, or null if none. 4805 */ 4806 @Nullable 4807 public String getCallingPackage() { 4808 try { 4809 return ActivityManagerNative.getDefault().getCallingPackage(mToken); 4810 } catch (RemoteException e) { 4811 return null; 4812 } 4813 } 4814 4815 /** 4816 * Return the name of the activity that invoked this activity. This is 4817 * who the data in {@link #setResult setResult()} will be sent to. You 4818 * can use this information to validate that the recipient is allowed to 4819 * receive the data. 4820 * 4821 * <p class="note">Note: if the calling activity is not expecting a result (that is it 4822 * did not use the {@link #startActivityForResult} 4823 * form that includes a request code), then the calling package will be 4824 * null. 4825 * 4826 * @return The ComponentName of the activity that will receive your 4827 * reply, or null if none. 4828 */ 4829 @Nullable 4830 public ComponentName getCallingActivity() { 4831 try { 4832 return ActivityManagerNative.getDefault().getCallingActivity(mToken); 4833 } catch (RemoteException e) { 4834 return null; 4835 } 4836 } 4837 4838 /** 4839 * Control whether this activity's main window is visible. This is intended 4840 * only for the special case of an activity that is not going to show a 4841 * UI itself, but can't just finish prior to onResume() because it needs 4842 * to wait for a service binding or such. Setting this to false allows 4843 * you to prevent your UI from being shown during that time. 4844 * 4845 * <p>The default value for this is taken from the 4846 * {@link android.R.attr#windowNoDisplay} attribute of the activity's theme. 4847 */ 4848 public void setVisible(boolean visible) { 4849 if (mVisibleFromClient != visible) { 4850 mVisibleFromClient = visible; 4851 if (mVisibleFromServer) { 4852 if (visible) makeVisible(); 4853 else mDecor.setVisibility(View.INVISIBLE); 4854 } 4855 } 4856 } 4857 4858 void makeVisible() { 4859 if (!mWindowAdded) { 4860 ViewManager wm = getWindowManager(); 4861 wm.addView(mDecor, getWindow().getAttributes()); 4862 mWindowAdded = true; 4863 } 4864 mDecor.setVisibility(View.VISIBLE); 4865 } 4866 4867 /** 4868 * Check to see whether this activity is in the process of finishing, 4869 * either because you called {@link #finish} on it or someone else 4870 * has requested that it finished. This is often used in 4871 * {@link #onPause} to determine whether the activity is simply pausing or 4872 * completely finishing. 4873 * 4874 * @return If the activity is finishing, returns true; else returns false. 4875 * 4876 * @see #finish 4877 */ 4878 public boolean isFinishing() { 4879 return mFinished; 4880 } 4881 4882 /** 4883 * Returns true if the final {@link #onDestroy()} call has been made 4884 * on the Activity, so this instance is now dead. 4885 */ 4886 public boolean isDestroyed() { 4887 return mDestroyed; 4888 } 4889 4890 /** 4891 * Check to see whether this activity is in the process of being destroyed in order to be 4892 * recreated with a new configuration. This is often used in 4893 * {@link #onStop} to determine whether the state needs to be cleaned up or will be passed 4894 * on to the next instance of the activity via {@link #onRetainNonConfigurationInstance()}. 4895 * 4896 * @return If the activity is being torn down in order to be recreated with a new configuration, 4897 * returns true; else returns false. 4898 */ 4899 public boolean isChangingConfigurations() { 4900 return mChangingConfigurations; 4901 } 4902 4903 /** 4904 * Cause this Activity to be recreated with a new instance. This results 4905 * in essentially the same flow as when the Activity is created due to 4906 * a configuration change -- the current instance will go through its 4907 * lifecycle to {@link #onDestroy} and a new instance then created after it. 4908 */ 4909 public void recreate() { 4910 if (mParent != null) { 4911 throw new IllegalStateException("Can only be called on top-level activity"); 4912 } 4913 if (Looper.myLooper() != mMainThread.getLooper()) { 4914 throw new IllegalStateException("Must be called from main thread"); 4915 } 4916 mMainThread.requestRelaunchActivity(mToken, null, null, 0, false, null, null, false); 4917 } 4918 4919 /** 4920 * Finishes the current activity and specifies whether to remove the task associated with this 4921 * activity. 4922 */ 4923 private void finish(int finishTask) { 4924 if (mParent == null) { 4925 int resultCode; 4926 Intent resultData; 4927 synchronized (this) { 4928 resultCode = mResultCode; 4929 resultData = mResultData; 4930 } 4931 if (false) Log.v(TAG, "Finishing self: token=" + mToken); 4932 try { 4933 if (resultData != null) { 4934 resultData.prepareToLeaveProcess(); 4935 } 4936 if (ActivityManagerNative.getDefault() 4937 .finishActivity(mToken, resultCode, resultData, finishTask)) { 4938 mFinished = true; 4939 } 4940 } catch (RemoteException e) { 4941 // Empty 4942 } 4943 } else { 4944 mParent.finishFromChild(this); 4945 } 4946 } 4947 4948 /** 4949 * Call this when your activity is done and should be closed. The 4950 * ActivityResult is propagated back to whoever launched you via 4951 * onActivityResult(). 4952 */ 4953 public void finish() { 4954 finish(DONT_FINISH_TASK_WITH_ACTIVITY); 4955 } 4956 4957 /** 4958 * Finish this activity as well as all activities immediately below it 4959 * in the current task that have the same affinity. This is typically 4960 * used when an application can be launched on to another task (such as 4961 * from an ACTION_VIEW of a content type it understands) and the user 4962 * has used the up navigation to switch out of the current task and in 4963 * to its own task. In this case, if the user has navigated down into 4964 * any other activities of the second application, all of those should 4965 * be removed from the original task as part of the task switch. 4966 * 4967 * <p>Note that this finish does <em>not</em> allow you to deliver results 4968 * to the previous activity, and an exception will be thrown if you are trying 4969 * to do so.</p> 4970 */ 4971 public void finishAffinity() { 4972 if (mParent != null) { 4973 throw new IllegalStateException("Can not be called from an embedded activity"); 4974 } 4975 if (mResultCode != RESULT_CANCELED || mResultData != null) { 4976 throw new IllegalStateException("Can not be called to deliver a result"); 4977 } 4978 try { 4979 if (ActivityManagerNative.getDefault().finishActivityAffinity(mToken)) { 4980 mFinished = true; 4981 } 4982 } catch (RemoteException e) { 4983 // Empty 4984 } 4985 } 4986 4987 /** 4988 * This is called when a child activity of this one calls its 4989 * {@link #finish} method. The default implementation simply calls 4990 * finish() on this activity (the parent), finishing the entire group. 4991 * 4992 * @param child The activity making the call. 4993 * 4994 * @see #finish 4995 */ 4996 public void finishFromChild(Activity child) { 4997 finish(); 4998 } 4999 5000 /** 5001 * Reverses the Activity Scene entry Transition and triggers the calling Activity 5002 * to reverse its exit Transition. When the exit Transition completes, 5003 * {@link #finish()} is called. If no entry Transition was used, finish() is called 5004 * immediately and the Activity exit Transition is run. 5005 * @see android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, android.util.Pair[]) 5006 */ 5007 public void finishAfterTransition() { 5008 if (!mActivityTransitionState.startExitBackTransition(this)) { 5009 finish(); 5010 } 5011 } 5012 5013 /** 5014 * Force finish another activity that you had previously started with 5015 * {@link #startActivityForResult}. 5016 * 5017 * @param requestCode The request code of the activity that you had 5018 * given to startActivityForResult(). If there are multiple 5019 * activities started with this request code, they 5020 * will all be finished. 5021 */ 5022 public void finishActivity(int requestCode) { 5023 if (mParent == null) { 5024 try { 5025 ActivityManagerNative.getDefault() 5026 .finishSubActivity(mToken, mEmbeddedID, requestCode); 5027 } catch (RemoteException e) { 5028 // Empty 5029 } 5030 } else { 5031 mParent.finishActivityFromChild(this, requestCode); 5032 } 5033 } 5034 5035 /** 5036 * This is called when a child activity of this one calls its 5037 * finishActivity(). 5038 * 5039 * @param child The activity making the call. 5040 * @param requestCode Request code that had been used to start the 5041 * activity. 5042 */ 5043 public void finishActivityFromChild(@NonNull Activity child, int requestCode) { 5044 try { 5045 ActivityManagerNative.getDefault() 5046 .finishSubActivity(mToken, child.mEmbeddedID, requestCode); 5047 } catch (RemoteException e) { 5048 // Empty 5049 } 5050 } 5051 5052 /** 5053 * Call this when your activity is done and should be closed and the task should be completely 5054 * removed as a part of finishing the root activity of the task. 5055 */ 5056 public void finishAndRemoveTask() { 5057 finish(FINISH_TASK_WITH_ROOT_ACTIVITY); 5058 } 5059 5060 /** 5061 * Ask that the local app instance of this activity be released to free up its memory. 5062 * This is asking for the activity to be destroyed, but does <b>not</b> finish the activity -- 5063 * a new instance of the activity will later be re-created if needed due to the user 5064 * navigating back to it. 5065 * 5066 * @return Returns true if the activity was in a state that it has started the process 5067 * of destroying its current instance; returns false if for any reason this could not 5068 * be done: it is currently visible to the user, it is already being destroyed, it is 5069 * being finished, it hasn't yet saved its state, etc. 5070 */ 5071 public boolean releaseInstance() { 5072 try { 5073 return ActivityManagerNative.getDefault().releaseActivityInstance(mToken); 5074 } catch (RemoteException e) { 5075 // Empty 5076 } 5077 return false; 5078 } 5079 5080 /** 5081 * Called when an activity you launched exits, giving you the requestCode 5082 * you started it with, the resultCode it returned, and any additional 5083 * data from it. The <var>resultCode</var> will be 5084 * {@link #RESULT_CANCELED} if the activity explicitly returned that, 5085 * didn't return any result, or crashed during its operation. 5086 * 5087 * <p>You will receive this call immediately before onResume() when your 5088 * activity is re-starting. 5089 * 5090 * <p>This method is never invoked if your activity sets 5091 * {@link android.R.styleable#AndroidManifestActivity_noHistory noHistory} to 5092 * <code>true</code>. 5093 * 5094 * @param requestCode The integer request code originally supplied to 5095 * startActivityForResult(), allowing you to identify who this 5096 * result came from. 5097 * @param resultCode The integer result code returned by the child activity 5098 * through its setResult(). 5099 * @param data An Intent, which can return result data to the caller 5100 * (various data can be attached to Intent "extras"). 5101 * 5102 * @see #startActivityForResult 5103 * @see #createPendingResult 5104 * @see #setResult(int) 5105 */ 5106 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 5107 } 5108 5109 /** 5110 * Called when an activity you launched with an activity transition exposes this 5111 * Activity through a returning activity transition, giving you the resultCode 5112 * and any additional data from it. This method will only be called if the activity 5113 * set a result code other than {@link #RESULT_CANCELED} and it supports activity 5114 * transitions with {@link Window#FEATURE_ACTIVITY_TRANSITIONS}. 5115 * 5116 * <p>The purpose of this function is to let the called Activity send a hint about 5117 * its state so that this underlying Activity can prepare to be exposed. A call to 5118 * this method does not guarantee that the called Activity has or will be exiting soon. 5119 * It only indicates that it will expose this Activity's Window and it has 5120 * some data to pass to prepare it.</p> 5121 * 5122 * @param resultCode The integer result code returned by the child activity 5123 * through its setResult(). 5124 * @param data An Intent, which can return result data to the caller 5125 * (various data can be attached to Intent "extras"). 5126 */ 5127 public void onActivityReenter(int resultCode, Intent data) { 5128 } 5129 5130 /** 5131 * Create a new PendingIntent object which you can hand to others 5132 * for them to use to send result data back to your 5133 * {@link #onActivityResult} callback. The created object will be either 5134 * one-shot (becoming invalid after a result is sent back) or multiple 5135 * (allowing any number of results to be sent through it). 5136 * 5137 * @param requestCode Private request code for the sender that will be 5138 * associated with the result data when it is returned. The sender can not 5139 * modify this value, allowing you to identify incoming results. 5140 * @param data Default data to supply in the result, which may be modified 5141 * by the sender. 5142 * @param flags May be {@link PendingIntent#FLAG_ONE_SHOT PendingIntent.FLAG_ONE_SHOT}, 5143 * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE}, 5144 * {@link PendingIntent#FLAG_CANCEL_CURRENT PendingIntent.FLAG_CANCEL_CURRENT}, 5145 * {@link PendingIntent#FLAG_UPDATE_CURRENT PendingIntent.FLAG_UPDATE_CURRENT}, 5146 * or any of the flags as supported by 5147 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 5148 * of the intent that can be supplied when the actual send happens. 5149 * 5150 * @return Returns an existing or new PendingIntent matching the given 5151 * parameters. May return null only if 5152 * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE} has been 5153 * supplied. 5154 * 5155 * @see PendingIntent 5156 */ 5157 public PendingIntent createPendingResult(int requestCode, @NonNull Intent data, 5158 @PendingIntent.Flags int flags) { 5159 String packageName = getPackageName(); 5160 try { 5161 data.prepareToLeaveProcess(); 5162 IIntentSender target = 5163 ActivityManagerNative.getDefault().getIntentSender( 5164 ActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName, 5165 mParent == null ? mToken : mParent.mToken, 5166 mEmbeddedID, requestCode, new Intent[] { data }, null, flags, null, 5167 UserHandle.myUserId()); 5168 return target != null ? new PendingIntent(target) : null; 5169 } catch (RemoteException e) { 5170 // Empty 5171 } 5172 return null; 5173 } 5174 5175 /** 5176 * Change the desired orientation of this activity. If the activity 5177 * is currently in the foreground or otherwise impacting the screen 5178 * orientation, the screen will immediately be changed (possibly causing 5179 * the activity to be restarted). Otherwise, this will be used the next 5180 * time the activity is visible. 5181 * 5182 * @param requestedOrientation An orientation constant as used in 5183 * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}. 5184 */ 5185 public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) { 5186 if (mParent == null) { 5187 try { 5188 ActivityManagerNative.getDefault().setRequestedOrientation( 5189 mToken, requestedOrientation); 5190 } catch (RemoteException e) { 5191 // Empty 5192 } 5193 } else { 5194 mParent.setRequestedOrientation(requestedOrientation); 5195 } 5196 } 5197 5198 /** 5199 * Return the current requested orientation of the activity. This will 5200 * either be the orientation requested in its component's manifest, or 5201 * the last requested orientation given to 5202 * {@link #setRequestedOrientation(int)}. 5203 * 5204 * @return Returns an orientation constant as used in 5205 * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}. 5206 */ 5207 @ActivityInfo.ScreenOrientation 5208 public int getRequestedOrientation() { 5209 if (mParent == null) { 5210 try { 5211 return ActivityManagerNative.getDefault() 5212 .getRequestedOrientation(mToken); 5213 } catch (RemoteException e) { 5214 // Empty 5215 } 5216 } else { 5217 return mParent.getRequestedOrientation(); 5218 } 5219 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 5220 } 5221 5222 /** 5223 * Return the identifier of the task this activity is in. This identifier 5224 * will remain the same for the lifetime of the activity. 5225 * 5226 * @return Task identifier, an opaque integer. 5227 */ 5228 public int getTaskId() { 5229 try { 5230 return ActivityManagerNative.getDefault() 5231 .getTaskForActivity(mToken, false); 5232 } catch (RemoteException e) { 5233 return -1; 5234 } 5235 } 5236 5237 /** 5238 * Return whether this activity is the root of a task. The root is the 5239 * first activity in a task. 5240 * 5241 * @return True if this is the root activity, else false. 5242 */ 5243 public boolean isTaskRoot() { 5244 try { 5245 return ActivityManagerNative.getDefault() 5246 .getTaskForActivity(mToken, true) >= 0; 5247 } catch (RemoteException e) { 5248 return false; 5249 } 5250 } 5251 5252 /** 5253 * Move the task containing this activity to the back of the activity 5254 * stack. The activity's order within the task is unchanged. 5255 * 5256 * @param nonRoot If false then this only works if the activity is the root 5257 * of a task; if true it will work for any activity in 5258 * a task. 5259 * 5260 * @return If the task was moved (or it was already at the 5261 * back) true is returned, else false. 5262 */ 5263 public boolean moveTaskToBack(boolean nonRoot) { 5264 try { 5265 return ActivityManagerNative.getDefault().moveActivityTaskToBack( 5266 mToken, nonRoot); 5267 } catch (RemoteException e) { 5268 // Empty 5269 } 5270 return false; 5271 } 5272 5273 /** 5274 * Returns class name for this activity with the package prefix removed. 5275 * This is the default name used to read and write settings. 5276 * 5277 * @return The local class name. 5278 */ 5279 @NonNull 5280 public String getLocalClassName() { 5281 final String pkg = getPackageName(); 5282 final String cls = mComponent.getClassName(); 5283 int packageLen = pkg.length(); 5284 if (!cls.startsWith(pkg) || cls.length() <= packageLen 5285 || cls.charAt(packageLen) != '.') { 5286 return cls; 5287 } 5288 return cls.substring(packageLen+1); 5289 } 5290 5291 /** 5292 * Returns complete component name of this activity. 5293 * 5294 * @return Returns the complete component name for this activity 5295 */ 5296 public ComponentName getComponentName() 5297 { 5298 return mComponent; 5299 } 5300 5301 /** 5302 * Retrieve a {@link SharedPreferences} object for accessing preferences 5303 * that are private to this activity. This simply calls the underlying 5304 * {@link #getSharedPreferences(String, int)} method by passing in this activity's 5305 * class name as the preferences name. 5306 * 5307 * @param mode Operating mode. Use {@link #MODE_PRIVATE} for the default 5308 * operation, {@link #MODE_WORLD_READABLE} and 5309 * {@link #MODE_WORLD_WRITEABLE} to control permissions. 5310 * 5311 * @return Returns the single SharedPreferences instance that can be used 5312 * to retrieve and modify the preference values. 5313 */ 5314 public SharedPreferences getPreferences(int mode) { 5315 return getSharedPreferences(getLocalClassName(), mode); 5316 } 5317 5318 private void ensureSearchManager() { 5319 if (mSearchManager != null) { 5320 return; 5321 } 5322 5323 mSearchManager = new SearchManager(this, null); 5324 } 5325 5326 @Override 5327 public Object getSystemService(@ServiceName @NonNull String name) { 5328 if (getBaseContext() == null) { 5329 throw new IllegalStateException( 5330 "System services not available to Activities before onCreate()"); 5331 } 5332 5333 if (WINDOW_SERVICE.equals(name)) { 5334 return mWindowManager; 5335 } else if (SEARCH_SERVICE.equals(name)) { 5336 ensureSearchManager(); 5337 return mSearchManager; 5338 } 5339 return super.getSystemService(name); 5340 } 5341 5342 /** 5343 * Change the title associated with this activity. If this is a 5344 * top-level activity, the title for its window will change. If it 5345 * is an embedded activity, the parent can do whatever it wants 5346 * with it. 5347 */ 5348 public void setTitle(CharSequence title) { 5349 mTitle = title; 5350 onTitleChanged(title, mTitleColor); 5351 5352 if (mParent != null) { 5353 mParent.onChildTitleChanged(this, title); 5354 } 5355 } 5356 5357 /** 5358 * Change the title associated with this activity. If this is a 5359 * top-level activity, the title for its window will change. If it 5360 * is an embedded activity, the parent can do whatever it wants 5361 * with it. 5362 */ 5363 public void setTitle(int titleId) { 5364 setTitle(getText(titleId)); 5365 } 5366 5367 /** 5368 * Change the color of the title associated with this activity. 5369 * <p> 5370 * This method is deprecated starting in API Level 11 and replaced by action 5371 * bar styles. For information on styling the Action Bar, read the <a 5372 * href="{@docRoot} guide/topics/ui/actionbar.html">Action Bar</a> developer 5373 * guide. 5374 * 5375 * @deprecated Use action bar styles instead. 5376 */ 5377 @Deprecated 5378 public void setTitleColor(int textColor) { 5379 mTitleColor = textColor; 5380 onTitleChanged(mTitle, textColor); 5381 } 5382 5383 public final CharSequence getTitle() { 5384 return mTitle; 5385 } 5386 5387 public final int getTitleColor() { 5388 return mTitleColor; 5389 } 5390 5391 protected void onTitleChanged(CharSequence title, int color) { 5392 if (mTitleReady) { 5393 final Window win = getWindow(); 5394 if (win != null) { 5395 win.setTitle(title); 5396 if (color != 0) { 5397 win.setTitleColor(color); 5398 } 5399 } 5400 if (mActionBar != null) { 5401 mActionBar.setWindowTitle(title); 5402 } 5403 } 5404 } 5405 5406 protected void onChildTitleChanged(Activity childActivity, CharSequence title) { 5407 } 5408 5409 /** 5410 * Sets information describing the task with this activity for presentation inside the Recents 5411 * System UI. When {@link ActivityManager#getRecentTasks} is called, the activities of each task 5412 * are traversed in order from the topmost activity to the bottommost. The traversal continues 5413 * for each property until a suitable value is found. For each task the taskDescription will be 5414 * returned in {@link android.app.ActivityManager.TaskDescription}. 5415 * 5416 * @see ActivityManager#getRecentTasks 5417 * @see android.app.ActivityManager.TaskDescription 5418 * 5419 * @param taskDescription The TaskDescription properties that describe the task with this activity 5420 */ 5421 public void setTaskDescription(ActivityManager.TaskDescription taskDescription) { 5422 ActivityManager.TaskDescription td; 5423 // Scale the icon down to something reasonable if it is provided 5424 if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) { 5425 final int size = ActivityManager.getLauncherLargeIconSizeInner(this); 5426 final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size, true); 5427 td = new ActivityManager.TaskDescription(taskDescription.getLabel(), icon, 5428 taskDescription.getPrimaryColor()); 5429 } else { 5430 td = taskDescription; 5431 } 5432 try { 5433 ActivityManagerNative.getDefault().setTaskDescription(mToken, td); 5434 } catch (RemoteException e) { 5435 } 5436 } 5437 5438 /** 5439 * Sets the visibility of the progress bar in the title. 5440 * <p> 5441 * In order for the progress bar to be shown, the feature must be requested 5442 * via {@link #requestWindowFeature(int)}. 5443 * 5444 * @param visible Whether to show the progress bars in the title. 5445 * @deprecated No longer supported starting in API 21. 5446 */ 5447 @Deprecated 5448 public final void setProgressBarVisibility(boolean visible) { 5449 getWindow().setFeatureInt(Window.FEATURE_PROGRESS, visible ? Window.PROGRESS_VISIBILITY_ON : 5450 Window.PROGRESS_VISIBILITY_OFF); 5451 } 5452 5453 /** 5454 * Sets the visibility of the indeterminate progress bar in the title. 5455 * <p> 5456 * In order for the progress bar to be shown, the feature must be requested 5457 * via {@link #requestWindowFeature(int)}. 5458 * 5459 * @param visible Whether to show the progress bars in the title. 5460 * @deprecated No longer supported starting in API 21. 5461 */ 5462 @Deprecated 5463 public final void setProgressBarIndeterminateVisibility(boolean visible) { 5464 getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, 5465 visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF); 5466 } 5467 5468 /** 5469 * Sets whether the horizontal progress bar in the title should be indeterminate (the circular 5470 * is always indeterminate). 5471 * <p> 5472 * In order for the progress bar to be shown, the feature must be requested 5473 * via {@link #requestWindowFeature(int)}. 5474 * 5475 * @param indeterminate Whether the horizontal progress bar should be indeterminate. 5476 * @deprecated No longer supported starting in API 21. 5477 */ 5478 @Deprecated 5479 public final void setProgressBarIndeterminate(boolean indeterminate) { 5480 getWindow().setFeatureInt(Window.FEATURE_PROGRESS, 5481 indeterminate ? Window.PROGRESS_INDETERMINATE_ON 5482 : Window.PROGRESS_INDETERMINATE_OFF); 5483 } 5484 5485 /** 5486 * Sets the progress for the progress bars in the title. 5487 * <p> 5488 * In order for the progress bar to be shown, the feature must be requested 5489 * via {@link #requestWindowFeature(int)}. 5490 * 5491 * @param progress The progress for the progress bar. Valid ranges are from 5492 * 0 to 10000 (both inclusive). If 10000 is given, the progress 5493 * bar will be completely filled and will fade out. 5494 * @deprecated No longer supported starting in API 21. 5495 */ 5496 @Deprecated 5497 public final void setProgress(int progress) { 5498 getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START); 5499 } 5500 5501 /** 5502 * Sets the secondary progress for the progress bar in the title. This 5503 * progress is drawn between the primary progress (set via 5504 * {@link #setProgress(int)} and the background. It can be ideal for media 5505 * scenarios such as showing the buffering progress while the default 5506 * progress shows the play progress. 5507 * <p> 5508 * In order for the progress bar to be shown, the feature must be requested 5509 * via {@link #requestWindowFeature(int)}. 5510 * 5511 * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from 5512 * 0 to 10000 (both inclusive). 5513 * @deprecated No longer supported starting in API 21. 5514 */ 5515 @Deprecated 5516 public final void setSecondaryProgress(int secondaryProgress) { 5517 getWindow().setFeatureInt(Window.FEATURE_PROGRESS, 5518 secondaryProgress + Window.PROGRESS_SECONDARY_START); 5519 } 5520 5521 /** 5522 * Suggests an audio stream whose volume should be changed by the hardware 5523 * volume controls. 5524 * <p> 5525 * The suggested audio stream will be tied to the window of this Activity. 5526 * Volume requests which are received while the Activity is in the 5527 * foreground will affect this stream. 5528 * <p> 5529 * It is not guaranteed that the hardware volume controls will always change 5530 * this stream's volume (for example, if a call is in progress, its stream's 5531 * volume may be changed instead). To reset back to the default, use 5532 * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}. 5533 * 5534 * @param streamType The type of the audio stream whose volume should be 5535 * changed by the hardware volume controls. 5536 */ 5537 public final void setVolumeControlStream(int streamType) { 5538 getWindow().setVolumeControlStream(streamType); 5539 } 5540 5541 /** 5542 * Gets the suggested audio stream whose volume should be changed by the 5543 * hardware volume controls. 5544 * 5545 * @return The suggested audio stream type whose volume should be changed by 5546 * the hardware volume controls. 5547 * @see #setVolumeControlStream(int) 5548 */ 5549 public final int getVolumeControlStream() { 5550 return getWindow().getVolumeControlStream(); 5551 } 5552 5553 /** 5554 * Sets a {@link MediaController} to send media keys and volume changes to. 5555 * <p> 5556 * The controller will be tied to the window of this Activity. Media key and 5557 * volume events which are received while the Activity is in the foreground 5558 * will be forwarded to the controller and used to invoke transport controls 5559 * or adjust the volume. This may be used instead of or in addition to 5560 * {@link #setVolumeControlStream} to affect a specific session instead of a 5561 * specific stream. 5562 * <p> 5563 * It is not guaranteed that the hardware volume controls will always change 5564 * this session's volume (for example, if a call is in progress, its 5565 * stream's volume may be changed instead). To reset back to the default use 5566 * null as the controller. 5567 * 5568 * @param controller The controller for the session which should receive 5569 * media keys and volume changes. 5570 */ 5571 public final void setMediaController(MediaController controller) { 5572 getWindow().setMediaController(controller); 5573 } 5574 5575 /** 5576 * Gets the controller which should be receiving media key and volume events 5577 * while this activity is in the foreground. 5578 * 5579 * @return The controller which should receive events. 5580 * @see #setMediaController(android.media.session.MediaController) 5581 */ 5582 public final MediaController getMediaController() { 5583 return getWindow().getMediaController(); 5584 } 5585 5586 /** 5587 * Runs the specified action on the UI thread. If the current thread is the UI 5588 * thread, then the action is executed immediately. If the current thread is 5589 * not the UI thread, the action is posted to the event queue of the UI thread. 5590 * 5591 * @param action the action to run on the UI thread 5592 */ 5593 public final void runOnUiThread(Runnable action) { 5594 if (Thread.currentThread() != mUiThread) { 5595 mHandler.post(action); 5596 } else { 5597 action.run(); 5598 } 5599 } 5600 5601 /** 5602 * Standard implementation of 5603 * {@link android.view.LayoutInflater.Factory#onCreateView} used when 5604 * inflating with the LayoutInflater returned by {@link #getSystemService}. 5605 * This implementation does nothing and is for 5606 * pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} apps. Newer apps 5607 * should use {@link #onCreateView(View, String, Context, AttributeSet)}. 5608 * 5609 * @see android.view.LayoutInflater#createView 5610 * @see android.view.Window#getLayoutInflater 5611 */ 5612 @Nullable 5613 public View onCreateView(String name, Context context, AttributeSet attrs) { 5614 return null; 5615 } 5616 5617 /** 5618 * Standard implementation of 5619 * {@link android.view.LayoutInflater.Factory2#onCreateView(View, String, Context, AttributeSet)} 5620 * used when inflating with the LayoutInflater returned by {@link #getSystemService}. 5621 * This implementation handles <fragment> tags to embed fragments inside 5622 * of the activity. 5623 * 5624 * @see android.view.LayoutInflater#createView 5625 * @see android.view.Window#getLayoutInflater 5626 */ 5627 public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { 5628 if (!"fragment".equals(name)) { 5629 return onCreateView(name, context, attrs); 5630 } 5631 5632 return mFragments.onCreateView(parent, name, context, attrs); 5633 } 5634 5635 /** 5636 * Print the Activity's state into the given stream. This gets invoked if 5637 * you run "adb shell dumpsys activity <activity_component_name>". 5638 * 5639 * @param prefix Desired prefix to prepend at each line of output. 5640 * @param fd The raw file descriptor that the dump is being sent to. 5641 * @param writer The PrintWriter to which you should dump your state. This will be 5642 * closed for you after you return. 5643 * @param args additional arguments to the dump request. 5644 */ 5645 public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 5646 dumpInner(prefix, fd, writer, args); 5647 } 5648 5649 void dumpInner(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 5650 writer.print(prefix); writer.print("Local Activity "); 5651 writer.print(Integer.toHexString(System.identityHashCode(this))); 5652 writer.println(" State:"); 5653 String innerPrefix = prefix + " "; 5654 writer.print(innerPrefix); writer.print("mResumed="); 5655 writer.print(mResumed); writer.print(" mStopped="); 5656 writer.print(mStopped); writer.print(" mFinished="); 5657 writer.println(mFinished); 5658 writer.print(innerPrefix); writer.print("mChangingConfigurations="); 5659 writer.println(mChangingConfigurations); 5660 writer.print(innerPrefix); writer.print("mCurrentConfig="); 5661 writer.println(mCurrentConfig); 5662 5663 mFragments.dumpLoaders(innerPrefix, fd, writer, args); 5664 mFragments.getFragmentManager().dump(innerPrefix, fd, writer, args); 5665 if (mVoiceInteractor != null) { 5666 mVoiceInteractor.dump(innerPrefix, fd, writer, args); 5667 } 5668 5669 if (getWindow() != null && 5670 getWindow().peekDecorView() != null && 5671 getWindow().peekDecorView().getViewRootImpl() != null) { 5672 getWindow().peekDecorView().getViewRootImpl().dump(prefix, fd, writer, args); 5673 } 5674 5675 mHandler.getLooper().dump(new PrintWriterPrinter(writer), prefix); 5676 } 5677 5678 /** 5679 * Bit indicating that this activity is "immersive" and should not be 5680 * interrupted by notifications if possible. 5681 * 5682 * This value is initially set by the manifest property 5683 * <code>android:immersive</code> but may be changed at runtime by 5684 * {@link #setImmersive}. 5685 * 5686 * @see #setImmersive(boolean) 5687 * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE 5688 */ 5689 public boolean isImmersive() { 5690 try { 5691 return ActivityManagerNative.getDefault().isImmersive(mToken); 5692 } catch (RemoteException e) { 5693 return false; 5694 } 5695 } 5696 5697 /** 5698 * Indication of whether this is the highest level activity in this task. Can be used to 5699 * determine whether an activity launched by this activity was placed in the same task or 5700 * another task. 5701 * 5702 * @return true if this is the topmost, non-finishing activity in its task. 5703 */ 5704 private boolean isTopOfTask() { 5705 try { 5706 return ActivityManagerNative.getDefault().isTopOfTask(mToken); 5707 } catch (RemoteException e) { 5708 return false; 5709 } 5710 } 5711 5712 /** 5713 * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} to a 5714 * fullscreen opaque Activity. 5715 * <p> 5716 * Call this whenever the background of a translucent Activity has changed to become opaque. 5717 * Doing so will allow the {@link android.view.Surface} of the Activity behind to be released. 5718 * <p> 5719 * This call has no effect on non-translucent activities or on activities with the 5720 * {@link android.R.attr#windowIsFloating} attribute. 5721 * 5722 * @see #convertToTranslucent(android.app.Activity.TranslucentConversionListener, 5723 * ActivityOptions) 5724 * @see TranslucentConversionListener 5725 * 5726 * @hide 5727 */ 5728 @SystemApi 5729 public void convertFromTranslucent() { 5730 try { 5731 mTranslucentCallback = null; 5732 if (ActivityManagerNative.getDefault().convertFromTranslucent(mToken)) { 5733 WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true); 5734 } 5735 } catch (RemoteException e) { 5736 // pass 5737 } 5738 } 5739 5740 /** 5741 * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} back from 5742 * opaque to translucent following a call to {@link #convertFromTranslucent()}. 5743 * <p> 5744 * Calling this allows the Activity behind this one to be seen again. Once all such Activities 5745 * have been redrawn {@link TranslucentConversionListener#onTranslucentConversionComplete} will 5746 * be called indicating that it is safe to make this activity translucent again. Until 5747 * {@link TranslucentConversionListener#onTranslucentConversionComplete} is called the image 5748 * behind the frontmost Activity will be indeterminate. 5749 * <p> 5750 * This call has no effect on non-translucent activities or on activities with the 5751 * {@link android.R.attr#windowIsFloating} attribute. 5752 * 5753 * @param callback the method to call when all visible Activities behind this one have been 5754 * drawn and it is safe to make this Activity translucent again. 5755 * @param options activity options delivered to the activity below this one. The options 5756 * are retrieved using {@link #getActivityOptions}. 5757 * @return <code>true</code> if Window was opaque and will become translucent or 5758 * <code>false</code> if window was translucent and no change needed to be made. 5759 * 5760 * @see #convertFromTranslucent() 5761 * @see TranslucentConversionListener 5762 * 5763 * @hide 5764 */ 5765 @SystemApi 5766 public boolean convertToTranslucent(TranslucentConversionListener callback, 5767 ActivityOptions options) { 5768 boolean drawComplete; 5769 try { 5770 mTranslucentCallback = callback; 5771 mChangeCanvasToTranslucent = 5772 ActivityManagerNative.getDefault().convertToTranslucent(mToken, options); 5773 WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false); 5774 drawComplete = true; 5775 } catch (RemoteException e) { 5776 // Make callback return as though it timed out. 5777 mChangeCanvasToTranslucent = false; 5778 drawComplete = false; 5779 } 5780 if (!mChangeCanvasToTranslucent && mTranslucentCallback != null) { 5781 // Window is already translucent. 5782 mTranslucentCallback.onTranslucentConversionComplete(drawComplete); 5783 } 5784 return mChangeCanvasToTranslucent; 5785 } 5786 5787 /** @hide */ 5788 void onTranslucentConversionComplete(boolean drawComplete) { 5789 if (mTranslucentCallback != null) { 5790 mTranslucentCallback.onTranslucentConversionComplete(drawComplete); 5791 mTranslucentCallback = null; 5792 } 5793 if (mChangeCanvasToTranslucent) { 5794 WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false); 5795 } 5796 } 5797 5798 /** @hide */ 5799 public void onNewActivityOptions(ActivityOptions options) { 5800 mActivityTransitionState.setEnterActivityOptions(this, options); 5801 if (!mStopped) { 5802 mActivityTransitionState.enterReady(this); 5803 } 5804 } 5805 5806 /** 5807 * Retrieve the ActivityOptions passed in from the launching activity or passed back 5808 * from an activity launched by this activity in its call to {@link 5809 * #convertToTranslucent(TranslucentConversionListener, ActivityOptions)} 5810 * 5811 * @return The ActivityOptions passed to {@link #convertToTranslucent}. 5812 * @hide 5813 */ 5814 ActivityOptions getActivityOptions() { 5815 try { 5816 return ActivityManagerNative.getDefault().getActivityOptions(mToken); 5817 } catch (RemoteException e) { 5818 } 5819 return null; 5820 } 5821 5822 /** 5823 * Activities that want to remain visible behind a translucent activity above them must call 5824 * this method anytime between the start of {@link #onResume()} and the return from 5825 * {@link #onPause()}. If this call is successful then the activity will remain visible after 5826 * {@link #onPause()} is called, and is allowed to continue playing media in the background. 5827 * 5828 * <p>The actions of this call are reset each time that this activity is brought to the 5829 * front. That is, every time {@link #onResume()} is called the activity will be assumed 5830 * to not have requested visible behind. Therefore, if you want this activity to continue to 5831 * be visible in the background you must call this method again. 5832 * 5833 * <p>Only fullscreen opaque activities may make this call. I.e. this call is a nop 5834 * for dialog and translucent activities. 5835 * 5836 * <p>Under all circumstances, the activity must stop playing and release resources prior to or 5837 * within a call to {@link #onVisibleBehindCanceled()} or if this call returns false. 5838 * 5839 * <p>False will be returned any time this method is called between the return of onPause and 5840 * the next call to onResume. 5841 * 5842 * @param visible true to notify the system that the activity wishes to be visible behind other 5843 * translucent activities, false to indicate otherwise. Resources must be 5844 * released when passing false to this method. 5845 * @return the resulting visibiity state. If true the activity will remain visible beyond 5846 * {@link #onPause()} if the next activity is translucent or not fullscreen. If false 5847 * then the activity may not count on being visible behind other translucent activities, 5848 * and must stop any media playback and release resources. 5849 * Returning false may occur in lieu of a call to {@link #onVisibleBehindCanceled()} so 5850 * the return value must be checked. 5851 * 5852 * @see #onVisibleBehindCanceled() 5853 * @see #onBackgroundVisibleBehindChanged(boolean) 5854 */ 5855 public boolean requestVisibleBehind(boolean visible) { 5856 if (!mResumed) { 5857 // Do not permit paused or stopped activities to do this. 5858 visible = false; 5859 } 5860 try { 5861 mVisibleBehind = ActivityManagerNative.getDefault() 5862 .requestVisibleBehind(mToken, visible) && visible; 5863 } catch (RemoteException e) { 5864 mVisibleBehind = false; 5865 } 5866 return mVisibleBehind; 5867 } 5868 5869 /** 5870 * Called when a translucent activity over this activity is becoming opaque or another 5871 * activity is being launched. Activities that override this method must call 5872 * <code>super.onVisibleBehindCanceled()</code> or a SuperNotCalledException will be thrown. 5873 * 5874 * <p>When this method is called the activity has 500 msec to release any resources it may be 5875 * using while visible in the background. 5876 * If the activity has not returned from this method in 500 msec the system will destroy 5877 * the activity and kill the process in order to recover the resources for another 5878 * process. Otherwise {@link #onStop()} will be called following return. 5879 * 5880 * @see #requestVisibleBehind(boolean) 5881 * @see #onBackgroundVisibleBehindChanged(boolean) 5882 */ 5883 @CallSuper 5884 public void onVisibleBehindCanceled() { 5885 mCalled = true; 5886 } 5887 5888 /** 5889 * Translucent activities may call this to determine if there is an activity below them that 5890 * is currently set to be visible in the background. 5891 * 5892 * @return true if an activity below is set to visible according to the most recent call to 5893 * {@link #requestVisibleBehind(boolean)}, false otherwise. 5894 * 5895 * @see #requestVisibleBehind(boolean) 5896 * @see #onVisibleBehindCanceled() 5897 * @see #onBackgroundVisibleBehindChanged(boolean) 5898 * @hide 5899 */ 5900 @SystemApi 5901 public boolean isBackgroundVisibleBehind() { 5902 try { 5903 return ActivityManagerNative.getDefault().isBackgroundVisibleBehind(mToken); 5904 } catch (RemoteException e) { 5905 } 5906 return false; 5907 } 5908 5909 /** 5910 * The topmost foreground activity will receive this call when the background visibility state 5911 * of the activity below it changes. 5912 * 5913 * This call may be a consequence of {@link #requestVisibleBehind(boolean)} or might be 5914 * due to a background activity finishing itself. 5915 * 5916 * @param visible true if a background activity is visible, false otherwise. 5917 * 5918 * @see #requestVisibleBehind(boolean) 5919 * @see #onVisibleBehindCanceled() 5920 * @hide 5921 */ 5922 @SystemApi 5923 public void onBackgroundVisibleBehindChanged(boolean visible) { 5924 } 5925 5926 /** 5927 * Activities cannot draw during the period that their windows are animating in. In order 5928 * to know when it is safe to begin drawing they can override this method which will be 5929 * called when the entering animation has completed. 5930 */ 5931 public void onEnterAnimationComplete() { 5932 } 5933 5934 /** 5935 * @hide 5936 */ 5937 public void dispatchEnterAnimationComplete() { 5938 onEnterAnimationComplete(); 5939 if (getWindow() != null && getWindow().getDecorView() != null) { 5940 getWindow().getDecorView().getViewTreeObserver().dispatchOnEnterAnimationComplete(); 5941 } 5942 } 5943 5944 /** 5945 * Adjust the current immersive mode setting. 5946 * 5947 * Note that changing this value will have no effect on the activity's 5948 * {@link android.content.pm.ActivityInfo} structure; that is, if 5949 * <code>android:immersive</code> is set to <code>true</code> 5950 * in the application's manifest entry for this activity, the {@link 5951 * android.content.pm.ActivityInfo#flags ActivityInfo.flags} member will 5952 * always have its {@link android.content.pm.ActivityInfo#FLAG_IMMERSIVE 5953 * FLAG_IMMERSIVE} bit set. 5954 * 5955 * @see #isImmersive() 5956 * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE 5957 */ 5958 public void setImmersive(boolean i) { 5959 try { 5960 ActivityManagerNative.getDefault().setImmersive(mToken, i); 5961 } catch (RemoteException e) { 5962 // pass 5963 } 5964 } 5965 5966 /** 5967 * Start an action mode of the default type {@link ActionMode#TYPE_PRIMARY}. 5968 * 5969 * @param callback Callback that will manage lifecycle events for this action mode 5970 * @return The ActionMode that was started, or null if it was canceled 5971 * 5972 * @see ActionMode 5973 */ 5974 @Nullable 5975 public ActionMode startActionMode(ActionMode.Callback callback) { 5976 return mWindow.getDecorView().startActionMode(callback); 5977 } 5978 5979 /** 5980 * Start an action mode of the given type. 5981 * 5982 * @param callback Callback that will manage lifecycle events for this action mode 5983 * @param type One of {@link ActionMode#TYPE_PRIMARY} or {@link ActionMode#TYPE_FLOATING}. 5984 * @return The ActionMode that was started, or null if it was canceled 5985 * 5986 * @see ActionMode 5987 */ 5988 @Nullable 5989 public ActionMode startActionMode(ActionMode.Callback callback, int type) { 5990 return mWindow.getDecorView().startActionMode(callback, type); 5991 } 5992 5993 /** 5994 * Give the Activity a chance to control the UI for an action mode requested 5995 * by the system. 5996 * 5997 * <p>Note: If you are looking for a notification callback that an action mode 5998 * has been started for this activity, see {@link #onActionModeStarted(ActionMode)}.</p> 5999 * 6000 * @param callback The callback that should control the new action mode 6001 * @return The new action mode, or <code>null</code> if the activity does not want to 6002 * provide special handling for this action mode. (It will be handled by the system.) 6003 */ 6004 @Nullable 6005 @Override 6006 public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) { 6007 // Only Primary ActionModes are represented in the ActionBar. 6008 if (mActionModeTypeStarting == ActionMode.TYPE_PRIMARY) { 6009 initWindowDecorActionBar(); 6010 if (mActionBar != null) { 6011 return mActionBar.startActionMode(callback); 6012 } 6013 } 6014 return null; 6015 } 6016 6017 /** 6018 * {@inheritDoc} 6019 */ 6020 @Nullable 6021 @Override 6022 public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) { 6023 try { 6024 mActionModeTypeStarting = type; 6025 return onWindowStartingActionMode(callback); 6026 } finally { 6027 mActionModeTypeStarting = ActionMode.TYPE_PRIMARY; 6028 } 6029 } 6030 6031 /** 6032 * Notifies the Activity that an action mode has been started. 6033 * Activity subclasses overriding this method should call the superclass implementation. 6034 * 6035 * @param mode The new action mode. 6036 */ 6037 @CallSuper 6038 @Override 6039 public void onActionModeStarted(ActionMode mode) { 6040 } 6041 6042 /** 6043 * Notifies the activity that an action mode has finished. 6044 * Activity subclasses overriding this method should call the superclass implementation. 6045 * 6046 * @param mode The action mode that just finished. 6047 */ 6048 @CallSuper 6049 @Override 6050 public void onActionModeFinished(ActionMode mode) { 6051 } 6052 6053 /** 6054 * Returns true if the app should recreate the task when navigating 'up' from this activity 6055 * by using targetIntent. 6056 * 6057 * <p>If this method returns false the app can trivially call 6058 * {@link #navigateUpTo(Intent)} using the same parameters to correctly perform 6059 * up navigation. If this method returns false, the app should synthesize a new task stack 6060 * by using {@link TaskStackBuilder} or another similar mechanism to perform up navigation.</p> 6061 * 6062 * @param targetIntent An intent representing the target destination for up navigation 6063 * @return true if navigating up should recreate a new task stack, false if the same task 6064 * should be used for the destination 6065 */ 6066 public boolean shouldUpRecreateTask(Intent targetIntent) { 6067 try { 6068 PackageManager pm = getPackageManager(); 6069 ComponentName cn = targetIntent.getComponent(); 6070 if (cn == null) { 6071 cn = targetIntent.resolveActivity(pm); 6072 } 6073 ActivityInfo info = pm.getActivityInfo(cn, 0); 6074 if (info.taskAffinity == null) { 6075 return false; 6076 } 6077 return ActivityManagerNative.getDefault() 6078 .shouldUpRecreateTask(mToken, info.taskAffinity); 6079 } catch (RemoteException e) { 6080 return false; 6081 } catch (NameNotFoundException e) { 6082 return false; 6083 } 6084 } 6085 6086 /** 6087 * Navigate from this activity to the activity specified by upIntent, finishing this activity 6088 * in the process. If the activity indicated by upIntent already exists in the task's history, 6089 * this activity and all others before the indicated activity in the history stack will be 6090 * finished. 6091 * 6092 * <p>If the indicated activity does not appear in the history stack, this will finish 6093 * each activity in this task until the root activity of the task is reached, resulting in 6094 * an "in-app home" behavior. This can be useful in apps with a complex navigation hierarchy 6095 * when an activity may be reached by a path not passing through a canonical parent 6096 * activity.</p> 6097 * 6098 * <p>This method should be used when performing up navigation from within the same task 6099 * as the destination. If up navigation should cross tasks in some cases, see 6100 * {@link #shouldUpRecreateTask(Intent)}.</p> 6101 * 6102 * @param upIntent An intent representing the target destination for up navigation 6103 * 6104 * @return true if up navigation successfully reached the activity indicated by upIntent and 6105 * upIntent was delivered to it. false if an instance of the indicated activity could 6106 * not be found and this activity was simply finished normally. 6107 */ 6108 public boolean navigateUpTo(Intent upIntent) { 6109 if (mParent == null) { 6110 ComponentName destInfo = upIntent.getComponent(); 6111 if (destInfo == null) { 6112 destInfo = upIntent.resolveActivity(getPackageManager()); 6113 if (destInfo == null) { 6114 return false; 6115 } 6116 upIntent = new Intent(upIntent); 6117 upIntent.setComponent(destInfo); 6118 } 6119 int resultCode; 6120 Intent resultData; 6121 synchronized (this) { 6122 resultCode = mResultCode; 6123 resultData = mResultData; 6124 } 6125 if (resultData != null) { 6126 resultData.prepareToLeaveProcess(); 6127 } 6128 try { 6129 upIntent.prepareToLeaveProcess(); 6130 return ActivityManagerNative.getDefault().navigateUpTo(mToken, upIntent, 6131 resultCode, resultData); 6132 } catch (RemoteException e) { 6133 return false; 6134 } 6135 } else { 6136 return mParent.navigateUpToFromChild(this, upIntent); 6137 } 6138 } 6139 6140 /** 6141 * This is called when a child activity of this one calls its 6142 * {@link #navigateUpTo} method. The default implementation simply calls 6143 * navigateUpTo(upIntent) on this activity (the parent). 6144 * 6145 * @param child The activity making the call. 6146 * @param upIntent An intent representing the target destination for up navigation 6147 * 6148 * @return true if up navigation successfully reached the activity indicated by upIntent and 6149 * upIntent was delivered to it. false if an instance of the indicated activity could 6150 * not be found and this activity was simply finished normally. 6151 */ 6152 public boolean navigateUpToFromChild(Activity child, Intent upIntent) { 6153 return navigateUpTo(upIntent); 6154 } 6155 6156 /** 6157 * Obtain an {@link Intent} that will launch an explicit target activity specified by 6158 * this activity's logical parent. The logical parent is named in the application's manifest 6159 * by the {@link android.R.attr#parentActivityName parentActivityName} attribute. 6160 * Activity subclasses may override this method to modify the Intent returned by 6161 * super.getParentActivityIntent() or to implement a different mechanism of retrieving 6162 * the parent intent entirely. 6163 * 6164 * @return a new Intent targeting the defined parent of this activity or null if 6165 * there is no valid parent. 6166 */ 6167 @Nullable 6168 public Intent getParentActivityIntent() { 6169 final String parentName = mActivityInfo.parentActivityName; 6170 if (TextUtils.isEmpty(parentName)) { 6171 return null; 6172 } 6173 6174 // If the parent itself has no parent, generate a main activity intent. 6175 final ComponentName target = new ComponentName(this, parentName); 6176 try { 6177 final ActivityInfo parentInfo = getPackageManager().getActivityInfo(target, 0); 6178 final String parentActivity = parentInfo.parentActivityName; 6179 final Intent parentIntent = parentActivity == null 6180 ? Intent.makeMainActivity(target) 6181 : new Intent().setComponent(target); 6182 return parentIntent; 6183 } catch (NameNotFoundException e) { 6184 Log.e(TAG, "getParentActivityIntent: bad parentActivityName '" + parentName + 6185 "' in manifest"); 6186 return null; 6187 } 6188 } 6189 6190 /** 6191 * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, 6192 * android.view.View, String)} was used to start an Activity, <var>callback</var> 6193 * will be called to handle shared elements on the <i>launched</i> Activity. This requires 6194 * {@link Window#FEATURE_ACTIVITY_TRANSITIONS}. 6195 * 6196 * @param callback Used to manipulate shared element transitions on the launched Activity. 6197 */ 6198 public void setEnterSharedElementCallback(SharedElementCallback callback) { 6199 if (callback == null) { 6200 callback = SharedElementCallback.NULL_CALLBACK; 6201 } 6202 mEnterTransitionListener = callback; 6203 } 6204 6205 /** 6206 * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, 6207 * android.view.View, String)} was used to start an Activity, <var>callback</var> 6208 * will be called to handle shared elements on the <i>launching</i> Activity. Most 6209 * calls will only come when returning from the started Activity. 6210 * This requires {@link Window#FEATURE_ACTIVITY_TRANSITIONS}. 6211 * 6212 * @param callback Used to manipulate shared element transitions on the launching Activity. 6213 */ 6214 public void setExitSharedElementCallback(SharedElementCallback callback) { 6215 if (callback == null) { 6216 callback = SharedElementCallback.NULL_CALLBACK; 6217 } 6218 mExitTransitionListener = callback; 6219 } 6220 6221 /** 6222 * Postpone the entering activity transition when Activity was started with 6223 * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, 6224 * android.util.Pair[])}. 6225 * <p>This method gives the Activity the ability to delay starting the entering and 6226 * shared element transitions until all data is loaded. Until then, the Activity won't 6227 * draw into its window, leaving the window transparent. This may also cause the 6228 * returning animation to be delayed until data is ready. This method should be 6229 * called in {@link #onCreate(android.os.Bundle)} or in 6230 * {@link #onActivityReenter(int, android.content.Intent)}. 6231 * {@link #startPostponedEnterTransition()} must be called to allow the Activity to 6232 * start the transitions. If the Activity did not use 6233 * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, 6234 * android.util.Pair[])}, then this method does nothing.</p> 6235 */ 6236 public void postponeEnterTransition() { 6237 mActivityTransitionState.postponeEnterTransition(); 6238 } 6239 6240 /** 6241 * Begin postponed transitions after {@link #postponeEnterTransition()} was called. 6242 * If postponeEnterTransition() was called, you must call startPostponedEnterTransition() 6243 * to have your Activity start drawing. 6244 */ 6245 public void startPostponedEnterTransition() { 6246 mActivityTransitionState.startPostponedEnterTransition(); 6247 } 6248 6249 // ------------------ Internal API ------------------ 6250 6251 final void setParent(Activity parent) { 6252 mParent = parent; 6253 } 6254 6255 final void attach(Context context, ActivityThread aThread, 6256 Instrumentation instr, IBinder token, int ident, 6257 Application application, Intent intent, ActivityInfo info, 6258 CharSequence title, Activity parent, String id, 6259 NonConfigurationInstances lastNonConfigurationInstances, 6260 Configuration config, String referrer, IVoiceInteractor voiceInteractor) { 6261 attachBaseContext(context); 6262 6263 mFragments.attachHost(null /*parent*/); 6264 6265 mWindow = new PhoneWindow(this); 6266 mWindow.setWindowControllerCallback(this); 6267 mWindow.setCallback(this); 6268 mWindow.setOnWindowDismissedCallback(this); 6269 mWindow.getLayoutInflater().setPrivateFactory(this); 6270 if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { 6271 mWindow.setSoftInputMode(info.softInputMode); 6272 } 6273 if (info.uiOptions != 0) { 6274 mWindow.setUiOptions(info.uiOptions); 6275 } 6276 mUiThread = Thread.currentThread(); 6277 6278 mMainThread = aThread; 6279 mInstrumentation = instr; 6280 mToken = token; 6281 mIdent = ident; 6282 mApplication = application; 6283 mIntent = intent; 6284 mReferrer = referrer; 6285 mComponent = intent.getComponent(); 6286 mActivityInfo = info; 6287 mTitle = title; 6288 mParent = parent; 6289 mEmbeddedID = id; 6290 mLastNonConfigurationInstances = lastNonConfigurationInstances; 6291 if (voiceInteractor != null) { 6292 if (lastNonConfigurationInstances != null) { 6293 mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor; 6294 } else { 6295 mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this, 6296 Looper.myLooper()); 6297 } 6298 } 6299 6300 mWindow.setWindowManager( 6301 (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), 6302 mToken, mComponent.flattenToString(), 6303 (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); 6304 if (mParent != null) { 6305 mWindow.setContainer(mParent.getWindow()); 6306 } 6307 mWindowManager = mWindow.getWindowManager(); 6308 mCurrentConfig = config; 6309 } 6310 6311 /** @hide */ 6312 public final IBinder getActivityToken() { 6313 return mParent != null ? mParent.getActivityToken() : mToken; 6314 } 6315 6316 final void performCreateCommon() { 6317 mVisibleFromClient = !mWindow.getWindowStyle().getBoolean( 6318 com.android.internal.R.styleable.Window_windowNoDisplay, false); 6319 mFragments.dispatchActivityCreated(); 6320 mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions()); 6321 } 6322 6323 final void performCreate(Bundle icicle) { 6324 onCreate(icicle); 6325 mActivityTransitionState.readState(icicle); 6326 performCreateCommon(); 6327 } 6328 6329 final void performCreate(Bundle icicle, PersistableBundle persistentState) { 6330 onCreate(icicle, persistentState); 6331 mActivityTransitionState.readState(icicle); 6332 performCreateCommon(); 6333 } 6334 6335 final void performStart() { 6336 mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions()); 6337 mFragments.noteStateNotSaved(); 6338 mCalled = false; 6339 mFragments.execPendingActions(); 6340 mInstrumentation.callActivityOnStart(this); 6341 if (!mCalled) { 6342 throw new SuperNotCalledException( 6343 "Activity " + mComponent.toShortString() + 6344 " did not call through to super.onStart()"); 6345 } 6346 mFragments.dispatchStart(); 6347 mFragments.reportLoaderStart(); 6348 mActivityTransitionState.enterReady(this); 6349 } 6350 6351 final void performRestart() { 6352 mFragments.noteStateNotSaved(); 6353 6354 if (mStopped) { 6355 mStopped = false; 6356 if (mToken != null && mParent == null) { 6357 WindowManagerGlobal.getInstance().setStoppedState(mToken, false); 6358 } 6359 6360 synchronized (mManagedCursors) { 6361 final int N = mManagedCursors.size(); 6362 for (int i=0; i<N; i++) { 6363 ManagedCursor mc = mManagedCursors.get(i); 6364 if (mc.mReleased || mc.mUpdated) { 6365 if (!mc.mCursor.requery()) { 6366 if (getApplicationInfo().targetSdkVersion 6367 >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 6368 throw new IllegalStateException( 6369 "trying to requery an already closed cursor " 6370 + mc.mCursor); 6371 } 6372 } 6373 mc.mReleased = false; 6374 mc.mUpdated = false; 6375 } 6376 } 6377 } 6378 6379 mCalled = false; 6380 mInstrumentation.callActivityOnRestart(this); 6381 if (!mCalled) { 6382 throw new SuperNotCalledException( 6383 "Activity " + mComponent.toShortString() + 6384 " did not call through to super.onRestart()"); 6385 } 6386 performStart(); 6387 } 6388 } 6389 6390 final void performResume() { 6391 performRestart(); 6392 6393 mFragments.execPendingActions(); 6394 6395 mLastNonConfigurationInstances = null; 6396 6397 mCalled = false; 6398 // mResumed is set by the instrumentation 6399 mInstrumentation.callActivityOnResume(this); 6400 if (!mCalled) { 6401 throw new SuperNotCalledException( 6402 "Activity " + mComponent.toShortString() + 6403 " did not call through to super.onResume()"); 6404 } 6405 6406 // invisible activities must be finished before onResume() completes 6407 if (!mVisibleFromClient && !mFinished) { 6408 Log.w(TAG, "An activity without a UI must call finish() before onResume() completes"); 6409 if (getApplicationInfo().targetSdkVersion 6410 > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { 6411 throw new IllegalStateException( 6412 "Activity " + mComponent.toShortString() + 6413 " did not call finish() prior to onResume() completing"); 6414 } 6415 } 6416 6417 // Now really resume, and install the current status bar and menu. 6418 mCalled = false; 6419 6420 mFragments.dispatchResume(); 6421 mFragments.execPendingActions(); 6422 6423 onPostResume(); 6424 if (!mCalled) { 6425 throw new SuperNotCalledException( 6426 "Activity " + mComponent.toShortString() + 6427 " did not call through to super.onPostResume()"); 6428 } 6429 } 6430 6431 final void performPause() { 6432 mDoReportFullyDrawn = false; 6433 mFragments.dispatchPause(); 6434 mCalled = false; 6435 onPause(); 6436 mResumed = false; 6437 if (!mCalled && getApplicationInfo().targetSdkVersion 6438 >= android.os.Build.VERSION_CODES.GINGERBREAD) { 6439 throw new SuperNotCalledException( 6440 "Activity " + mComponent.toShortString() + 6441 " did not call through to super.onPause()"); 6442 } 6443 mResumed = false; 6444 } 6445 6446 final void performUserLeaving() { 6447 onUserInteraction(); 6448 onUserLeaveHint(); 6449 } 6450 6451 final void performStop() { 6452 mDoReportFullyDrawn = false; 6453 mFragments.doLoaderStop(mChangingConfigurations /*retain*/); 6454 6455 if (!mStopped) { 6456 if (mWindow != null) { 6457 mWindow.closeAllPanels(); 6458 } 6459 6460 if (mToken != null && mParent == null) { 6461 WindowManagerGlobal.getInstance().setStoppedState(mToken, true); 6462 } 6463 6464 mFragments.dispatchStop(); 6465 6466 mCalled = false; 6467 mInstrumentation.callActivityOnStop(this); 6468 if (!mCalled) { 6469 throw new SuperNotCalledException( 6470 "Activity " + mComponent.toShortString() + 6471 " did not call through to super.onStop()"); 6472 } 6473 6474 synchronized (mManagedCursors) { 6475 final int N = mManagedCursors.size(); 6476 for (int i=0; i<N; i++) { 6477 ManagedCursor mc = mManagedCursors.get(i); 6478 if (!mc.mReleased) { 6479 mc.mCursor.deactivate(); 6480 mc.mReleased = true; 6481 } 6482 } 6483 } 6484 6485 mStopped = true; 6486 } 6487 mResumed = false; 6488 } 6489 6490 final void performDestroy() { 6491 mDestroyed = true; 6492 mWindow.destroy(); 6493 mFragments.dispatchDestroy(); 6494 onDestroy(); 6495 mFragments.doLoaderDestroy(); 6496 if (mVoiceInteractor != null) { 6497 mVoiceInteractor.detachActivity(); 6498 } 6499 } 6500 6501 /** 6502 * @hide 6503 */ 6504 public final boolean isResumed() { 6505 return mResumed; 6506 } 6507 6508 void dispatchActivityResult(String who, int requestCode, 6509 int resultCode, Intent data) { 6510 if (false) Log.v( 6511 TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode 6512 + ", resCode=" + resultCode + ", data=" + data); 6513 mFragments.noteStateNotSaved(); 6514 if (who == null) { 6515 onActivityResult(requestCode, resultCode, data); 6516 } else if (who.startsWith(REQUEST_PERMISSIONS_WHO_PREFIX)) { 6517 who = who.substring(REQUEST_PERMISSIONS_WHO_PREFIX.length()); 6518 if (TextUtils.isEmpty(who)) { 6519 dispatchRequestPermissionsResult(requestCode, data); 6520 } else { 6521 Fragment frag = mFragments.findFragmentByWho(who); 6522 if (frag != null) { 6523 dispatchRequestPermissionsResultToFragment(requestCode, data, frag); 6524 } 6525 } 6526 } else if (who.startsWith("@android:view:")) { 6527 ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews( 6528 getActivityToken()); 6529 for (ViewRootImpl viewRoot : views) { 6530 if (viewRoot.getView() != null 6531 && viewRoot.getView().dispatchActivityResult( 6532 who, requestCode, resultCode, data)) { 6533 return; 6534 } 6535 } 6536 } else { 6537 Fragment frag = mFragments.findFragmentByWho(who); 6538 if (frag != null) { 6539 frag.onActivityResult(requestCode, resultCode, data); 6540 } 6541 } 6542 } 6543 6544 /** 6545 * Request to put this Activity in a mode where the user is locked to the 6546 * current task. 6547 * 6548 * This will prevent the user from launching other apps, going to settings, or reaching the 6549 * home screen. This does not include those apps whose {@link android.R.attr#lockTaskMode} 6550 * values permit launching while locked. 6551 * 6552 * If {@link DevicePolicyManager#isLockTaskPermitted(String)} returns true or 6553 * lockTaskMode=lockTaskModeAlways for this component then the app will go directly into 6554 * Lock Task mode. The user will not be able to exit this mode until 6555 * {@link Activity#stopLockTask()} is called. 6556 * 6557 * If {@link DevicePolicyManager#isLockTaskPermitted(String)} returns false 6558 * then the system will prompt the user with a dialog requesting permission to enter 6559 * this mode. When entered through this method the user can exit at any time through 6560 * an action described by the request dialog. Calling stopLockTask will also exit the 6561 * mode. 6562 * 6563 * @see android.R.attr#lockTaskMode 6564 */ 6565 public void startLockTask() { 6566 try { 6567 ActivityManagerNative.getDefault().startLockTaskMode(mToken); 6568 } catch (RemoteException e) { 6569 } 6570 } 6571 6572 /** 6573 * Allow the user to switch away from the current task. 6574 * 6575 * Called to end the mode started by {@link Activity#startLockTask}. This 6576 * can only be called by activities that have successfully called 6577 * startLockTask previously. 6578 * 6579 * This will allow the user to exit this app and move onto other activities. 6580 * <p>Note: This method should only be called when the activity is user-facing. That is, 6581 * between onResume() and onPause(). 6582 * <p>Note: If there are other tasks below this one that are also locked then calling this 6583 * method will immediately finish this task and resume the previous locked one, remaining in 6584 * lockTask mode. 6585 * 6586 * @see android.R.attr#lockTaskMode 6587 * @see ActivityManager#getLockTaskModeState() 6588 */ 6589 public void stopLockTask() { 6590 try { 6591 ActivityManagerNative.getDefault().stopLockTaskMode(); 6592 } catch (RemoteException e) { 6593 } 6594 } 6595 6596 /** 6597 * Shows the user the system defined message for telling the user how to exit 6598 * lock task mode. The task containing this activity must be in lock task mode at the time 6599 * of this call for the message to be displayed. 6600 */ 6601 public void showLockTaskEscapeMessage() { 6602 try { 6603 ActivityManagerNative.getDefault().showLockTaskEscapeMessage(mToken); 6604 } catch (RemoteException e) { 6605 } 6606 } 6607 6608 /** 6609 * Interface for informing a translucent {@link Activity} once all visible activities below it 6610 * have completed drawing. This is necessary only after an {@link Activity} has been made 6611 * opaque using {@link Activity#convertFromTranslucent()} and before it has been drawn 6612 * translucent again following a call to {@link 6613 * Activity#convertToTranslucent(android.app.Activity.TranslucentConversionListener, 6614 * ActivityOptions)} 6615 * 6616 * @hide 6617 */ 6618 @SystemApi 6619 public interface TranslucentConversionListener { 6620 /** 6621 * Callback made following {@link Activity#convertToTranslucent} once all visible Activities 6622 * below the top one have been redrawn. Following this callback it is safe to make the top 6623 * Activity translucent because the underlying Activity has been drawn. 6624 * 6625 * @param drawComplete True if the background Activity has drawn itself. False if a timeout 6626 * occurred waiting for the Activity to complete drawing. 6627 * 6628 * @see Activity#convertFromTranslucent() 6629 * @see Activity#convertToTranslucent(TranslucentConversionListener, ActivityOptions) 6630 */ 6631 public void onTranslucentConversionComplete(boolean drawComplete); 6632 } 6633 6634 private void dispatchRequestPermissionsResult(int requestCode, Intent data) { 6635 // If the package installer crashed we may have not data - best effort. 6636 String[] permissions = (data != null) ? data.getStringArrayExtra( 6637 PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0]; 6638 final int[] grantResults = (data != null) ? data.getIntArrayExtra( 6639 PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0]; 6640 onRequestPermissionsResult(requestCode, permissions, grantResults); 6641 } 6642 6643 private void dispatchRequestPermissionsResultToFragment(int requestCode, Intent data, 6644 Fragment fragment) { 6645 // If the package installer crashed we may have not data - best effort. 6646 String[] permissions = (data != null) ? data.getStringArrayExtra( 6647 PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0]; 6648 final int[] grantResults = (data != null) ? data.getIntArrayExtra( 6649 PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0]; 6650 fragment.onRequestPermissionsResult(requestCode, permissions, grantResults); 6651 } 6652 6653 class HostCallbacks extends FragmentHostCallback<Activity> { 6654 public HostCallbacks() { 6655 super(Activity.this /*activity*/); 6656 } 6657 6658 @Override 6659 public void onDump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 6660 Activity.this.dump(prefix, fd, writer, args); 6661 } 6662 6663 @Override 6664 public boolean onShouldSaveFragmentState(Fragment fragment) { 6665 return !isFinishing(); 6666 } 6667 6668 @Override 6669 public LayoutInflater onGetLayoutInflater() { 6670 final LayoutInflater result = Activity.this.getLayoutInflater(); 6671 if (onUseFragmentManagerInflaterFactory()) { 6672 return result.cloneInContext(Activity.this); 6673 } 6674 return result; 6675 } 6676 6677 @Override 6678 public boolean onUseFragmentManagerInflaterFactory() { 6679 // Newer platform versions use the child fragment manager's LayoutInflaterFactory. 6680 return getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP; 6681 } 6682 6683 @Override 6684 public Activity onGetHost() { 6685 return Activity.this; 6686 } 6687 6688 @Override 6689 public void onInvalidateOptionsMenu() { 6690 Activity.this.invalidateOptionsMenu(); 6691 } 6692 6693 @Override 6694 public void onStartActivityFromFragment(Fragment fragment, Intent intent, int requestCode, 6695 Bundle options) { 6696 Activity.this.startActivityFromFragment(fragment, intent, requestCode, options); 6697 } 6698 6699 @Override 6700 public void onRequestPermissionsFromFragment(Fragment fragment, String[] permissions, 6701 int requestCode) { 6702 String who = REQUEST_PERMISSIONS_WHO_PREFIX + fragment.mWho; 6703 Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions); 6704 startActivityForResult(who, intent, requestCode, null); 6705 } 6706 6707 @Override 6708 public boolean onHasWindowAnimations() { 6709 return getWindow() != null; 6710 } 6711 6712 @Override 6713 public int onGetWindowAnimations() { 6714 final Window w = getWindow(); 6715 return (w == null) ? 0 : w.getAttributes().windowAnimations; 6716 } 6717 6718 @Override 6719 public void onAttachFragment(Fragment fragment) { 6720 Activity.this.onAttachFragment(fragment); 6721 } 6722 6723 @Nullable 6724 @Override 6725 public View onFindViewById(int id) { 6726 return Activity.this.findViewById(id); 6727 } 6728 6729 @Override 6730 public boolean onHasView() { 6731 final Window w = getWindow(); 6732 return (w != null && w.peekDecorView() != null); 6733 } 6734 } 6735} 6736