1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IIntentReceiver; 25 import android.content.IIntentSender; 26 import android.content.IntentSender; 27 import android.os.Bundle; 28 import android.os.Looper; 29 import android.os.RemoteException; 30 import android.os.Handler; 31 import android.os.IBinder; 32 import android.os.Parcel; 33 import android.os.Parcelable; 34 import android.os.Process; 35 import android.os.UserHandle; 36 import android.util.AndroidException; 37 38 import java.lang.annotation.Retention; 39 import java.lang.annotation.RetentionPolicy; 40 41 /** 42 * A description of an Intent and target action to perform with it. Instances 43 * of this class are created with {@link #getActivity}, {@link #getActivities}, 44 * {@link #getBroadcast}, and {@link #getService}; the returned object can be 45 * handed to other applications so that they can perform the action you 46 * described on your behalf at a later time. 47 * 48 * <p>By giving a PendingIntent to another application, 49 * you are granting it the right to perform the operation you have specified 50 * as if the other application was yourself (with the same permissions and 51 * identity). As such, you should be careful about how you build the PendingIntent: 52 * almost always, for example, the base Intent you supply should have the component 53 * name explicitly set to one of your own components, to ensure it is ultimately 54 * sent there and nowhere else. 55 * 56 * <p>A PendingIntent itself is simply a reference to a token maintained by 57 * the system describing the original data used to retrieve it. This means 58 * that, even if its owning application's process is killed, the 59 * PendingIntent itself will remain usable from other processes that 60 * have been given it. If the creating application later re-retrieves the 61 * same kind of PendingIntent (same operation, same Intent action, data, 62 * categories, and components, and same flags), it will receive a PendingIntent 63 * representing the same token if that is still valid, and can thus call 64 * {@link #cancel} to remove it. 65 * 66 * <p>Because of this behavior, it is important to know when two Intents 67 * are considered to be the same for purposes of retrieving a PendingIntent. 68 * A common mistake people make is to create multiple PendingIntent objects 69 * with Intents that only vary in their "extra" contents, expecting to get 70 * a different PendingIntent each time. This does <em>not</em> happen. The 71 * parts of the Intent that are used for matching are the same ones defined 72 * by {@link Intent#filterEquals(Intent) Intent.filterEquals}. If you use two 73 * Intent objects that are equivalent as per 74 * {@link Intent#filterEquals(Intent) Intent.filterEquals}, then you will get 75 * the same PendingIntent for both of them. 76 * 77 * <p>There are two typical ways to deal with this. 78 * 79 * <p>If you truly need multiple distinct PendingIntent objects active at 80 * the same time (such as to use as two notifications that are both shown 81 * at the same time), then you will need to ensure there is something that 82 * is different about them to associate them with different PendingIntents. 83 * This may be any of the Intent attributes considered by 84 * {@link Intent#filterEquals(Intent) Intent.filterEquals}, or different 85 * request code integers supplied to {@link #getActivity}, {@link #getActivities}, 86 * {@link #getBroadcast}, or {@link #getService}. 87 * 88 * <p>If you only need one PendingIntent active at a time for any of the 89 * Intents you will use, then you can alternatively use the flags 90 * {@link #FLAG_CANCEL_CURRENT} or {@link #FLAG_UPDATE_CURRENT} to either 91 * cancel or modify whatever current PendingIntent is associated with the 92 * Intent you are supplying. 93 */ 94 public final class PendingIntent implements Parcelable { 95 private final IIntentSender mTarget; 96 97 /** @hide */ 98 @IntDef(flag = true, 99 value = { 100 FLAG_ONE_SHOT, 101 FLAG_NO_CREATE, 102 FLAG_CANCEL_CURRENT, 103 FLAG_UPDATE_CURRENT, 104 105 Intent.FILL_IN_ACTION, 106 Intent.FILL_IN_DATA, 107 Intent.FILL_IN_CATEGORIES, 108 Intent.FILL_IN_COMPONENT, 109 Intent.FILL_IN_PACKAGE, 110 Intent.FILL_IN_SOURCE_BOUNDS, 111 Intent.FILL_IN_SELECTOR, 112 Intent.FILL_IN_CLIP_DATA 113 }) 114 @Retention(RetentionPolicy.SOURCE) 115 public @interface Flags {} 116 117 /** 118 * Flag indicating that this PendingIntent can be used only once. 119 * For use with {@link #getActivity}, {@link #getBroadcast}, and 120 * {@link #getService}. <p>If set, after 121 * {@link #send()} is called on it, it will be automatically 122 * canceled for you and any future attempt to send through it will fail. 123 */ 124 public static final int FLAG_ONE_SHOT = 1<<30; 125 /** 126 * Flag indicating that if the described PendingIntent does not 127 * already exist, then simply return null instead of creating it. 128 * For use with {@link #getActivity}, {@link #getBroadcast}, and 129 * {@link #getService}. 130 */ 131 public static final int FLAG_NO_CREATE = 1<<29; 132 /** 133 * Flag indicating that if the described PendingIntent already exists, 134 * the current one should be canceled before generating a new one. 135 * For use with {@link #getActivity}, {@link #getBroadcast}, and 136 * {@link #getService}. <p>You can use 137 * this to retrieve a new PendingIntent when you are only changing the 138 * extra data in the Intent; by canceling the previous pending intent, 139 * this ensures that only entities given the new data will be able to 140 * launch it. If this assurance is not an issue, consider 141 * {@link #FLAG_UPDATE_CURRENT}. 142 */ 143 public static final int FLAG_CANCEL_CURRENT = 1<<28; 144 /** 145 * Flag indicating that if the described PendingIntent already exists, 146 * then keep it but replace its extra data with what is in this new 147 * Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and 148 * {@link #getService}. <p>This can be used if you are creating intents where only the 149 * extras change, and don't care that any entities that received your 150 * previous PendingIntent will be able to launch it with your new 151 * extras even if they are not explicitly given to it. 152 */ 153 public static final int FLAG_UPDATE_CURRENT = 1<<27; 154 155 /** 156 * Flag indicating that the created PendingIntent should be immutable. 157 * This means that the additional intent argument passed to the send 158 * methods to fill in unpopulated properties of this intent will be 159 * ignored. 160 */ 161 public static final int FLAG_IMMUTABLE = 1<<26; 162 163 /** 164 * Exception thrown when trying to send through a PendingIntent that 165 * has been canceled or is otherwise no longer able to execute the request. 166 */ 167 public static class CanceledException extends AndroidException { CanceledException()168 public CanceledException() { 169 } 170 CanceledException(String name)171 public CanceledException(String name) { 172 super(name); 173 } 174 CanceledException(Exception cause)175 public CanceledException(Exception cause) { 176 super(cause); 177 } 178 } 179 180 /** 181 * Callback interface for discovering when a send operation has 182 * completed. Primarily for use with a PendingIntent that is 183 * performing a broadcast, this provides the same information as 184 * calling {@link Context#sendOrderedBroadcast(Intent, String, 185 * android.content.BroadcastReceiver, Handler, int, String, Bundle) 186 * Context.sendBroadcast()} with a final BroadcastReceiver. 187 */ 188 public interface OnFinished { 189 /** 190 * Called when a send operation as completed. 191 * 192 * @param pendingIntent The PendingIntent this operation was sent through. 193 * @param intent The original Intent that was sent. 194 * @param resultCode The final result code determined by the send. 195 * @param resultData The final data collected by a broadcast. 196 * @param resultExtras The final extras collected by a broadcast. 197 */ onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)198 void onSendFinished(PendingIntent pendingIntent, Intent intent, 199 int resultCode, String resultData, Bundle resultExtras); 200 } 201 202 private static class FinishedDispatcher extends IIntentReceiver.Stub 203 implements Runnable { 204 private final PendingIntent mPendingIntent; 205 private final OnFinished mWho; 206 private final Handler mHandler; 207 private Intent mIntent; 208 private int mResultCode; 209 private String mResultData; 210 private Bundle mResultExtras; 211 private static Handler sDefaultSystemHandler; FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler)212 FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler) { 213 mPendingIntent = pi; 214 mWho = who; 215 if (handler == null && ActivityThread.isSystem()) { 216 // We assign a default handler for the system process to avoid deadlocks when 217 // processing receivers in various components that hold global service locks. 218 if (sDefaultSystemHandler == null) { 219 sDefaultSystemHandler = new Handler(Looper.getMainLooper()); 220 } 221 mHandler = sDefaultSystemHandler; 222 } else { 223 mHandler = handler; 224 } 225 } performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean serialized, boolean sticky, int sendingUser)226 public void performReceive(Intent intent, int resultCode, String data, 227 Bundle extras, boolean serialized, boolean sticky, int sendingUser) { 228 mIntent = intent; 229 mResultCode = resultCode; 230 mResultData = data; 231 mResultExtras = extras; 232 if (mHandler == null) { 233 run(); 234 } else { 235 mHandler.post(this); 236 } 237 } run()238 public void run() { 239 mWho.onSendFinished(mPendingIntent, mIntent, mResultCode, 240 mResultData, mResultExtras); 241 } 242 } 243 244 /** 245 * Listener for observing when pending intents are written to a parcel. 246 * 247 * @hide 248 */ 249 public interface OnMarshaledListener { 250 /** 251 * Called when a pending intent is written to a parcel. 252 * 253 * @param intent The pending intent. 254 * @param parcel The parcel to which it was written. 255 * @param flags The parcel flags when it was written. 256 */ onMarshaled(PendingIntent intent, Parcel parcel, int flags)257 void onMarshaled(PendingIntent intent, Parcel parcel, int flags); 258 } 259 260 private static final ThreadLocal<OnMarshaledListener> sOnMarshaledListener 261 = new ThreadLocal<>(); 262 263 /** 264 * Registers an listener for pending intents being written to a parcel. 265 * 266 * @param listener The listener, null to clear. 267 * 268 * @hide 269 */ setOnMarshaledListener(OnMarshaledListener listener)270 public static void setOnMarshaledListener(OnMarshaledListener listener) { 271 sOnMarshaledListener.set(listener); 272 } 273 274 /** 275 * Retrieve a PendingIntent that will start a new activity, like calling 276 * {@link Context#startActivity(Intent) Context.startActivity(Intent)}. 277 * Note that the activity will be started outside of the context of an 278 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 279 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. 280 * 281 * <p class="note">For security reasons, the {@link android.content.Intent} 282 * you supply here should almost always be an <em>explicit intent</em>, 283 * that is specify an explicit component to be delivered to through 284 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 285 * 286 * @param context The Context in which this PendingIntent should start 287 * the activity. 288 * @param requestCode Private request code for the sender 289 * @param intent Intent of the activity to be launched. 290 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 291 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 292 * or any of the flags as supported by 293 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 294 * of the intent that can be supplied when the actual send happens. 295 * 296 * @return Returns an existing or new PendingIntent matching the given 297 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 298 * supplied. 299 */ getActivity(Context context, int requestCode, Intent intent, @Flags int flags)300 public static PendingIntent getActivity(Context context, int requestCode, 301 Intent intent, @Flags int flags) { 302 return getActivity(context, requestCode, intent, flags, null); 303 } 304 305 /** 306 * Retrieve a PendingIntent that will start a new activity, like calling 307 * {@link Context#startActivity(Intent) Context.startActivity(Intent)}. 308 * Note that the activity will be started outside of the context of an 309 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 310 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. 311 * 312 * <p class="note">For security reasons, the {@link android.content.Intent} 313 * you supply here should almost always be an <em>explicit intent</em>, 314 * that is specify an explicit component to be delivered to through 315 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 316 * 317 * @param context The Context in which this PendingIntent should start 318 * the activity. 319 * @param requestCode Private request code for the sender 320 * @param intent Intent of the activity to be launched. 321 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 322 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 323 * or any of the flags as supported by 324 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 325 * of the intent that can be supplied when the actual send happens. 326 * @param options Additional options for how the Activity should be started. 327 * May be null if there are no options. 328 * 329 * @return Returns an existing or new PendingIntent matching the given 330 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 331 * supplied. 332 */ getActivity(Context context, int requestCode, @NonNull Intent intent, @Flags int flags, @Nullable Bundle options)333 public static PendingIntent getActivity(Context context, int requestCode, 334 @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) { 335 String packageName = context.getPackageName(); 336 String resolvedType = intent != null ? intent.resolveTypeIfNeeded( 337 context.getContentResolver()) : null; 338 try { 339 intent.migrateExtraStreamToClipData(); 340 intent.prepareToLeaveProcess(context); 341 IIntentSender target = 342 ActivityManagerNative.getDefault().getIntentSender( 343 ActivityManager.INTENT_SENDER_ACTIVITY, packageName, 344 null, null, requestCode, new Intent[] { intent }, 345 resolvedType != null ? new String[] { resolvedType } : null, 346 flags, options, UserHandle.myUserId()); 347 return target != null ? new PendingIntent(target) : null; 348 } catch (RemoteException e) { 349 } 350 return null; 351 } 352 353 /** 354 * @hide 355 * Note that UserHandle.CURRENT will be interpreted at the time the 356 * activity is started, not when the pending intent is created. 357 */ getActivityAsUser(Context context, int requestCode, @NonNull Intent intent, int flags, Bundle options, UserHandle user)358 public static PendingIntent getActivityAsUser(Context context, int requestCode, 359 @NonNull Intent intent, int flags, Bundle options, UserHandle user) { 360 String packageName = context.getPackageName(); 361 String resolvedType = intent != null ? intent.resolveTypeIfNeeded( 362 context.getContentResolver()) : null; 363 try { 364 intent.migrateExtraStreamToClipData(); 365 intent.prepareToLeaveProcess(context); 366 IIntentSender target = 367 ActivityManagerNative.getDefault().getIntentSender( 368 ActivityManager.INTENT_SENDER_ACTIVITY, packageName, 369 null, null, requestCode, new Intent[] { intent }, 370 resolvedType != null ? new String[] { resolvedType } : null, 371 flags, options, user.getIdentifier()); 372 return target != null ? new PendingIntent(target) : null; 373 } catch (RemoteException e) { 374 } 375 return null; 376 } 377 378 /** 379 * Like {@link #getActivity(Context, int, Intent, int)}, but allows an 380 * array of Intents to be supplied. The last Intent in the array is 381 * taken as the primary key for the PendingIntent, like the single Intent 382 * given to {@link #getActivity(Context, int, Intent, int)}. Upon sending 383 * the resulting PendingIntent, all of the Intents are started in the same 384 * way as they would be by passing them to {@link Context#startActivities(Intent[])}. 385 * 386 * <p class="note"> 387 * The <em>first</em> intent in the array will be started outside of the context of an 388 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 389 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. (Activities after 390 * the first in the array are started in the context of the previous activity 391 * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.) 392 * </p> 393 * 394 * <p class="note"> 395 * The <em>last</em> intent in the array represents the key for the 396 * PendingIntent. In other words, it is the significant element for matching 397 * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)}, 398 * its content will be the subject of replacement by 399 * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc. 400 * This is because it is the most specific of the supplied intents, and the 401 * UI the user actually sees when the intents are started. 402 * </p> 403 * 404 * <p class="note">For security reasons, the {@link android.content.Intent} objects 405 * you supply here should almost always be <em>explicit intents</em>, 406 * that is specify an explicit component to be delivered to through 407 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 408 * 409 * @param context The Context in which this PendingIntent should start 410 * the activity. 411 * @param requestCode Private request code for the sender 412 * @param intents Array of Intents of the activities to be launched. 413 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 414 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 415 * or any of the flags as supported by 416 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 417 * of the intent that can be supplied when the actual send happens. 418 * 419 * @return Returns an existing or new PendingIntent matching the given 420 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 421 * supplied. 422 */ getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags)423 public static PendingIntent getActivities(Context context, int requestCode, 424 @NonNull Intent[] intents, @Flags int flags) { 425 return getActivities(context, requestCode, intents, flags, null); 426 } 427 428 /** 429 * Like {@link #getActivity(Context, int, Intent, int)}, but allows an 430 * array of Intents to be supplied. The last Intent in the array is 431 * taken as the primary key for the PendingIntent, like the single Intent 432 * given to {@link #getActivity(Context, int, Intent, int)}. Upon sending 433 * the resulting PendingIntent, all of the Intents are started in the same 434 * way as they would be by passing them to {@link Context#startActivities(Intent[])}. 435 * 436 * <p class="note"> 437 * The <em>first</em> intent in the array will be started outside of the context of an 438 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 439 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. (Activities after 440 * the first in the array are started in the context of the previous activity 441 * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.) 442 * </p> 443 * 444 * <p class="note"> 445 * The <em>last</em> intent in the array represents the key for the 446 * PendingIntent. In other words, it is the significant element for matching 447 * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)}, 448 * its content will be the subject of replacement by 449 * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc. 450 * This is because it is the most specific of the supplied intents, and the 451 * UI the user actually sees when the intents are started. 452 * </p> 453 * 454 * <p class="note">For security reasons, the {@link android.content.Intent} objects 455 * you supply here should almost always be <em>explicit intents</em>, 456 * that is specify an explicit component to be delivered to through 457 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 458 * 459 * @param context The Context in which this PendingIntent should start 460 * the activity. 461 * @param requestCode Private request code for the sender 462 * @param intents Array of Intents of the activities to be launched. 463 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 464 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 465 * {@link #FLAG_IMMUTABLE} or any of the flags as supported by 466 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 467 * of the intent that can be supplied when the actual send happens. 468 * 469 * @return Returns an existing or new PendingIntent matching the given 470 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 471 * supplied. 472 */ getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options)473 public static PendingIntent getActivities(Context context, int requestCode, 474 @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) { 475 String packageName = context.getPackageName(); 476 String[] resolvedTypes = new String[intents.length]; 477 for (int i=0; i<intents.length; i++) { 478 intents[i].migrateExtraStreamToClipData(); 479 intents[i].prepareToLeaveProcess(context); 480 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver()); 481 } 482 try { 483 IIntentSender target = 484 ActivityManagerNative.getDefault().getIntentSender( 485 ActivityManager.INTENT_SENDER_ACTIVITY, packageName, 486 null, null, requestCode, intents, resolvedTypes, flags, options, 487 UserHandle.myUserId()); 488 return target != null ? new PendingIntent(target) : null; 489 } catch (RemoteException e) { 490 } 491 return null; 492 } 493 494 /** 495 * @hide 496 * Note that UserHandle.CURRENT will be interpreted at the time the 497 * activity is started, not when the pending intent is created. 498 */ getActivitiesAsUser(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user)499 public static PendingIntent getActivitiesAsUser(Context context, int requestCode, 500 @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) { 501 String packageName = context.getPackageName(); 502 String[] resolvedTypes = new String[intents.length]; 503 for (int i=0; i<intents.length; i++) { 504 intents[i].migrateExtraStreamToClipData(); 505 intents[i].prepareToLeaveProcess(context); 506 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver()); 507 } 508 try { 509 IIntentSender target = 510 ActivityManagerNative.getDefault().getIntentSender( 511 ActivityManager.INTENT_SENDER_ACTIVITY, packageName, 512 null, null, requestCode, intents, resolvedTypes, 513 flags, options, user.getIdentifier()); 514 return target != null ? new PendingIntent(target) : null; 515 } catch (RemoteException e) { 516 } 517 return null; 518 } 519 520 /** 521 * Retrieve a PendingIntent that will perform a broadcast, like calling 522 * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}. 523 * 524 * <p class="note">For security reasons, the {@link android.content.Intent} 525 * you supply here should almost always be an <em>explicit intent</em>, 526 * that is specify an explicit component to be delivered to through 527 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 528 * 529 * @param context The Context in which this PendingIntent should perform 530 * the broadcast. 531 * @param requestCode Private request code for the sender 532 * @param intent The Intent to be broadcast. 533 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 534 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 535 * {@link #FLAG_IMMUTABLE} or any of the flags as supported by 536 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 537 * of the intent that can be supplied when the actual send happens. 538 * 539 * @return Returns an existing or new PendingIntent matching the given 540 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 541 * supplied. 542 */ getBroadcast(Context context, int requestCode, Intent intent, @Flags int flags)543 public static PendingIntent getBroadcast(Context context, int requestCode, 544 Intent intent, @Flags int flags) { 545 return getBroadcastAsUser(context, requestCode, intent, flags, 546 new UserHandle(UserHandle.myUserId())); 547 } 548 549 /** 550 * @hide 551 * Note that UserHandle.CURRENT will be interpreted at the time the 552 * broadcast is sent, not when the pending intent is created. 553 */ getBroadcastAsUser(Context context, int requestCode, Intent intent, int flags, UserHandle userHandle)554 public static PendingIntent getBroadcastAsUser(Context context, int requestCode, 555 Intent intent, int flags, UserHandle userHandle) { 556 String packageName = context.getPackageName(); 557 String resolvedType = intent != null ? intent.resolveTypeIfNeeded( 558 context.getContentResolver()) : null; 559 try { 560 intent.prepareToLeaveProcess(context); 561 IIntentSender target = 562 ActivityManagerNative.getDefault().getIntentSender( 563 ActivityManager.INTENT_SENDER_BROADCAST, packageName, 564 null, null, requestCode, new Intent[] { intent }, 565 resolvedType != null ? new String[] { resolvedType } : null, 566 flags, null, userHandle.getIdentifier()); 567 return target != null ? new PendingIntent(target) : null; 568 } catch (RemoteException e) { 569 } 570 return null; 571 } 572 573 /** 574 * Retrieve a PendingIntent that will start a service, like calling 575 * {@link Context#startService Context.startService()}. The start 576 * arguments given to the service will come from the extras of the Intent. 577 * 578 * <p class="note">For security reasons, the {@link android.content.Intent} 579 * you supply here should almost always be an <em>explicit intent</em>, 580 * that is specify an explicit component to be delivered to through 581 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 582 * 583 * @param context The Context in which this PendingIntent should start 584 * the service. 585 * @param requestCode Private request code for the sender 586 * @param intent An Intent describing the service to be started. 587 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 588 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 589 * {@link #FLAG_IMMUTABLE} or any of the flags as supported by 590 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 591 * of the intent that can be supplied when the actual send happens. 592 * 593 * @return Returns an existing or new PendingIntent matching the given 594 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 595 * supplied. 596 */ getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)597 public static PendingIntent getService(Context context, int requestCode, 598 @NonNull Intent intent, @Flags int flags) { 599 String packageName = context.getPackageName(); 600 String resolvedType = intent != null ? intent.resolveTypeIfNeeded( 601 context.getContentResolver()) : null; 602 try { 603 intent.prepareToLeaveProcess(context); 604 IIntentSender target = 605 ActivityManagerNative.getDefault().getIntentSender( 606 ActivityManager.INTENT_SENDER_SERVICE, packageName, 607 null, null, requestCode, new Intent[] { intent }, 608 resolvedType != null ? new String[] { resolvedType } : null, 609 flags, null, UserHandle.myUserId()); 610 return target != null ? new PendingIntent(target) : null; 611 } catch (RemoteException e) { 612 } 613 return null; 614 } 615 616 /** 617 * Retrieve a IntentSender object that wraps the existing sender of the PendingIntent 618 * 619 * @return Returns a IntentSender object that wraps the sender of PendingIntent 620 * 621 */ getIntentSender()622 public IntentSender getIntentSender() { 623 return new IntentSender(mTarget); 624 } 625 626 /** 627 * Cancel a currently active PendingIntent. Only the original application 628 * owning a PendingIntent can cancel it. 629 */ cancel()630 public void cancel() { 631 try { 632 ActivityManagerNative.getDefault().cancelIntentSender(mTarget); 633 } catch (RemoteException e) { 634 } 635 } 636 637 /** 638 * Perform the operation associated with this PendingIntent. 639 * 640 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) 641 * 642 * @throws CanceledException Throws CanceledException if the PendingIntent 643 * is no longer allowing more intents to be sent through it. 644 */ send()645 public void send() throws CanceledException { 646 send(null, 0, null, null, null, null, null); 647 } 648 649 /** 650 * Perform the operation associated with this PendingIntent. 651 * 652 * @param code Result code to supply back to the PendingIntent's target. 653 * 654 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) 655 * 656 * @throws CanceledException Throws CanceledException if the PendingIntent 657 * is no longer allowing more intents to be sent through it. 658 */ send(int code)659 public void send(int code) throws CanceledException { 660 send(null, code, null, null, null, null, null); 661 } 662 663 /** 664 * Perform the operation associated with this PendingIntent, allowing the 665 * caller to specify information about the Intent to use. 666 * 667 * @param context The Context of the caller. 668 * @param code Result code to supply back to the PendingIntent's target. 669 * @param intent Additional Intent data. See {@link Intent#fillIn 670 * Intent.fillIn()} for information on how this is applied to the 671 * original Intent. If flag {@link #FLAG_IMMUTABLE} was set when this 672 * pending intent was created, this argument will be ignored. 673 * 674 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) 675 * 676 * @throws CanceledException Throws CanceledException if the PendingIntent 677 * is no longer allowing more intents to be sent through it. 678 */ send(Context context, int code, @Nullable Intent intent)679 public void send(Context context, int code, @Nullable Intent intent) 680 throws CanceledException { 681 send(context, code, intent, null, null, null, null); 682 } 683 684 /** 685 * Perform the operation associated with this PendingIntent, allowing the 686 * caller to be notified when the send has completed. 687 * 688 * @param code Result code to supply back to the PendingIntent's target. 689 * @param onFinished The object to call back on when the send has 690 * completed, or null for no callback. 691 * @param handler Handler identifying the thread on which the callback 692 * should happen. If null, the callback will happen from the thread 693 * pool of the process. 694 * 695 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) 696 * 697 * @throws CanceledException Throws CanceledException if the PendingIntent 698 * is no longer allowing more intents to be sent through it. 699 */ send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)700 public void send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler) 701 throws CanceledException { 702 send(null, code, null, onFinished, handler, null, null); 703 } 704 705 /** 706 * Perform the operation associated with this PendingIntent, allowing the 707 * caller to specify information about the Intent to use and be notified 708 * when the send has completed. 709 * 710 * <p>For the intent parameter, a PendingIntent 711 * often has restrictions on which fields can be supplied here, based on 712 * how the PendingIntent was retrieved in {@link #getActivity}, 713 * {@link #getBroadcast}, or {@link #getService}. 714 * 715 * @param context The Context of the caller. This may be null if 716 * <var>intent</var> is also null. 717 * @param code Result code to supply back to the PendingIntent's target. 718 * @param intent Additional Intent data. See {@link Intent#fillIn 719 * Intent.fillIn()} for information on how this is applied to the 720 * original Intent. Use null to not modify the original Intent. 721 * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was 722 * created, this argument will be ignored. 723 * @param onFinished The object to call back on when the send has 724 * completed, or null for no callback. 725 * @param handler Handler identifying the thread on which the callback 726 * should happen. If null, the callback will happen from the thread 727 * pool of the process. 728 * 729 * @see #send() 730 * @see #send(int) 731 * @see #send(Context, int, Intent) 732 * @see #send(int, android.app.PendingIntent.OnFinished, Handler) 733 * @see #send(Context, int, Intent, OnFinished, Handler, String) 734 * 735 * @throws CanceledException Throws CanceledException if the PendingIntent 736 * is no longer allowing more intents to be sent through it. 737 */ send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler)738 public void send(Context context, int code, @Nullable Intent intent, 739 @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException { 740 send(context, code, intent, onFinished, handler, null, null); 741 } 742 743 /** 744 * Perform the operation associated with this PendingIntent, allowing the 745 * caller to specify information about the Intent to use and be notified 746 * when the send has completed. 747 * 748 * <p>For the intent parameter, a PendingIntent 749 * often has restrictions on which fields can be supplied here, based on 750 * how the PendingIntent was retrieved in {@link #getActivity}, 751 * {@link #getBroadcast}, or {@link #getService}. 752 * 753 * @param context The Context of the caller. This may be null if 754 * <var>intent</var> is also null. 755 * @param code Result code to supply back to the PendingIntent's target. 756 * @param intent Additional Intent data. See {@link Intent#fillIn 757 * Intent.fillIn()} for information on how this is applied to the 758 * original Intent. Use null to not modify the original Intent. 759 * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was 760 * created, this argument will be ignored. 761 * @param onFinished The object to call back on when the send has 762 * completed, or null for no callback. 763 * @param handler Handler identifying the thread on which the callback 764 * should happen. If null, the callback will happen from the thread 765 * pool of the process. 766 * @param requiredPermission Name of permission that a recipient of the PendingIntent 767 * is required to hold. This is only valid for broadcast intents, and 768 * corresponds to the permission argument in 769 * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}. 770 * If null, no permission is required. 771 * 772 * @see #send() 773 * @see #send(int) 774 * @see #send(Context, int, Intent) 775 * @see #send(int, android.app.PendingIntent.OnFinished, Handler) 776 * @see #send(Context, int, Intent, OnFinished, Handler) 777 * 778 * @throws CanceledException Throws CanceledException if the PendingIntent 779 * is no longer allowing more intents to be sent through it. 780 */ send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission)781 public void send(Context context, int code, @Nullable Intent intent, 782 @Nullable OnFinished onFinished, @Nullable Handler handler, 783 @Nullable String requiredPermission) 784 throws CanceledException { 785 send(context, code, intent, onFinished, handler, requiredPermission, null); 786 } 787 788 /** 789 * Perform the operation associated with this PendingIntent, allowing the 790 * caller to specify information about the Intent to use and be notified 791 * when the send has completed. 792 * 793 * <p>For the intent parameter, a PendingIntent 794 * often has restrictions on which fields can be supplied here, based on 795 * how the PendingIntent was retrieved in {@link #getActivity}, 796 * {@link #getBroadcast}, or {@link #getService}. 797 * 798 * @param context The Context of the caller. This may be null if 799 * <var>intent</var> is also null. 800 * @param code Result code to supply back to the PendingIntent's target. 801 * @param intent Additional Intent data. See {@link Intent#fillIn 802 * Intent.fillIn()} for information on how this is applied to the 803 * original Intent. Use null to not modify the original Intent. 804 * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was 805 * created, this argument will be ignored. 806 * @param onFinished The object to call back on when the send has 807 * completed, or null for no callback. 808 * @param handler Handler identifying the thread on which the callback 809 * should happen. If null, the callback will happen from the thread 810 * pool of the process. 811 * @param requiredPermission Name of permission that a recipient of the PendingIntent 812 * is required to hold. This is only valid for broadcast intents, and 813 * corresponds to the permission argument in 814 * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}. 815 * If null, no permission is required. 816 * @param options Additional options the caller would like to provide to modify the sending 817 * behavior. May be built from an {@link ActivityOptions} to apply to an activity start. 818 * 819 * @see #send() 820 * @see #send(int) 821 * @see #send(Context, int, Intent) 822 * @see #send(int, android.app.PendingIntent.OnFinished, Handler) 823 * @see #send(Context, int, Intent, OnFinished, Handler) 824 * 825 * @throws CanceledException Throws CanceledException if the PendingIntent 826 * is no longer allowing more intents to be sent through it. 827 */ send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission, @Nullable Bundle options)828 public void send(Context context, int code, @Nullable Intent intent, 829 @Nullable OnFinished onFinished, @Nullable Handler handler, 830 @Nullable String requiredPermission, @Nullable Bundle options) 831 throws CanceledException { 832 try { 833 String resolvedType = intent != null ? 834 intent.resolveTypeIfNeeded(context.getContentResolver()) 835 : null; 836 int res = ActivityManagerNative.getDefault().sendIntentSender( 837 mTarget, code, intent, resolvedType, 838 onFinished != null 839 ? new FinishedDispatcher(this, onFinished, handler) 840 : null, 841 requiredPermission, options); 842 if (res < 0) { 843 throw new CanceledException(); 844 } 845 } catch (RemoteException e) { 846 throw new CanceledException(e); 847 } 848 } 849 850 /** 851 * @deprecated Renamed to {@link #getCreatorPackage()}. 852 */ 853 @Deprecated getTargetPackage()854 public String getTargetPackage() { 855 try { 856 return ActivityManagerNative.getDefault() 857 .getPackageForIntentSender(mTarget); 858 } catch (RemoteException e) { 859 // Should never happen. 860 return null; 861 } 862 } 863 864 /** 865 * Return the package name of the application that created this 866 * PendingIntent, that is the identity under which you will actually be 867 * sending the Intent. The returned string is supplied by the system, so 868 * that an application can not spoof its package. 869 * 870 * <p class="note">Be careful about how you use this. All this tells you is 871 * who created the PendingIntent. It does <strong>not</strong> tell you who 872 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be 873 * passed between applications, so the PendingIntent you receive from an application 874 * could actually be one it received from another application, meaning the result 875 * you get here will identify the original application. Because of this, you should 876 * only use this information to identify who you expect to be interacting with 877 * through a {@link #send} call, not who gave you the PendingIntent.</p> 878 * 879 * @return The package name of the PendingIntent, or null if there is 880 * none associated with it. 881 */ 882 @Nullable getCreatorPackage()883 public String getCreatorPackage() { 884 try { 885 return ActivityManagerNative.getDefault() 886 .getPackageForIntentSender(mTarget); 887 } catch (RemoteException e) { 888 // Should never happen. 889 return null; 890 } 891 } 892 893 /** 894 * Return the uid of the application that created this 895 * PendingIntent, that is the identity under which you will actually be 896 * sending the Intent. The returned integer is supplied by the system, so 897 * that an application can not spoof its uid. 898 * 899 * <p class="note">Be careful about how you use this. All this tells you is 900 * who created the PendingIntent. It does <strong>not</strong> tell you who 901 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be 902 * passed between applications, so the PendingIntent you receive from an application 903 * could actually be one it received from another application, meaning the result 904 * you get here will identify the original application. Because of this, you should 905 * only use this information to identify who you expect to be interacting with 906 * through a {@link #send} call, not who gave you the PendingIntent.</p> 907 * 908 * @return The uid of the PendingIntent, or -1 if there is 909 * none associated with it. 910 */ getCreatorUid()911 public int getCreatorUid() { 912 try { 913 return ActivityManagerNative.getDefault() 914 .getUidForIntentSender(mTarget); 915 } catch (RemoteException e) { 916 // Should never happen. 917 return -1; 918 } 919 } 920 921 /** 922 * Return the user handle of the application that created this 923 * PendingIntent, that is the user under which you will actually be 924 * sending the Intent. The returned UserHandle is supplied by the system, so 925 * that an application can not spoof its user. See 926 * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for 927 * more explanation of user handles. 928 * 929 * <p class="note">Be careful about how you use this. All this tells you is 930 * who created the PendingIntent. It does <strong>not</strong> tell you who 931 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be 932 * passed between applications, so the PendingIntent you receive from an application 933 * could actually be one it received from another application, meaning the result 934 * you get here will identify the original application. Because of this, you should 935 * only use this information to identify who you expect to be interacting with 936 * through a {@link #send} call, not who gave you the PendingIntent.</p> 937 * 938 * @return The user handle of the PendingIntent, or null if there is 939 * none associated with it. 940 */ 941 @Nullable getCreatorUserHandle()942 public UserHandle getCreatorUserHandle() { 943 try { 944 int uid = ActivityManagerNative.getDefault() 945 .getUidForIntentSender(mTarget); 946 return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null; 947 } catch (RemoteException e) { 948 // Should never happen. 949 return null; 950 } 951 } 952 953 /** 954 * @hide 955 * Check to verify that this PendingIntent targets a specific package. 956 */ isTargetedToPackage()957 public boolean isTargetedToPackage() { 958 try { 959 return ActivityManagerNative.getDefault() 960 .isIntentSenderTargetedToPackage(mTarget); 961 } catch (RemoteException e) { 962 // Should never happen. 963 return false; 964 } 965 } 966 967 /** 968 * @hide 969 * Check whether this PendingIntent will launch an Activity. 970 */ isActivity()971 public boolean isActivity() { 972 try { 973 return ActivityManagerNative.getDefault() 974 .isIntentSenderAnActivity(mTarget); 975 } catch (RemoteException e) { 976 // Should never happen. 977 return false; 978 } 979 } 980 981 /** 982 * @hide 983 * Return the Intent of this PendingIntent. 984 */ getIntent()985 public Intent getIntent() { 986 try { 987 return ActivityManagerNative.getDefault() 988 .getIntentForIntentSender(mTarget); 989 } catch (RemoteException e) { 990 // Should never happen. 991 return null; 992 } 993 } 994 995 /** 996 * @hide 997 * Return descriptive tag for this PendingIntent. 998 */ getTag(String prefix)999 public String getTag(String prefix) { 1000 try { 1001 return ActivityManagerNative.getDefault() 1002 .getTagForIntentSender(mTarget, prefix); 1003 } catch (RemoteException e) { 1004 // Should never happen. 1005 return null; 1006 } 1007 } 1008 1009 /** 1010 * Comparison operator on two PendingIntent objects, such that true 1011 * is returned then they both represent the same operation from the 1012 * same package. This allows you to use {@link #getActivity}, 1013 * {@link #getBroadcast}, or {@link #getService} multiple times (even 1014 * across a process being killed), resulting in different PendingIntent 1015 * objects but whose equals() method identifies them as being the same 1016 * operation. 1017 */ 1018 @Override equals(Object otherObj)1019 public boolean equals(Object otherObj) { 1020 if (otherObj instanceof PendingIntent) { 1021 return mTarget.asBinder().equals(((PendingIntent)otherObj) 1022 .mTarget.asBinder()); 1023 } 1024 return false; 1025 } 1026 1027 @Override hashCode()1028 public int hashCode() { 1029 return mTarget.asBinder().hashCode(); 1030 } 1031 1032 @Override toString()1033 public String toString() { 1034 StringBuilder sb = new StringBuilder(128); 1035 sb.append("PendingIntent{"); 1036 sb.append(Integer.toHexString(System.identityHashCode(this))); 1037 sb.append(": "); 1038 sb.append(mTarget != null ? mTarget.asBinder() : null); 1039 sb.append('}'); 1040 return sb.toString(); 1041 } 1042 describeContents()1043 public int describeContents() { 1044 return 0; 1045 } 1046 writeToParcel(Parcel out, int flags)1047 public void writeToParcel(Parcel out, int flags) { 1048 out.writeStrongBinder(mTarget.asBinder()); 1049 OnMarshaledListener listener = sOnMarshaledListener.get(); 1050 if (listener != null) { 1051 listener.onMarshaled(this, out, flags); 1052 } 1053 1054 } 1055 1056 public static final Parcelable.Creator<PendingIntent> CREATOR 1057 = new Parcelable.Creator<PendingIntent>() { 1058 public PendingIntent createFromParcel(Parcel in) { 1059 IBinder target = in.readStrongBinder(); 1060 return target != null ? new PendingIntent(target) : null; 1061 } 1062 1063 public PendingIntent[] newArray(int size) { 1064 return new PendingIntent[size]; 1065 } 1066 }; 1067 1068 /** 1069 * Convenience function for writing either a PendingIntent or null pointer to 1070 * a Parcel. You must use this with {@link #readPendingIntentOrNullFromParcel} 1071 * for later reading it. 1072 * 1073 * @param sender The PendingIntent to write, or null. 1074 * @param out Where to write the PendingIntent. 1075 */ writePendingIntentOrNullToParcel(@ullable PendingIntent sender, @NonNull Parcel out)1076 public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender, 1077 @NonNull Parcel out) { 1078 out.writeStrongBinder(sender != null ? sender.mTarget.asBinder() 1079 : null); 1080 } 1081 1082 /** 1083 * Convenience function for reading either a Messenger or null pointer from 1084 * a Parcel. You must have previously written the Messenger with 1085 * {@link #writePendingIntentOrNullToParcel}. 1086 * 1087 * @param in The Parcel containing the written Messenger. 1088 * 1089 * @return Returns the Messenger read from the Parcel, or null if null had 1090 * been written. 1091 */ 1092 @Nullable readPendingIntentOrNullFromParcel(@onNull Parcel in)1093 public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) { 1094 IBinder b = in.readStrongBinder(); 1095 return b != null ? new PendingIntent(b) : null; 1096 } 1097 PendingIntent(IIntentSender target)1098 /*package*/ PendingIntent(IIntentSender target) { 1099 mTarget = target; 1100 } 1101 PendingIntent(IBinder target)1102 /*package*/ PendingIntent(IBinder target) { 1103 mTarget = IIntentSender.Stub.asInterface(target); 1104 } 1105 1106 /** @hide */ getTarget()1107 public IIntentSender getTarget() { 1108 return mTarget; 1109 } 1110 } 1111