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.IntDef; 20import android.annotation.NonNull; 21import android.annotation.Nullable; 22import android.content.Context; 23import android.content.Intent; 24import android.content.IIntentReceiver; 25import android.content.IIntentSender; 26import android.content.IntentSender; 27import android.os.Bundle; 28import android.os.Looper; 29import android.os.RemoteException; 30import android.os.Handler; 31import android.os.IBinder; 32import android.os.Parcel; 33import android.os.Parcelable; 34import android.os.Process; 35import android.os.UserHandle; 36import android.util.AndroidException; 37 38import java.lang.annotation.Retention; 39import 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 */ 94public 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 { 168 public CanceledException() { 169 } 170 171 public CanceledException(String name) { 172 super(name); 173 } 174 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 */ 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; 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 } 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 } 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 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 1028 public int hashCode() { 1029 return mTarget.asBinder().hashCode(); 1030 } 1031 1032 @Override 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 1043 public int describeContents() { 1044 return 0; 1045 } 1046 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 */ 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 1093 public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) { 1094 IBinder b = in.readStrongBinder(); 1095 return b != null ? new PendingIntent(b) : null; 1096 } 1097 1098 /*package*/ PendingIntent(IIntentSender target) { 1099 mTarget = target; 1100 } 1101 1102 /*package*/ PendingIntent(IBinder target) { 1103 mTarget = IIntentSender.Stub.asInterface(target); 1104 } 1105 1106 /** @hide */ 1107 public IIntentSender getTarget() { 1108 return mTarget; 1109 } 1110} 1111