1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IIntentReceiver; 25 import android.content.IIntentSender; 26 import android.content.IntentSender; 27 import android.os.Bundle; 28 import android.os.Looper; 29 import android.os.RemoteException; 30 import android.os.Handler; 31 import android.os.IBinder; 32 import android.os.Parcel; 33 import android.os.Parcelable; 34 import android.os.Process; 35 import android.os.UserHandle; 36 import android.util.AndroidException; 37 38 import java.lang.annotation.Retention; 39 import java.lang.annotation.RetentionPolicy; 40 41 /** 42 * A description of an Intent and target action to perform with it. Instances 43 * of this class are created with {@link #getActivity}, {@link #getActivities}, 44 * {@link #getBroadcast}, and {@link #getService}; the returned object can be 45 * handed to other applications so that they can perform the action you 46 * described on your behalf at a later time. 47 * 48 * <p>By giving a PendingIntent to another application, 49 * you are granting it the right to perform the operation you have specified 50 * as if the other application was yourself (with the same permissions and 51 * identity). As such, you should be careful about how you build the PendingIntent: 52 * almost always, for example, the base Intent you supply should have the component 53 * name explicitly set to one of your own components, to ensure it is ultimately 54 * sent there and nowhere else. 55 * 56 * <p>A PendingIntent itself is simply a reference to a token maintained by 57 * the system describing the original data used to retrieve it. This means 58 * that, even if its owning application's process is killed, the 59 * PendingIntent itself will remain usable from other processes that 60 * have been given it. If the creating application later re-retrieves the 61 * same kind of PendingIntent (same operation, same Intent action, data, 62 * categories, and components, and same flags), it will receive a PendingIntent 63 * representing the same token if that is still valid, and can thus call 64 * {@link #cancel} to remove it. 65 * 66 * <p>Because of this behavior, it is important to know when two Intents 67 * are considered to be the same for purposes of retrieving a PendingIntent. 68 * A common mistake people make is to create multiple PendingIntent objects 69 * with Intents that only vary in their "extra" contents, expecting to get 70 * a different PendingIntent each time. This does <em>not</em> happen. The 71 * parts of the Intent that are used for matching are the same ones defined 72 * by {@link Intent#filterEquals(Intent) Intent.filterEquals}. If you use two 73 * Intent objects that are equivalent as per 74 * {@link Intent#filterEquals(Intent) Intent.filterEquals}, then you will get 75 * the same PendingIntent for both of them. 76 * 77 * <p>There are two typical ways to deal with this. 78 * 79 * <p>If you truly need multiple distinct PendingIntent objects active at 80 * the same time (such as to use as two notifications that are both shown 81 * at the same time), then you will need to ensure there is something that 82 * is different about them to associate them with different PendingIntents. 83 * This may be any of the Intent attributes considered by 84 * {@link Intent#filterEquals(Intent) Intent.filterEquals}, or different 85 * request code integers supplied to {@link #getActivity}, {@link #getActivities}, 86 * {@link #getBroadcast}, or {@link #getService}. 87 * 88 * <p>If you only need one PendingIntent active at a time for any of the 89 * Intents you will use, then you can alternatively use the flags 90 * {@link #FLAG_CANCEL_CURRENT} or {@link #FLAG_UPDATE_CURRENT} to either 91 * cancel or modify whatever current PendingIntent is associated with the 92 * Intent you are supplying. 93 */ 94 public final class PendingIntent implements Parcelable { 95 private final IIntentSender mTarget; 96 97 /** @hide */ 98 @IntDef(flag = true, 99 value = { 100 FLAG_ONE_SHOT, 101 FLAG_NO_CREATE, 102 FLAG_CANCEL_CURRENT, 103 FLAG_UPDATE_CURRENT, 104 105 Intent.FILL_IN_ACTION, 106 Intent.FILL_IN_DATA, 107 Intent.FILL_IN_CATEGORIES, 108 Intent.FILL_IN_COMPONENT, 109 Intent.FILL_IN_PACKAGE, 110 Intent.FILL_IN_SOURCE_BOUNDS, 111 Intent.FILL_IN_SELECTOR, 112 Intent.FILL_IN_CLIP_DATA 113 }) 114 @Retention(RetentionPolicy.SOURCE) 115 public @interface Flags {} 116 117 /** 118 * Flag indicating that this PendingIntent can be used only once. 119 * For use with {@link #getActivity}, {@link #getBroadcast}, and 120 * {@link #getService}. <p>If set, after 121 * {@link #send()} is called on it, it will be automatically 122 * canceled for you and any future attempt to send through it will fail. 123 */ 124 public static final int FLAG_ONE_SHOT = 1<<30; 125 /** 126 * Flag indicating that if the described PendingIntent does not 127 * already exist, then simply return null instead of creating it. 128 * For use with {@link #getActivity}, {@link #getBroadcast}, and 129 * {@link #getService}. 130 */ 131 public static final int FLAG_NO_CREATE = 1<<29; 132 /** 133 * Flag indicating that if the described PendingIntent already exists, 134 * the current one should be canceled before generating a new one. 135 * For use with {@link #getActivity}, {@link #getBroadcast}, and 136 * {@link #getService}. <p>You can use 137 * this to retrieve a new PendingIntent when you are only changing the 138 * extra data in the Intent; by canceling the previous pending intent, 139 * this ensures that only entities given the new data will be able to 140 * launch it. If this assurance is not an issue, consider 141 * {@link #FLAG_UPDATE_CURRENT}. 142 */ 143 public static final int FLAG_CANCEL_CURRENT = 1<<28; 144 /** 145 * Flag indicating that if the described PendingIntent already exists, 146 * then keep it but replace its extra data with what is in this new 147 * Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and 148 * {@link #getService}. <p>This can be used if you are creating intents where only the 149 * extras change, and don't care that any entities that received your 150 * previous PendingIntent will be able to launch it with your new 151 * extras even if they are not explicitly given to it. 152 */ 153 public static final int FLAG_UPDATE_CURRENT = 1<<27; 154 155 /** 156 * Flag indicating that the created PendingIntent should be immutable. 157 * This means that the additional intent argument passed to the send 158 * methods to fill in unpopulated properties of this intent will be 159 * ignored. 160 */ 161 public static final int FLAG_IMMUTABLE = 1<<26; 162 163 /** 164 * Exception thrown when trying to send through a PendingIntent that 165 * has been canceled or is otherwise no longer able to execute the request. 166 */ 167 public static class CanceledException extends AndroidException { CanceledException()168 public CanceledException() { 169 } 170 CanceledException(String name)171 public CanceledException(String name) { 172 super(name); 173 } 174 CanceledException(Exception cause)175 public CanceledException(Exception cause) { 176 super(cause); 177 } 178 } 179 180 /** 181 * Callback interface for discovering when a send operation has 182 * completed. Primarily for use with a PendingIntent that is 183 * performing a broadcast, this provides the same information as 184 * calling {@link Context#sendOrderedBroadcast(Intent, String, 185 * android.content.BroadcastReceiver, Handler, int, String, Bundle) 186 * Context.sendBroadcast()} with a final BroadcastReceiver. 187 */ 188 public interface OnFinished { 189 /** 190 * Called when a send operation as completed. 191 * 192 * @param pendingIntent The PendingIntent this operation was sent through. 193 * @param intent The original Intent that was sent. 194 * @param resultCode The final result code determined by the send. 195 * @param resultData The final data collected by a broadcast. 196 * @param resultExtras The final extras collected by a broadcast. 197 */ onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)198 void onSendFinished(PendingIntent pendingIntent, Intent intent, 199 int resultCode, String resultData, Bundle resultExtras); 200 } 201 202 private static class FinishedDispatcher extends IIntentReceiver.Stub 203 implements Runnable { 204 private final PendingIntent mPendingIntent; 205 private final OnFinished mWho; 206 private final Handler mHandler; 207 private Intent mIntent; 208 private int mResultCode; 209 private String mResultData; 210 private Bundle mResultExtras; 211 private static Handler sDefaultSystemHandler; FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler)212 FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler) { 213 mPendingIntent = pi; 214 mWho = who; 215 if (handler == null && ActivityThread.isSystem()) { 216 // We assign a default handler for the system process to avoid deadlocks when 217 // processing receivers in various components that hold global service locks. 218 if (sDefaultSystemHandler == null) { 219 sDefaultSystemHandler = new Handler(Looper.getMainLooper()); 220 } 221 mHandler = sDefaultSystemHandler; 222 } else { 223 mHandler = handler; 224 } 225 } performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean serialized, boolean sticky, int sendingUser)226 public void performReceive(Intent intent, int resultCode, String data, 227 Bundle extras, boolean serialized, boolean sticky, int sendingUser) { 228 mIntent = intent; 229 mResultCode = resultCode; 230 mResultData = data; 231 mResultExtras = extras; 232 if (mHandler == null) { 233 run(); 234 } else { 235 mHandler.post(this); 236 } 237 } run()238 public void run() { 239 mWho.onSendFinished(mPendingIntent, mIntent, mResultCode, 240 mResultData, mResultExtras); 241 } 242 } 243 244 /** 245 * 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 */ getActivity(Context context, int requestCode, Intent intent, @Flags int flags)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 */ getActivity(Context context, int requestCode, @NonNull Intent intent, @Flags int flags, @Nullable Bundle options)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 */ getActivityAsUser(Context context, int requestCode, @NonNull Intent intent, int flags, Bundle options, UserHandle user)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 */ getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags)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 */ getActivities(Context context, int requestCode, @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options)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 */ getActivitiesAsUser(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user)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 */ getBroadcast(Context context, int requestCode, Intent intent, @Flags int flags)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 */ getBroadcastAsUser(Context context, int requestCode, Intent intent, int flags, UserHandle userHandle)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 */ getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)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 */ getIntentSender()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 */ cancel()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 */ send()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 */ send(int code)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 */ send(Context context, int code, @Nullable Intent intent)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 */ send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler)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 */ send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler)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 */ send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission)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 */ send(Context context, int code, @Nullable Intent intent, @Nullable OnFinished onFinished, @Nullable Handler handler, @Nullable String requiredPermission, @Nullable Bundle options)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 getTargetPackage()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 getCreatorPackage()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 */ getCreatorUid()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 getCreatorUserHandle()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 */ isTargetedToPackage()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 */ isActivity()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 */ getIntent()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 */ getTag(String prefix)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 equals(Object otherObj)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 hashCode()997 public int hashCode() { 998 return mTarget.asBinder().hashCode(); 999 } 1000 1001 @Override toString()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 describeContents()1012 public int describeContents() { 1013 return 0; 1014 } 1015 writeToParcel(Parcel out, int flags)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 */ writePendingIntentOrNullToParcel(@ullable PendingIntent sender, @NonNull Parcel out)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 readPendingIntentOrNullFromParcel(@onNull Parcel in)1057 public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) { 1058 IBinder b = in.readStrongBinder(); 1059 return b != null ? new PendingIntent(b) : null; 1060 } 1061 PendingIntent(IIntentSender target)1062 /*package*/ PendingIntent(IIntentSender target) { 1063 mTarget = target; 1064 } 1065 PendingIntent(IBinder target)1066 /*package*/ PendingIntent(IBinder target) { 1067 mTarget = IIntentSender.Stub.asInterface(target); 1068 } 1069 1070 /** @hide */ getTarget()1071 public IIntentSender getTarget() { 1072 return mTarget; 1073 } 1074 } 1075