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 { 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 * Retrieve a PendingIntent that will start a new activity, like calling 246 * {@link Context#startActivity(Intent) Context.startActivity(Intent)}. 247 * Note that the activity will be started outside of the context of an 248 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 249 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. 250 * 251 * <p class="note">For security reasons, the {@link android.content.Intent} 252 * you supply here should almost always be an <em>explicit intent</em>, 253 * that is specify an explicit component to be delivered to through 254 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 255 * 256 * @param context The Context in which this PendingIntent should start 257 * the activity. 258 * @param requestCode Private request code for the sender 259 * @param intent Intent of the activity to be launched. 260 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 261 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 262 * or any of the flags as supported by 263 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 264 * of the intent that can be supplied when the actual send happens. 265 * 266 * @return Returns an existing or new PendingIntent matching the given 267 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 268 * supplied. 269 */ 270 public static PendingIntent getActivity(Context context, int requestCode, 271 Intent intent, @Flags int flags) { 272 return getActivity(context, requestCode, intent, flags, null); 273 } 274 275 /** 276 * Retrieve a PendingIntent that will start a new activity, like calling 277 * {@link Context#startActivity(Intent) Context.startActivity(Intent)}. 278 * Note that the activity will be started outside of the context of an 279 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 280 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. 281 * 282 * <p class="note">For security reasons, the {@link android.content.Intent} 283 * you supply here should almost always be an <em>explicit intent</em>, 284 * that is specify an explicit component to be delivered to through 285 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 286 * 287 * @param context The Context in which this PendingIntent should start 288 * the activity. 289 * @param requestCode Private request code for the sender 290 * @param intent Intent of the activity to be launched. 291 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 292 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 293 * or any of the flags as supported by 294 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 295 * of the intent that can be supplied when the actual send happens. 296 * @param options Additional options for how the Activity should be started. 297 * May be null if there are no options. 298 * 299 * @return Returns an existing or new PendingIntent matching the given 300 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 301 * supplied. 302 */ 303 public static PendingIntent getActivity(Context context, int requestCode, 304 @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) { 305 String packageName = context.getPackageName(); 306 String resolvedType = intent != null ? intent.resolveTypeIfNeeded( 307 context.getContentResolver()) : null; 308 try { 309 intent.migrateExtraStreamToClipData(); 310 intent.prepareToLeaveProcess(); 311 IIntentSender target = 312 ActivityManagerNative.getDefault().getIntentSender( 313 ActivityManager.INTENT_SENDER_ACTIVITY, packageName, 314 null, null, requestCode, new Intent[] { intent }, 315 resolvedType != null ? new String[] { resolvedType } : null, 316 flags, options, UserHandle.myUserId()); 317 return target != null ? new PendingIntent(target) : null; 318 } catch (RemoteException e) { 319 } 320 return null; 321 } 322 323 /** 324 * @hide 325 * Note that UserHandle.CURRENT will be interpreted at the time the 326 * activity is started, not when the pending intent is created. 327 */ 328 public static PendingIntent getActivityAsUser(Context context, int requestCode, 329 @NonNull Intent intent, int flags, Bundle options, UserHandle user) { 330 String packageName = context.getPackageName(); 331 String resolvedType = intent != null ? intent.resolveTypeIfNeeded( 332 context.getContentResolver()) : null; 333 try { 334 intent.migrateExtraStreamToClipData(); 335 intent.prepareToLeaveProcess(); 336 IIntentSender target = 337 ActivityManagerNative.getDefault().getIntentSender( 338 ActivityManager.INTENT_SENDER_ACTIVITY, packageName, 339 null, null, requestCode, new Intent[] { intent }, 340 resolvedType != null ? new String[] { resolvedType } : null, 341 flags, options, user.getIdentifier()); 342 return target != null ? new PendingIntent(target) : null; 343 } catch (RemoteException e) { 344 } 345 return null; 346 } 347 348 /** 349 * Like {@link #getActivity(Context, int, Intent, int)}, but allows an 350 * array of Intents to be supplied. The last Intent in the array is 351 * taken as the primary key for the PendingIntent, like the single Intent 352 * given to {@link #getActivity(Context, int, Intent, int)}. Upon sending 353 * the resulting PendingIntent, all of the Intents are started in the same 354 * way as they would be by passing them to {@link Context#startActivities(Intent[])}. 355 * 356 * <p class="note"> 357 * The <em>first</em> intent in the array will be started outside of the context of an 358 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 359 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. (Activities after 360 * the first in the array are started in the context of the previous activity 361 * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.) 362 * </p> 363 * 364 * <p class="note"> 365 * The <em>last</em> intent in the array represents the key for the 366 * PendingIntent. In other words, it is the significant element for matching 367 * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)}, 368 * its content will be the subject of replacement by 369 * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc. 370 * This is because it is the most specific of the supplied intents, and the 371 * UI the user actually sees when the intents are started. 372 * </p> 373 * 374 * <p class="note">For security reasons, the {@link android.content.Intent} objects 375 * you supply here should almost always be <em>explicit intents</em>, 376 * that is specify an explicit component to be delivered to through 377 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 378 * 379 * @param context The Context in which this PendingIntent should start 380 * the activity. 381 * @param requestCode Private request code for the sender 382 * @param intents Array of Intents of the activities to be launched. 383 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 384 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 385 * or any of the flags as supported by 386 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 387 * of the intent that can be supplied when the actual send happens. 388 * 389 * @return Returns an existing or new PendingIntent matching the given 390 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 391 * supplied. 392 */ 393 public static PendingIntent getActivities(Context context, int requestCode, 394 @NonNull Intent[] intents, @Flags int flags) { 395 return getActivities(context, requestCode, intents, flags, null); 396 } 397 398 /** 399 * Like {@link #getActivity(Context, int, Intent, int)}, but allows an 400 * array of Intents to be supplied. The last Intent in the array is 401 * taken as the primary key for the PendingIntent, like the single Intent 402 * given to {@link #getActivity(Context, int, Intent, int)}. Upon sending 403 * the resulting PendingIntent, all of the Intents are started in the same 404 * way as they would be by passing them to {@link Context#startActivities(Intent[])}. 405 * 406 * <p class="note"> 407 * The <em>first</em> intent in the array will be started outside of the context of an 408 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK 409 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. (Activities after 410 * the first in the array are started in the context of the previous activity 411 * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.) 412 * </p> 413 * 414 * <p class="note"> 415 * The <em>last</em> intent in the array represents the key for the 416 * PendingIntent. In other words, it is the significant element for matching 417 * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)}, 418 * its content will be the subject of replacement by 419 * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc. 420 * This is because it is the most specific of the supplied intents, and the 421 * UI the user actually sees when the intents are started. 422 * </p> 423 * 424 * <p class="note">For security reasons, the {@link android.content.Intent} objects 425 * you supply here should almost always be <em>explicit intents</em>, 426 * that is specify an explicit component to be delivered to through 427 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 428 * 429 * @param context The Context in which this PendingIntent should start 430 * the activity. 431 * @param requestCode Private request code for the sender 432 * @param intents Array of Intents of the activities to be launched. 433 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 434 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 435 * or any of the flags as supported by 436 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 437 * of the intent that can be supplied when the actual send happens. 438 * 439 * @return Returns an existing or new PendingIntent matching the given 440 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 441 * supplied. 442 */ 443 public static PendingIntent getActivities(Context context, int requestCode, 444 @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) { 445 String packageName = context.getPackageName(); 446 String[] resolvedTypes = new String[intents.length]; 447 for (int i=0; i<intents.length; i++) { 448 intents[i].migrateExtraStreamToClipData(); 449 intents[i].prepareToLeaveProcess(); 450 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver()); 451 } 452 try { 453 IIntentSender target = 454 ActivityManagerNative.getDefault().getIntentSender( 455 ActivityManager.INTENT_SENDER_ACTIVITY, packageName, 456 null, null, requestCode, intents, resolvedTypes, flags, options, 457 UserHandle.myUserId()); 458 return target != null ? new PendingIntent(target) : null; 459 } catch (RemoteException e) { 460 } 461 return null; 462 } 463 464 /** 465 * @hide 466 * Note that UserHandle.CURRENT will be interpreted at the time the 467 * activity is started, not when the pending intent is created. 468 */ 469 public static PendingIntent getActivitiesAsUser(Context context, int requestCode, 470 @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) { 471 String packageName = context.getPackageName(); 472 String[] resolvedTypes = new String[intents.length]; 473 for (int i=0; i<intents.length; i++) { 474 intents[i].migrateExtraStreamToClipData(); 475 intents[i].prepareToLeaveProcess(); 476 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver()); 477 } 478 try { 479 IIntentSender target = 480 ActivityManagerNative.getDefault().getIntentSender( 481 ActivityManager.INTENT_SENDER_ACTIVITY, packageName, 482 null, null, requestCode, intents, resolvedTypes, 483 flags, options, user.getIdentifier()); 484 return target != null ? new PendingIntent(target) : null; 485 } catch (RemoteException e) { 486 } 487 return null; 488 } 489 490 /** 491 * Retrieve a PendingIntent that will perform a broadcast, like calling 492 * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}. 493 * 494 * <p class="note">For security reasons, the {@link android.content.Intent} 495 * you supply here should almost always be an <em>explicit intent</em>, 496 * that is specify an explicit component to be delivered to through 497 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 498 * 499 * @param context The Context in which this PendingIntent should perform 500 * the broadcast. 501 * @param requestCode Private request code for the sender 502 * @param intent The Intent to be broadcast. 503 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 504 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 505 * or any of the flags as supported by 506 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 507 * of the intent that can be supplied when the actual send happens. 508 * 509 * @return Returns an existing or new PendingIntent matching the given 510 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 511 * supplied. 512 */ 513 public static PendingIntent getBroadcast(Context context, int requestCode, 514 Intent intent, @Flags int flags) { 515 return getBroadcastAsUser(context, requestCode, intent, flags, 516 new UserHandle(UserHandle.myUserId())); 517 } 518 519 /** 520 * @hide 521 * Note that UserHandle.CURRENT will be interpreted at the time the 522 * broadcast is sent, not when the pending intent is created. 523 */ 524 public static PendingIntent getBroadcastAsUser(Context context, int requestCode, 525 Intent intent, int flags, UserHandle userHandle) { 526 String packageName = context.getPackageName(); 527 String resolvedType = intent != null ? intent.resolveTypeIfNeeded( 528 context.getContentResolver()) : null; 529 try { 530 intent.prepareToLeaveProcess(); 531 IIntentSender target = 532 ActivityManagerNative.getDefault().getIntentSender( 533 ActivityManager.INTENT_SENDER_BROADCAST, packageName, 534 null, null, requestCode, new Intent[] { intent }, 535 resolvedType != null ? new String[] { resolvedType } : null, 536 flags, null, userHandle.getIdentifier()); 537 return target != null ? new PendingIntent(target) : null; 538 } catch (RemoteException e) { 539 } 540 return null; 541 } 542 543 /** 544 * Retrieve a PendingIntent that will start a service, like calling 545 * {@link Context#startService Context.startService()}. The start 546 * arguments given to the service will come from the extras of the Intent. 547 * 548 * <p class="note">For security reasons, the {@link android.content.Intent} 549 * you supply here should almost always be an <em>explicit intent</em>, 550 * that is specify an explicit component to be delivered to through 551 * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p> 552 * 553 * @param context The Context in which this PendingIntent should start 554 * the service. 555 * @param requestCode Private request code for the sender 556 * @param intent An Intent describing the service to be started. 557 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE}, 558 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT}, 559 * or any of the flags as supported by 560 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts 561 * of the intent that can be supplied when the actual send happens. 562 * 563 * @return Returns an existing or new PendingIntent matching the given 564 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been 565 * supplied. 566 */ 567 public static PendingIntent getService(Context context, int requestCode, 568 @NonNull Intent intent, @Flags int flags) { 569 String packageName = context.getPackageName(); 570 String resolvedType = intent != null ? intent.resolveTypeIfNeeded( 571 context.getContentResolver()) : null; 572 try { 573 intent.prepareToLeaveProcess(); 574 IIntentSender target = 575 ActivityManagerNative.getDefault().getIntentSender( 576 ActivityManager.INTENT_SENDER_SERVICE, packageName, 577 null, null, requestCode, new Intent[] { intent }, 578 resolvedType != null ? new String[] { resolvedType } : null, 579 flags, null, UserHandle.myUserId()); 580 return target != null ? new PendingIntent(target) : null; 581 } catch (RemoteException e) { 582 } 583 return null; 584 } 585 586 /** 587 * Retrieve a IntentSender object that wraps the existing sender of the PendingIntent 588 * 589 * @return Returns a IntentSender object that wraps the sender of PendingIntent 590 * 591 */ 592 public IntentSender getIntentSender() { 593 return new IntentSender(mTarget); 594 } 595 596 /** 597 * Cancel a currently active PendingIntent. Only the original application 598 * owning a PendingIntent can cancel it. 599 */ 600 public void cancel() { 601 try { 602 ActivityManagerNative.getDefault().cancelIntentSender(mTarget); 603 } catch (RemoteException e) { 604 } 605 } 606 607 /** 608 * Perform the operation associated with this PendingIntent. 609 * 610 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) 611 * 612 * @throws CanceledException Throws CanceledException if the PendingIntent 613 * is no longer allowing more intents to be sent through it. 614 */ 615 public void send() throws CanceledException { 616 send(null, 0, null, null, null, null, null); 617 } 618 619 /** 620 * Perform the operation associated with this PendingIntent. 621 * 622 * @param code Result code to supply back to the PendingIntent's target. 623 * 624 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) 625 * 626 * @throws CanceledException Throws CanceledException if the PendingIntent 627 * is no longer allowing more intents to be sent through it. 628 */ 629 public void send(int code) throws CanceledException { 630 send(null, code, null, null, null, null, null); 631 } 632 633 /** 634 * Perform the operation associated with this PendingIntent, allowing the 635 * caller to specify information about the Intent to use. 636 * 637 * @param context The Context of the caller. 638 * @param code Result code to supply back to the PendingIntent's target. 639 * @param intent Additional Intent data. See {@link Intent#fillIn 640 * Intent.fillIn()} for information on how this is applied to the 641 * original Intent. If flag {@link #FLAG_IMMUTABLE} was set when this 642 * pending intent was created, this argument will be ignored. 643 * 644 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) 645 * 646 * @throws CanceledException Throws CanceledException if the PendingIntent 647 * is no longer allowing more intents to be sent through it. 648 */ 649 public void send(Context context, int code, @Nullable Intent intent) 650 throws CanceledException { 651 send(context, code, intent, null, null, null, null); 652 } 653 654 /** 655 * Perform the operation associated with this PendingIntent, allowing the 656 * caller to be notified when the send has completed. 657 * 658 * @param code Result code to supply back to the PendingIntent's target. 659 * @param onFinished The object to call back on when the send has 660 * completed, or null for no callback. 661 * @param handler Handler identifying the thread on which the callback 662 * should happen. If null, the callback will happen from the thread 663 * pool of the process. 664 * 665 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) 666 * 667 * @throws CanceledException Throws CanceledException if the PendingIntent 668 * is no longer allowing more intents to be sent through it. 669 */ 670 public void send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler) 671 throws CanceledException { 672 send(null, code, null, onFinished, handler, null, null); 673 } 674 675 /** 676 * Perform the operation associated with this PendingIntent, allowing the 677 * caller to specify information about the Intent to use and be notified 678 * when the send has completed. 679 * 680 * <p>For the intent parameter, a PendingIntent 681 * often has restrictions on which fields can be supplied here, based on 682 * how the PendingIntent was retrieved in {@link #getActivity}, 683 * {@link #getBroadcast}, or {@link #getService}. 684 * 685 * @param context The Context of the caller. This may be null if 686 * <var>intent</var> is also null. 687 * @param code Result code to supply back to the PendingIntent's target. 688 * @param intent Additional Intent data. See {@link Intent#fillIn 689 * Intent.fillIn()} for information on how this is applied to the 690 * original Intent. Use null to not modify the original Intent. 691 * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was 692 * created, this argument will be ignored. 693 * @param onFinished The object to call back on when the send has 694 * completed, or null for no callback. 695 * @param handler Handler identifying the thread on which the callback 696 * should happen. If null, the callback will happen from the thread 697 * pool of the process. 698 * 699 * @see #send() 700 * @see #send(int) 701 * @see #send(Context, int, Intent) 702 * @see #send(int, android.app.PendingIntent.OnFinished, Handler) 703 * @see #send(Context, int, Intent, OnFinished, Handler, String) 704 * 705 * @throws CanceledException Throws CanceledException if the PendingIntent 706 * is no longer allowing more intents to be sent through it. 707 */ 708 public void send(Context context, int code, @Nullable Intent intent, 709 @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException { 710 send(context, code, intent, onFinished, handler, null, null); 711 } 712 713 /** 714 * Perform the operation associated with this PendingIntent, allowing the 715 * caller to specify information about the Intent to use and be notified 716 * when the send has completed. 717 * 718 * <p>For the intent parameter, a PendingIntent 719 * often has restrictions on which fields can be supplied here, based on 720 * how the PendingIntent was retrieved in {@link #getActivity}, 721 * {@link #getBroadcast}, or {@link #getService}. 722 * 723 * @param context The Context of the caller. This may be null if 724 * <var>intent</var> is also null. 725 * @param code Result code to supply back to the PendingIntent's target. 726 * @param intent Additional Intent data. See {@link Intent#fillIn 727 * Intent.fillIn()} for information on how this is applied to the 728 * original Intent. Use null to not modify the original Intent. 729 * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was 730 * created, this argument will be ignored. 731 * @param onFinished The object to call back on when the send has 732 * completed, or null for no callback. 733 * @param handler Handler identifying the thread on which the callback 734 * should happen. If null, the callback will happen from the thread 735 * pool of the process. 736 * @param requiredPermission Name of permission that a recipient of the PendingIntent 737 * is required to hold. This is only valid for broadcast intents, and 738 * corresponds to the permission argument in 739 * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}. 740 * If null, no permission is required. 741 * 742 * @see #send() 743 * @see #send(int) 744 * @see #send(Context, int, Intent) 745 * @see #send(int, android.app.PendingIntent.OnFinished, Handler) 746 * @see #send(Context, int, Intent, OnFinished, Handler) 747 * 748 * @throws CanceledException Throws CanceledException if the PendingIntent 749 * is no longer allowing more intents to be sent through it. 750 */ 751 public void send(Context context, int code, @Nullable Intent intent, 752 @Nullable OnFinished onFinished, @Nullable Handler handler, 753 @Nullable String requiredPermission) 754 throws CanceledException { 755 send(context, code, intent, onFinished, handler, requiredPermission, null); 756 } 757 758 /** 759 * Perform the operation associated with this PendingIntent, allowing the 760 * caller to specify information about the Intent to use and be notified 761 * when the send has completed. 762 * 763 * <p>For the intent parameter, a PendingIntent 764 * often has restrictions on which fields can be supplied here, based on 765 * how the PendingIntent was retrieved in {@link #getActivity}, 766 * {@link #getBroadcast}, or {@link #getService}. 767 * 768 * @param context The Context of the caller. This may be null if 769 * <var>intent</var> is also null. 770 * @param code Result code to supply back to the PendingIntent's target. 771 * @param intent Additional Intent data. See {@link Intent#fillIn 772 * Intent.fillIn()} for information on how this is applied to the 773 * original Intent. Use null to not modify the original Intent. 774 * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was 775 * created, this argument will be ignored. 776 * @param onFinished The object to call back on when the send has 777 * completed, or null for no callback. 778 * @param handler Handler identifying the thread on which the callback 779 * should happen. If null, the callback will happen from the thread 780 * pool of the process. 781 * @param requiredPermission Name of permission that a recipient of the PendingIntent 782 * is required to hold. This is only valid for broadcast intents, and 783 * corresponds to the permission argument in 784 * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}. 785 * If null, no permission is required. 786 * @param options Additional options the caller would like to provide to modify the sending 787 * behavior. May be built from an {@link ActivityOptions} to apply to an activity start. 788 * 789 * @see #send() 790 * @see #send(int) 791 * @see #send(Context, int, Intent) 792 * @see #send(int, android.app.PendingIntent.OnFinished, Handler) 793 * @see #send(Context, int, Intent, OnFinished, Handler) 794 * 795 * @throws CanceledException Throws CanceledException if the PendingIntent 796 * is no longer allowing more intents to be sent through it. 797 */ 798 public void send(Context context, int code, @Nullable Intent intent, 799 @Nullable OnFinished onFinished, @Nullable Handler handler, 800 @Nullable String requiredPermission, @Nullable Bundle options) 801 throws CanceledException { 802 try { 803 String resolvedType = intent != null ? 804 intent.resolveTypeIfNeeded(context.getContentResolver()) 805 : null; 806 int res = mTarget.send(code, intent, resolvedType, 807 onFinished != null 808 ? new FinishedDispatcher(this, onFinished, handler) 809 : null, 810 requiredPermission, options); 811 if (res < 0) { 812 throw new CanceledException(); 813 } 814 } catch (RemoteException e) { 815 throw new CanceledException(e); 816 } 817 } 818 819 /** 820 * @deprecated Renamed to {@link #getCreatorPackage()}. 821 */ 822 @Deprecated 823 public String getTargetPackage() { 824 try { 825 return ActivityManagerNative.getDefault() 826 .getPackageForIntentSender(mTarget); 827 } catch (RemoteException e) { 828 // Should never happen. 829 return null; 830 } 831 } 832 833 /** 834 * Return the package name of the application that created this 835 * PendingIntent, that is the identity under which you will actually be 836 * sending the Intent. The returned string is supplied by the system, so 837 * that an application can not spoof its package. 838 * 839 * <p class="note">Be careful about how you use this. All this tells you is 840 * who created the PendingIntent. It does <strong>not</strong> tell you who 841 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be 842 * passed between applications, so the PendingIntent you receive from an application 843 * could actually be one it received from another application, meaning the result 844 * you get here will identify the original application. Because of this, you should 845 * only use this information to identify who you expect to be interacting with 846 * through a {@link #send} call, not who gave you the PendingIntent.</p> 847 * 848 * @return The package name of the PendingIntent, or null if there is 849 * none associated with it. 850 */ 851 @Nullable 852 public String getCreatorPackage() { 853 try { 854 return ActivityManagerNative.getDefault() 855 .getPackageForIntentSender(mTarget); 856 } catch (RemoteException e) { 857 // Should never happen. 858 return null; 859 } 860 } 861 862 /** 863 * Return the uid of the application that created this 864 * PendingIntent, that is the identity under which you will actually be 865 * sending the Intent. The returned integer is supplied by the system, so 866 * that an application can not spoof its uid. 867 * 868 * <p class="note">Be careful about how you use this. All this tells you is 869 * who created the PendingIntent. It does <strong>not</strong> tell you who 870 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be 871 * passed between applications, so the PendingIntent you receive from an application 872 * could actually be one it received from another application, meaning the result 873 * you get here will identify the original application. Because of this, you should 874 * only use this information to identify who you expect to be interacting with 875 * through a {@link #send} call, not who gave you the PendingIntent.</p> 876 * 877 * @return The uid of the PendingIntent, or -1 if there is 878 * none associated with it. 879 */ 880 public int getCreatorUid() { 881 try { 882 return ActivityManagerNative.getDefault() 883 .getUidForIntentSender(mTarget); 884 } catch (RemoteException e) { 885 // Should never happen. 886 return -1; 887 } 888 } 889 890 /** 891 * Return the user handle of the application that created this 892 * PendingIntent, that is the user under which you will actually be 893 * sending the Intent. The returned UserHandle is supplied by the system, so 894 * that an application can not spoof its user. See 895 * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for 896 * more explanation of user handles. 897 * 898 * <p class="note">Be careful about how you use this. All this tells you is 899 * who created the PendingIntent. It does <strong>not</strong> tell you who 900 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be 901 * passed between applications, so the PendingIntent you receive from an application 902 * could actually be one it received from another application, meaning the result 903 * you get here will identify the original application. Because of this, you should 904 * only use this information to identify who you expect to be interacting with 905 * through a {@link #send} call, not who gave you the PendingIntent.</p> 906 * 907 * @return The user handle of the PendingIntent, or null if there is 908 * none associated with it. 909 */ 910 @Nullable 911 public UserHandle getCreatorUserHandle() { 912 try { 913 int uid = ActivityManagerNative.getDefault() 914 .getUidForIntentSender(mTarget); 915 return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null; 916 } catch (RemoteException e) { 917 // Should never happen. 918 return null; 919 } 920 } 921 922 /** 923 * @hide 924 * Check to verify that this PendingIntent targets a specific package. 925 */ 926 public boolean isTargetedToPackage() { 927 try { 928 return ActivityManagerNative.getDefault() 929 .isIntentSenderTargetedToPackage(mTarget); 930 } catch (RemoteException e) { 931 // Should never happen. 932 return false; 933 } 934 } 935 936 /** 937 * @hide 938 * Check whether this PendingIntent will launch an Activity. 939 */ 940 public boolean isActivity() { 941 try { 942 return ActivityManagerNative.getDefault() 943 .isIntentSenderAnActivity(mTarget); 944 } catch (RemoteException e) { 945 // Should never happen. 946 return false; 947 } 948 } 949 950 /** 951 * @hide 952 * Return the Intent of this PendingIntent. 953 */ 954 public Intent getIntent() { 955 try { 956 return ActivityManagerNative.getDefault() 957 .getIntentForIntentSender(mTarget); 958 } catch (RemoteException e) { 959 // Should never happen. 960 return null; 961 } 962 } 963 964 /** 965 * @hide 966 * Return descriptive tag for this PendingIntent. 967 */ 968 public String getTag(String prefix) { 969 try { 970 return ActivityManagerNative.getDefault() 971 .getTagForIntentSender(mTarget, prefix); 972 } catch (RemoteException e) { 973 // Should never happen. 974 return null; 975 } 976 } 977 978 /** 979 * Comparison operator on two PendingIntent objects, such that true 980 * is returned then they both represent the same operation from the 981 * same package. This allows you to use {@link #getActivity}, 982 * {@link #getBroadcast}, or {@link #getService} multiple times (even 983 * across a process being killed), resulting in different PendingIntent 984 * objects but whose equals() method identifies them as being the same 985 * operation. 986 */ 987 @Override 988 public boolean equals(Object otherObj) { 989 if (otherObj instanceof PendingIntent) { 990 return mTarget.asBinder().equals(((PendingIntent)otherObj) 991 .mTarget.asBinder()); 992 } 993 return false; 994 } 995 996 @Override 997 public int hashCode() { 998 return mTarget.asBinder().hashCode(); 999 } 1000 1001 @Override 1002 public String toString() { 1003 StringBuilder sb = new StringBuilder(128); 1004 sb.append("PendingIntent{"); 1005 sb.append(Integer.toHexString(System.identityHashCode(this))); 1006 sb.append(": "); 1007 sb.append(mTarget != null ? mTarget.asBinder() : null); 1008 sb.append('}'); 1009 return sb.toString(); 1010 } 1011 1012 public int describeContents() { 1013 return 0; 1014 } 1015 1016 public void writeToParcel(Parcel out, int flags) { 1017 out.writeStrongBinder(mTarget.asBinder()); 1018 } 1019 1020 public static final Parcelable.Creator<PendingIntent> CREATOR 1021 = new Parcelable.Creator<PendingIntent>() { 1022 public PendingIntent createFromParcel(Parcel in) { 1023 IBinder target = in.readStrongBinder(); 1024 return target != null ? new PendingIntent(target) : null; 1025 } 1026 1027 public PendingIntent[] newArray(int size) { 1028 return new PendingIntent[size]; 1029 } 1030 }; 1031 1032 /** 1033 * Convenience function for writing either a PendingIntent or null pointer to 1034 * a Parcel. You must use this with {@link #readPendingIntentOrNullFromParcel} 1035 * for later reading it. 1036 * 1037 * @param sender The PendingIntent to write, or null. 1038 * @param out Where to write the PendingIntent. 1039 */ 1040 public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender, 1041 @NonNull Parcel out) { 1042 out.writeStrongBinder(sender != null ? sender.mTarget.asBinder() 1043 : null); 1044 } 1045 1046 /** 1047 * Convenience function for reading either a Messenger or null pointer from 1048 * a Parcel. You must have previously written the Messenger with 1049 * {@link #writePendingIntentOrNullToParcel}. 1050 * 1051 * @param in The Parcel containing the written Messenger. 1052 * 1053 * @return Returns the Messenger read from the Parcel, or null if null had 1054 * been written. 1055 */ 1056 @Nullable 1057 public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) { 1058 IBinder b = in.readStrongBinder(); 1059 return b != null ? new PendingIntent(b) : null; 1060 } 1061 1062 /*package*/ PendingIntent(IIntentSender target) { 1063 mTarget = target; 1064 } 1065 1066 /*package*/ PendingIntent(IBinder target) { 1067 mTarget = IIntentSender.Stub.asInterface(target); 1068 } 1069 1070 /** @hide */ 1071 public IIntentSender getTarget() { 1072 return mTarget; 1073 } 1074 } 1075