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