blob: f6e1f72dba29ea68f4a231885daf41b8981b3c4a [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import android.content.Context;
20import android.content.Intent;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070021import android.content.IIntentReceiver;
22import android.content.IIntentSender;
23import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.os.Bundle;
25import android.os.RemoteException;
26import android.os.Handler;
27import android.os.IBinder;
28import android.os.Parcel;
29import android.os.Parcelable;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070030import android.os.UserHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.util.AndroidException;
32
33/**
34 * A description of an Intent and target action to perform with it. Instances
Dianne Hackborn8832c182012-09-17 17:20:24 -070035 * of this class are created with {@link #getActivity}, {@link #getActivities},
36 * {@link #getBroadcast}, and {@link #getService}; the returned object can be
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037 * handed to other applications so that they can perform the action you
38 * described on your behalf at a later time.
39 *
40 * <p>By giving a PendingIntent to another application,
41 * you are granting it the right to perform the operation you have specified
42 * as if the other application was yourself (with the same permissions and
43 * identity). As such, you should be careful about how you build the PendingIntent:
Dianne Hackborna53ee352013-02-20 12:47:02 -080044 * almost always, for example, the base Intent you supply should have the component
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 * name explicitly set to one of your own components, to ensure it is ultimately
46 * sent there and nowhere else.
47 *
48 * <p>A PendingIntent itself is simply a reference to a token maintained by
49 * the system describing the original data used to retrieve it. This means
50 * that, even if its owning application's process is killed, the
51 * PendingIntent itself will remain usable from other processes that
52 * have been given it. If the creating application later re-retrieves the
53 * same kind of PendingIntent (same operation, same Intent action, data,
54 * categories, and components, and same flags), it will receive a PendingIntent
55 * representing the same token if that is still valid, and can thus call
56 * {@link #cancel} to remove it.
Dianne Hackborn8832c182012-09-17 17:20:24 -070057 *
58 * <p>Because of this behavior, it is important to know when two Intents
59 * are considered to be the same for purposes of retrieving a PendingIntent.
60 * A common mistake people make is to create multiple PendingIntent objects
61 * with Intents that only vary in their "extra" contents, expecting to get
62 * a different PendingIntent each time. This does <em>not</em> happen. The
63 * parts of the Intent that are used for matching are the same ones defined
64 * by {@link Intent#filterEquals(Intent) Intent.filterEquals}. If you use two
65 * Intent objects that are equivalent as per
66 * {@link Intent#filterEquals(Intent) Intent.filterEquals}, then you will get
67 * the same PendingIntent for both of them.
68 *
69 * <p>There are two typical ways to deal with this.
70 *
71 * <p>If you truly need multiple distinct PendingIntent objects active at
72 * the same time (such as to use as two notifications that are both shown
73 * at the same time), then you will need to ensure there is something that
74 * is different about them to associate them with different PendingIntents.
75 * This may be any of the Intent attributes considered by
76 * {@link Intent#filterEquals(Intent) Intent.filterEquals}, or different
77 * request code integers supplied to {@link #getActivity}, {@link #getActivities},
78 * {@link #getBroadcast}, or {@link #getService}.
79 *
80 * <p>If you only need one PendingIntent active at a time for any of the
81 * Intents you will use, then you can alternatively use the flags
82 * {@link #FLAG_CANCEL_CURRENT} or {@link #FLAG_UPDATE_CURRENT} to either
83 * cancel or modify whatever current PendingIntent is associated with the
84 * Intent you are supplying.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 */
86public final class PendingIntent implements Parcelable {
87 private final IIntentSender mTarget;
88
89 /**
Scott Maindf75bdc2013-01-15 15:12:13 -080090 * Flag indicating that this PendingIntent can be used only once.
91 * For use with {@link #getActivity}, {@link #getBroadcast}, and
92 * {@link #getService}. <p>If set, after
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 * {@link #send()} is called on it, it will be automatically
94 * canceled for you and any future attempt to send through it will fail.
95 */
96 public static final int FLAG_ONE_SHOT = 1<<30;
97 /**
Scott Maindf75bdc2013-01-15 15:12:13 -080098 * Flag indicating that if the described PendingIntent already
99 * exists, then simply return null instead of creating it.
100 * For use with {@link #getActivity}, {@link #getBroadcast}, and
101 * {@link #getService}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 */
103 public static final int FLAG_NO_CREATE = 1<<29;
104 /**
Scott Maindf75bdc2013-01-15 15:12:13 -0800105 * Flag indicating that if the described PendingIntent already exists,
106 * the current one should be canceled before generating a new one.
107 * For use with {@link #getActivity}, {@link #getBroadcast}, and
108 * {@link #getService}. <p>You can use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 * this to retrieve a new PendingIntent when you are only changing the
110 * extra data in the Intent; by canceling the previous pending intent,
111 * this ensures that only entities given the new data will be able to
112 * launch it. If this assurance is not an issue, consider
113 * {@link #FLAG_UPDATE_CURRENT}.
114 */
115 public static final int FLAG_CANCEL_CURRENT = 1<<28;
116 /**
Scott Maindf75bdc2013-01-15 15:12:13 -0800117 * Flag indicating that if the described PendingIntent already exists,
118 * then keep it but replace its extra data with what is in this new
119 * Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and
120 * {@link #getService}. <p>This can be used if you are creating intents where only the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 * extras change, and don't care that any entities that received your
122 * previous PendingIntent will be able to launch it with your new
123 * extras even if they are not explicitly given to it.
124 */
125 public static final int FLAG_UPDATE_CURRENT = 1<<27;
126
127 /**
128 * Exception thrown when trying to send through a PendingIntent that
129 * has been canceled or is otherwise no longer able to execute the request.
130 */
131 public static class CanceledException extends AndroidException {
132 public CanceledException() {
133 }
134
135 public CanceledException(String name) {
136 super(name);
137 }
138
139 public CanceledException(Exception cause) {
140 super(cause);
141 }
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -0700142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143
144 /**
145 * Callback interface for discovering when a send operation has
146 * completed. Primarily for use with a PendingIntent that is
147 * performing a broadcast, this provides the same information as
148 * calling {@link Context#sendOrderedBroadcast(Intent, String,
149 * android.content.BroadcastReceiver, Handler, int, String, Bundle)
150 * Context.sendBroadcast()} with a final BroadcastReceiver.
151 */
152 public interface OnFinished {
153 /**
154 * Called when a send operation as completed.
155 *
156 * @param pendingIntent The PendingIntent this operation was sent through.
157 * @param intent The original Intent that was sent.
158 * @param resultCode The final result code determined by the send.
159 * @param resultData The final data collected by a broadcast.
160 * @param resultExtras The final extras collected by a broadcast.
161 */
162 void onSendFinished(PendingIntent pendingIntent, Intent intent,
163 int resultCode, String resultData, Bundle resultExtras);
164 }
165
166 private static class FinishedDispatcher extends IIntentReceiver.Stub
167 implements Runnable {
168 private final PendingIntent mPendingIntent;
169 private final OnFinished mWho;
170 private final Handler mHandler;
171 private Intent mIntent;
172 private int mResultCode;
173 private String mResultData;
174 private Bundle mResultExtras;
175 FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler) {
176 mPendingIntent = pi;
177 mWho = who;
178 mHandler = handler;
179 }
Dianne Hackborn20e80982012-08-31 19:00:44 -0700180 public void performReceive(Intent intent, int resultCode, String data,
181 Bundle extras, boolean serialized, boolean sticky, int sendingUser) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 mIntent = intent;
183 mResultCode = resultCode;
184 mResultData = data;
185 mResultExtras = extras;
186 if (mHandler == null) {
187 run();
188 } else {
189 mHandler.post(this);
190 }
191 }
192 public void run() {
193 mWho.onSendFinished(mPendingIntent, mIntent, mResultCode,
194 mResultData, mResultExtras);
195 }
196 }
197
198 /**
199 * Retrieve a PendingIntent that will start a new activity, like calling
200 * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
201 * Note that the activity will be started outside of the context of an
202 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
203 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
204 *
Dianne Hackborna53ee352013-02-20 12:47:02 -0800205 * <p class="note">For security reasons, the {@link android.content.Intent}
206 * you supply here should almost always be an <em>explicit intent</em>,
207 * that is specify an explicit component to be delivered to through
208 * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
209 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 * @param context The Context in which this PendingIntent should start
211 * the activity.
Danny Baumannf15a4192013-04-05 13:42:57 +0200212 * @param requestCode Private request code for the sender
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 * @param intent Intent of the activity to be launched.
214 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
215 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
216 * or any of the flags as supported by
217 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
218 * of the intent that can be supplied when the actual send happens.
219 *
220 * @return Returns an existing or new PendingIntent matching the given
221 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
222 * supplied.
223 */
224 public static PendingIntent getActivity(Context context, int requestCode,
225 Intent intent, int flags) {
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700226 return getActivity(context, requestCode, intent, flags, null);
227 }
228
229 /**
230 * Retrieve a PendingIntent that will start a new activity, like calling
231 * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
232 * Note that the activity will be started outside of the context of an
233 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
234 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
235 *
Dianne Hackborna53ee352013-02-20 12:47:02 -0800236 * <p class="note">For security reasons, the {@link android.content.Intent}
237 * you supply here should almost always be an <em>explicit intent</em>,
238 * that is specify an explicit component to be delivered to through
239 * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
240 *
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700241 * @param context The Context in which this PendingIntent should start
242 * the activity.
Danny Baumannf15a4192013-04-05 13:42:57 +0200243 * @param requestCode Private request code for the sender
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700244 * @param intent Intent of the activity to be launched.
245 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
246 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
247 * or any of the flags as supported by
248 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
249 * of the intent that can be supplied when the actual send happens.
250 * @param options Additional options for how the Activity should be started.
251 * May be null if there are no options.
252 *
253 * @return Returns an existing or new PendingIntent matching the given
254 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
255 * supplied.
256 */
257 public static PendingIntent getActivity(Context context, int requestCode,
258 Intent intent, int flags, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 String packageName = context.getPackageName();
260 String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
261 context.getContentResolver()) : null;
262 try {
Jeff Sharkey02ffba92013-03-08 16:13:15 -0800263 intent.migrateExtraStreamToClipData();
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700264 intent.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 IIntentSender target =
266 ActivityManagerNative.getDefault().getIntentSender(
Dianne Hackborna4972e92012-03-14 10:38:05 -0700267 ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800268 null, null, requestCode, new Intent[] { intent },
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700269 resolvedType != null ? new String[] { resolvedType } : null,
Dianne Hackborn41203752012-08-31 14:05:51 -0700270 flags, options, UserHandle.myUserId());
271 return target != null ? new PendingIntent(target) : null;
272 } catch (RemoteException e) {
273 }
274 return null;
275 }
276
277 /**
278 * @hide
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -0700279 * Note that UserHandle.CURRENT will be interpreted at the time the
280 * activity is started, not when the pending intent is created.
Dianne Hackborn41203752012-08-31 14:05:51 -0700281 */
282 public static PendingIntent getActivityAsUser(Context context, int requestCode,
283 Intent intent, int flags, Bundle options, UserHandle user) {
284 String packageName = context.getPackageName();
285 String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
286 context.getContentResolver()) : null;
287 try {
Jeff Sharkey02ffba92013-03-08 16:13:15 -0800288 intent.migrateExtraStreamToClipData();
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700289 intent.prepareToLeaveProcess();
Dianne Hackborn41203752012-08-31 14:05:51 -0700290 IIntentSender target =
291 ActivityManagerNative.getDefault().getIntentSender(
292 ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
293 null, null, requestCode, new Intent[] { intent },
294 resolvedType != null ? new String[] { resolvedType } : null,
295 flags, options, user.getIdentifier());
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800296 return target != null ? new PendingIntent(target) : null;
297 } catch (RemoteException e) {
298 }
299 return null;
300 }
301
302 /**
303 * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
Tim Hutt5313c9f2012-12-10 12:34:19 +0000304 * array of Intents to be supplied. The last Intent in the array is
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800305 * taken as the primary key for the PendingIntent, like the single Intent
306 * given to {@link #getActivity(Context, int, Intent, int)}. Upon sending
307 * the resulting PendingIntent, all of the Intents are started in the same
308 * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
309 *
310 * <p class="note">
311 * The <em>first</em> intent in the array will be started outside of the context of an
312 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
313 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. (Activities after
314 * the first in the array are started in the context of the previous activity
315 * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
316 * </p>
317 *
318 * <p class="note">
319 * The <em>last</em> intent in the array represents the key for the
320 * PendingIntent. In other words, it is the significant element for matching
321 * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
322 * its content will be the subject of replacement by
323 * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
324 * This is because it is the most specific of the supplied intents, and the
325 * UI the user actually sees when the intents are started.
326 * </p>
327 *
Dianne Hackborna53ee352013-02-20 12:47:02 -0800328 * <p class="note">For security reasons, the {@link android.content.Intent} objects
329 * you supply here should almost always be <em>explicit intents</em>,
330 * that is specify an explicit component to be delivered to through
331 * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
332 *
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800333 * @param context The Context in which this PendingIntent should start
334 * the activity.
Danny Baumannf15a4192013-04-05 13:42:57 +0200335 * @param requestCode Private request code for the sender
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800336 * @param intents Array of Intents of the activities to be launched.
337 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
338 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
339 * or any of the flags as supported by
340 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
341 * of the intent that can be supplied when the actual send happens.
342 *
343 * @return Returns an existing or new PendingIntent matching the given
344 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
345 * supplied.
346 */
347 public static PendingIntent getActivities(Context context, int requestCode,
348 Intent[] intents, int flags) {
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700349 return getActivities(context, requestCode, intents, flags, null);
350 }
351
352 /**
353 * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
Tim Hutt5313c9f2012-12-10 12:34:19 +0000354 * array of Intents to be supplied. The last Intent in the array is
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700355 * taken as the primary key for the PendingIntent, like the single Intent
356 * given to {@link #getActivity(Context, int, Intent, int)}. Upon sending
357 * the resulting PendingIntent, all of the Intents are started in the same
358 * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
359 *
360 * <p class="note">
361 * The <em>first</em> intent in the array will be started outside of the context of an
362 * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
363 * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. (Activities after
364 * the first in the array are started in the context of the previous activity
365 * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
366 * </p>
367 *
368 * <p class="note">
369 * The <em>last</em> intent in the array represents the key for the
370 * PendingIntent. In other words, it is the significant element for matching
371 * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
372 * its content will be the subject of replacement by
373 * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
374 * This is because it is the most specific of the supplied intents, and the
375 * UI the user actually sees when the intents are started.
376 * </p>
377 *
Dianne Hackborna53ee352013-02-20 12:47:02 -0800378 * <p class="note">For security reasons, the {@link android.content.Intent} objects
379 * you supply here should almost always be <em>explicit intents</em>,
380 * that is specify an explicit component to be delivered to through
381 * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
382 *
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700383 * @param context The Context in which this PendingIntent should start
384 * the activity.
Danny Baumannf15a4192013-04-05 13:42:57 +0200385 * @param requestCode Private request code for the sender
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700386 * @param intents Array of Intents of the activities to be launched.
387 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
388 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
389 * or any of the flags as supported by
390 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
391 * of the intent that can be supplied when the actual send happens.
392 *
393 * @return Returns an existing or new PendingIntent matching the given
394 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
395 * supplied.
396 */
397 public static PendingIntent getActivities(Context context, int requestCode,
398 Intent[] intents, int flags, Bundle options) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800399 String packageName = context.getPackageName();
400 String[] resolvedTypes = new String[intents.length];
401 for (int i=0; i<intents.length; i++) {
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700402 intents[i].migrateExtraStreamToClipData();
403 intents[i].prepareToLeaveProcess();
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800404 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
405 }
406 try {
407 IIntentSender target =
408 ActivityManagerNative.getDefault().getIntentSender(
Dianne Hackborna4972e92012-03-14 10:38:05 -0700409 ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
Dianne Hackborn41203752012-08-31 14:05:51 -0700410 null, null, requestCode, intents, resolvedTypes, flags, options,
411 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 return target != null ? new PendingIntent(target) : null;
413 } catch (RemoteException e) {
414 }
415 return null;
416 }
417
418 /**
Adam Powelld56b4d12012-09-30 18:27:31 -0700419 * @hide
420 * Note that UserHandle.CURRENT will be interpreted at the time the
421 * activity is started, not when the pending intent is created.
422 */
423 public static PendingIntent getActivitiesAsUser(Context context, int requestCode,
424 Intent[] intents, int flags, Bundle options, UserHandle user) {
425 String packageName = context.getPackageName();
426 String[] resolvedTypes = new String[intents.length];
427 for (int i=0; i<intents.length; i++) {
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700428 intents[i].migrateExtraStreamToClipData();
429 intents[i].prepareToLeaveProcess();
Adam Powelld56b4d12012-09-30 18:27:31 -0700430 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,
437 flags, options, user.getIdentifier());
438 return target != null ? new PendingIntent(target) : null;
439 } catch (RemoteException e) {
440 }
441 return null;
442 }
443
444 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 * Retrieve a PendingIntent that will perform a broadcast, like calling
446 * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
447 *
Dianne Hackborna53ee352013-02-20 12:47:02 -0800448 * <p class="note">For security reasons, the {@link android.content.Intent}
449 * you supply here should almost always be an <em>explicit intent</em>,
450 * that is specify an explicit component to be delivered to through
451 * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
452 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 * @param context The Context in which this PendingIntent should perform
454 * the broadcast.
Danny Baumannf15a4192013-04-05 13:42:57 +0200455 * @param requestCode Private request code for the sender
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 * @param intent The Intent to be broadcast.
457 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
458 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
459 * or any of the flags as supported by
460 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
461 * of the intent that can be supplied when the actual send happens.
462 *
463 * @return Returns an existing or new PendingIntent matching the given
464 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
465 * supplied.
466 */
467 public static PendingIntent getBroadcast(Context context, int requestCode,
468 Intent intent, int flags) {
Amith Yamasani599dd7c2012-09-14 23:20:08 -0700469 return getBroadcastAsUser(context, requestCode, intent, flags,
470 new UserHandle(UserHandle.myUserId()));
471 }
472
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -0700473 /**
474 * @hide
475 * Note that UserHandle.CURRENT will be interpreted at the time the
476 * broadcast is sent, not when the pending intent is created.
477 */
Amith Yamasani599dd7c2012-09-14 23:20:08 -0700478 public static PendingIntent getBroadcastAsUser(Context context, int requestCode,
479 Intent intent, int flags, UserHandle userHandle) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 String packageName = context.getPackageName();
481 String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
482 context.getContentResolver()) : null;
483 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700484 intent.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 IIntentSender target =
486 ActivityManagerNative.getDefault().getIntentSender(
Dianne Hackborna4972e92012-03-14 10:38:05 -0700487 ActivityManager.INTENT_SENDER_BROADCAST, packageName,
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800488 null, null, requestCode, new Intent[] { intent },
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700489 resolvedType != null ? new String[] { resolvedType } : null,
Amith Yamasani599dd7c2012-09-14 23:20:08 -0700490 flags, null, userHandle.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 return target != null ? new PendingIntent(target) : null;
492 } catch (RemoteException e) {
493 }
494 return null;
495 }
496
497 /**
498 * Retrieve a PendingIntent that will start a service, like calling
499 * {@link Context#startService Context.startService()}. The start
500 * arguments given to the service will come from the extras of the Intent.
501 *
Dianne Hackborna53ee352013-02-20 12:47:02 -0800502 * <p class="note">For security reasons, the {@link android.content.Intent}
503 * you supply here should almost always be an <em>explicit intent</em>,
504 * that is specify an explicit component to be delivered to through
505 * {@link Intent#setClass(android.content.Context, Class)} Intent.setClass</p>
506 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 * @param context The Context in which this PendingIntent should start
508 * the service.
Danny Baumannf15a4192013-04-05 13:42:57 +0200509 * @param requestCode Private request code for the sender
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510 * @param intent An Intent describing the service to be started.
511 * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
512 * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
513 * or any of the flags as supported by
514 * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
515 * of the intent that can be supplied when the actual send happens.
516 *
517 * @return Returns an existing or new PendingIntent matching the given
518 * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
519 * supplied.
520 */
521 public static PendingIntent getService(Context context, int requestCode,
522 Intent intent, int flags) {
523 String packageName = context.getPackageName();
524 String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
525 context.getContentResolver()) : null;
526 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700527 intent.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 IIntentSender target =
529 ActivityManagerNative.getDefault().getIntentSender(
Dianne Hackborna4972e92012-03-14 10:38:05 -0700530 ActivityManager.INTENT_SENDER_SERVICE, packageName,
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800531 null, null, requestCode, new Intent[] { intent },
Dianne Hackborn7a2195c2012-03-19 17:38:00 -0700532 resolvedType != null ? new String[] { resolvedType } : null,
Dianne Hackborn41203752012-08-31 14:05:51 -0700533 flags, null, UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 return target != null ? new PendingIntent(target) : null;
535 } catch (RemoteException e) {
536 }
537 return null;
538 }
539
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -0700540 /**
541 * Retrieve a IntentSender object that wraps the existing sender of the PendingIntent
542 *
543 * @return Returns a IntentSender object that wraps the sender of PendingIntent
544 *
545 */
546 public IntentSender getIntentSender() {
Dianne Hackborn7f205432009-07-28 00:13:47 -0700547 return new IntentSender(mTarget);
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -0700548 }
549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 /**
551 * Cancel a currently active PendingIntent. Only the original application
Ken Wakasaf76a50c2012-03-09 19:56:35 +0900552 * owning a PendingIntent can cancel it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 */
554 public void cancel() {
555 try {
556 ActivityManagerNative.getDefault().cancelIntentSender(mTarget);
557 } catch (RemoteException e) {
558 }
559 }
560
561 /**
562 * Perform the operation associated with this PendingIntent.
563 *
564 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
565 *
566 * @throws CanceledException Throws CanceledException if the PendingIntent
567 * is no longer allowing more intents to be sent through it.
568 */
569 public void send() throws CanceledException {
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700570 send(null, 0, null, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 }
572
573 /**
574 * Perform the operation associated with this PendingIntent.
575 *
576 * @param code Result code to supply back to the PendingIntent's target.
577 *
578 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
579 *
580 * @throws CanceledException Throws CanceledException if the PendingIntent
581 * is no longer allowing more intents to be sent through it.
582 */
583 public void send(int code) throws CanceledException {
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700584 send(null, code, null, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 }
586
587 /**
588 * Perform the operation associated with this PendingIntent, allowing the
589 * caller to specify information about the Intent to use.
590 *
591 * @param context The Context of the caller.
592 * @param code Result code to supply back to the PendingIntent's target.
593 * @param intent Additional Intent data. See {@link Intent#fillIn
594 * Intent.fillIn()} for information on how this is applied to the
595 * original Intent.
596 *
597 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
598 *
599 * @throws CanceledException Throws CanceledException if the PendingIntent
600 * is no longer allowing more intents to be sent through it.
601 */
602 public void send(Context context, int code, Intent intent)
603 throws CanceledException {
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700604 send(context, code, intent, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 }
606
607 /**
608 * Perform the operation associated with this PendingIntent, allowing the
609 * caller to be notified when the send has completed.
610 *
611 * @param code Result code to supply back to the PendingIntent's target.
612 * @param onFinished The object to call back on when the send has
613 * completed, or null for no callback.
614 * @param handler Handler identifying the thread on which the callback
615 * should happen. If null, the callback will happen from the thread
616 * pool of the process.
617 *
618 * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler)
619 *
620 * @throws CanceledException Throws CanceledException if the PendingIntent
621 * is no longer allowing more intents to be sent through it.
622 */
623 public void send(int code, OnFinished onFinished, Handler handler)
624 throws CanceledException {
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700625 send(null, code, null, onFinished, handler, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 }
627
628 /**
629 * Perform the operation associated with this PendingIntent, allowing the
630 * caller to specify information about the Intent to use and be notified
631 * when the send has completed.
632 *
633 * <p>For the intent parameter, a PendingIntent
634 * often has restrictions on which fields can be supplied here, based on
635 * how the PendingIntent was retrieved in {@link #getActivity},
636 * {@link #getBroadcast}, or {@link #getService}.
637 *
638 * @param context The Context of the caller. This may be null if
639 * <var>intent</var> is also null.
640 * @param code Result code to supply back to the PendingIntent's target.
641 * @param intent Additional Intent data. See {@link Intent#fillIn
642 * Intent.fillIn()} for information on how this is applied to the
643 * original Intent. Use null to not modify the original Intent.
644 * @param onFinished The object to call back on when the send has
645 * completed, or null for no callback.
646 * @param handler Handler identifying the thread on which the callback
647 * should happen. If null, the callback will happen from the thread
648 * pool of the process.
649 *
650 * @see #send()
651 * @see #send(int)
652 * @see #send(Context, int, Intent)
653 * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700654 * @see #send(Context, int, Intent, OnFinished, Handler, String)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 *
656 * @throws CanceledException Throws CanceledException if the PendingIntent
657 * is no longer allowing more intents to be sent through it.
658 */
659 public void send(Context context, int code, Intent intent,
660 OnFinished onFinished, Handler handler) throws CanceledException {
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700661 send(context, code, intent, onFinished, handler, null);
662 }
663
664 /**
665 * Perform the operation associated with this PendingIntent, allowing the
666 * caller to specify information about the Intent to use and be notified
667 * when the send has completed.
668 *
669 * <p>For the intent parameter, a PendingIntent
670 * often has restrictions on which fields can be supplied here, based on
671 * how the PendingIntent was retrieved in {@link #getActivity},
672 * {@link #getBroadcast}, or {@link #getService}.
673 *
674 * @param context The Context of the caller. This may be null if
675 * <var>intent</var> is also null.
676 * @param code Result code to supply back to the PendingIntent's target.
677 * @param intent Additional Intent data. See {@link Intent#fillIn
678 * Intent.fillIn()} for information on how this is applied to the
679 * original Intent. Use null to not modify the original Intent.
680 * @param onFinished The object to call back on when the send has
681 * completed, or null for no callback.
682 * @param handler Handler identifying the thread on which the callback
683 * should happen. If null, the callback will happen from the thread
684 * pool of the process.
685 * @param requiredPermission Name of permission that a recipient of the PendingIntent
686 * is required to hold. This is only valid for broadcast intents, and
687 * corresponds to the permission argument in
688 * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
689 * If null, no permission is required.
690 *
691 * @see #send()
692 * @see #send(int)
693 * @see #send(Context, int, Intent)
694 * @see #send(int, android.app.PendingIntent.OnFinished, Handler)
695 * @see #send(Context, int, Intent, OnFinished, Handler)
696 *
697 * @throws CanceledException Throws CanceledException if the PendingIntent
698 * is no longer allowing more intents to be sent through it.
699 */
700 public void send(Context context, int code, Intent intent,
701 OnFinished onFinished, Handler handler, String requiredPermission)
702 throws CanceledException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703 try {
704 String resolvedType = intent != null ?
705 intent.resolveTypeIfNeeded(context.getContentResolver())
706 : null;
707 int res = mTarget.send(code, intent, resolvedType,
708 onFinished != null
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700709 ? new FinishedDispatcher(this, onFinished, handler)
710 : null,
711 requiredPermission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712 if (res < 0) {
713 throw new CanceledException();
714 }
715 } catch (RemoteException e) {
716 throw new CanceledException(e);
717 }
718 }
719
720 /**
Dianne Hackborn8832c182012-09-17 17:20:24 -0700721 * @deprecated Renamed to {@link #getCreatorPackage()}.
722 */
723 @Deprecated
724 public String getTargetPackage() {
725 try {
726 return ActivityManagerNative.getDefault()
727 .getPackageForIntentSender(mTarget);
728 } catch (RemoteException e) {
729 // Should never happen.
730 return null;
731 }
732 }
733
734 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 * Return the package name of the application that created this
736 * PendingIntent, that is the identity under which you will actually be
737 * sending the Intent. The returned string is supplied by the system, so
738 * that an application can not spoof its package.
739 *
Dianne Hackborna53ee352013-02-20 12:47:02 -0800740 * <p class="note">Be careful about how you use this. All this tells you is
741 * who created the PendingIntent. It does <strong>not</strong> tell you who
742 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
743 * passed between applications, so the PendingIntent you receive from an application
744 * could actually be one it received from another application, meaning the result
745 * you get here will identify the original application. Because of this, you should
746 * only use this information to identify who you expect to be interacting with
747 * through a {@link #send} call, not who gave you the PendingIntent.</p>
748 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749 * @return The package name of the PendingIntent, or null if there is
750 * none associated with it.
751 */
Dianne Hackborn8832c182012-09-17 17:20:24 -0700752 public String getCreatorPackage() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 try {
754 return ActivityManagerNative.getDefault()
755 .getPackageForIntentSender(mTarget);
756 } catch (RemoteException e) {
757 // Should never happen.
758 return null;
759 }
760 }
761
762 /**
Dianne Hackbornc7501272012-08-14 18:05:05 -0700763 * Return the uid of the application that created this
764 * PendingIntent, that is the identity under which you will actually be
765 * sending the Intent. The returned integer is supplied by the system, so
766 * that an application can not spoof its uid.
767 *
Dianne Hackborna53ee352013-02-20 12:47:02 -0800768 * <p class="note">Be careful about how you use this. All this tells you is
769 * who created the PendingIntent. It does <strong>not</strong> tell you who
770 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
771 * passed between applications, so the PendingIntent you receive from an application
772 * could actually be one it received from another application, meaning the result
773 * you get here will identify the original application. Because of this, you should
774 * only use this information to identify who you expect to be interacting with
775 * through a {@link #send} call, not who gave you the PendingIntent.</p>
776 *
Dianne Hackbornc7501272012-08-14 18:05:05 -0700777 * @return The uid of the PendingIntent, or -1 if there is
778 * none associated with it.
779 */
Dianne Hackborn8832c182012-09-17 17:20:24 -0700780 public int getCreatorUid() {
Dianne Hackbornc7501272012-08-14 18:05:05 -0700781 try {
782 return ActivityManagerNative.getDefault()
783 .getUidForIntentSender(mTarget);
784 } catch (RemoteException e) {
785 // Should never happen.
786 return -1;
787 }
788 }
789
790 /**
791 * Return the user handle of the application that created this
792 * PendingIntent, that is the user under which you will actually be
Dianne Hackborn79af1dd2012-08-16 16:42:52 -0700793 * sending the Intent. The returned UserHandle is supplied by the system, so
Dianne Hackbornc7501272012-08-14 18:05:05 -0700794 * that an application can not spoof its user. See
795 * {@link android.os.Process#myUserHandle() Process.myUserHandle()} for
796 * more explanation of user handles.
797 *
Dianne Hackborna53ee352013-02-20 12:47:02 -0800798 * <p class="note">Be careful about how you use this. All this tells you is
799 * who created the PendingIntent. It does <strong>not</strong> tell you who
800 * handed the PendingIntent to you: that is, PendingIntent objects are intended to be
801 * passed between applications, so the PendingIntent you receive from an application
802 * could actually be one it received from another application, meaning the result
803 * you get here will identify the original application. Because of this, you should
804 * only use this information to identify who you expect to be interacting with
805 * through a {@link #send} call, not who gave you the PendingIntent.</p>
806 *
Dianne Hackborn79af1dd2012-08-16 16:42:52 -0700807 * @return The user handle of the PendingIntent, or null if there is
Dianne Hackbornc7501272012-08-14 18:05:05 -0700808 * none associated with it.
809 */
Dianne Hackborn8832c182012-09-17 17:20:24 -0700810 public UserHandle getCreatorUserHandle() {
Dianne Hackbornc7501272012-08-14 18:05:05 -0700811 try {
812 int uid = ActivityManagerNative.getDefault()
813 .getUidForIntentSender(mTarget);
Dianne Hackborn79af1dd2012-08-16 16:42:52 -0700814 return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null;
Dianne Hackbornc7501272012-08-14 18:05:05 -0700815 } catch (RemoteException e) {
816 // Should never happen.
Dianne Hackborn79af1dd2012-08-16 16:42:52 -0700817 return null;
Dianne Hackbornc7501272012-08-14 18:05:05 -0700818 }
819 }
820
821 /**
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700822 * @hide
823 * Check to verify that this PendingIntent targets a specific package.
824 */
825 public boolean isTargetedToPackage() {
826 try {
827 return ActivityManagerNative.getDefault()
828 .isIntentSenderTargetedToPackage(mTarget);
829 } catch (RemoteException e) {
830 // Should never happen.
831 return false;
832 }
833 }
834
835 /**
Dianne Hackborn1927ae82012-06-22 15:21:36 -0700836 * @hide
837 * Check whether this PendingIntent will launch an Activity.
838 */
839 public boolean isActivity() {
840 try {
841 return ActivityManagerNative.getDefault()
842 .isIntentSenderAnActivity(mTarget);
843 } catch (RemoteException e) {
844 // Should never happen.
845 return false;
846 }
847 }
848
849 /**
Dianne Hackborn81038902012-11-26 17:04:09 -0800850 * @hide
851 * Return the Intent of this PendingIntent.
852 */
853 public Intent getIntent() {
854 try {
855 return ActivityManagerNative.getDefault()
856 .getIntentForIntentSender(mTarget);
857 } catch (RemoteException e) {
858 // Should never happen.
859 return null;
860 }
861 }
862
863 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 * Comparison operator on two PendingIntent objects, such that true
865 * is returned then they both represent the same operation from the
866 * same package. This allows you to use {@link #getActivity},
867 * {@link #getBroadcast}, or {@link #getService} multiple times (even
868 * across a process being killed), resulting in different PendingIntent
869 * objects but whose equals() method identifies them as being the same
870 * operation.
871 */
872 @Override
873 public boolean equals(Object otherObj) {
874 if (otherObj instanceof PendingIntent) {
875 return mTarget.asBinder().equals(((PendingIntent)otherObj)
876 .mTarget.asBinder());
877 }
878 return false;
879 }
880
881 @Override
882 public int hashCode() {
883 return mTarget.asBinder().hashCode();
884 }
885
886 @Override
887 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700888 StringBuilder sb = new StringBuilder(128);
889 sb.append("PendingIntent{");
890 sb.append(Integer.toHexString(System.identityHashCode(this)));
891 sb.append(": ");
892 sb.append(mTarget != null ? mTarget.asBinder() : null);
893 sb.append('}');
894 return sb.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 }
896
897 public int describeContents() {
898 return 0;
899 }
900
901 public void writeToParcel(Parcel out, int flags) {
902 out.writeStrongBinder(mTarget.asBinder());
903 }
904
905 public static final Parcelable.Creator<PendingIntent> CREATOR
906 = new Parcelable.Creator<PendingIntent>() {
907 public PendingIntent createFromParcel(Parcel in) {
908 IBinder target = in.readStrongBinder();
909 return target != null ? new PendingIntent(target) : null;
910 }
911
912 public PendingIntent[] newArray(int size) {
913 return new PendingIntent[size];
914 }
915 };
916
917 /**
918 * Convenience function for writing either a PendingIntent or null pointer to
919 * a Parcel. You must use this with {@link #readPendingIntentOrNullFromParcel}
920 * for later reading it.
921 *
922 * @param sender The PendingIntent to write, or null.
923 * @param out Where to write the PendingIntent.
924 */
925 public static void writePendingIntentOrNullToParcel(PendingIntent sender,
926 Parcel out) {
927 out.writeStrongBinder(sender != null ? sender.mTarget.asBinder()
928 : null);
929 }
930
931 /**
932 * Convenience function for reading either a Messenger or null pointer from
933 * a Parcel. You must have previously written the Messenger with
934 * {@link #writePendingIntentOrNullToParcel}.
935 *
936 * @param in The Parcel containing the written Messenger.
937 *
938 * @return Returns the Messenger read from the Parcel, or null if null had
939 * been written.
940 */
941 public static PendingIntent readPendingIntentOrNullFromParcel(Parcel in) {
942 IBinder b = in.readStrongBinder();
943 return b != null ? new PendingIntent(b) : null;
944 }
945
946 /*package*/ PendingIntent(IIntentSender target) {
947 mTarget = target;
948 }
949
950 /*package*/ PendingIntent(IBinder target) {
951 mTarget = IIntentSender.Stub.asInterface(target);
952 }
953
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -0700954 /** @hide */
955 public IIntentSender getTarget() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 return mTarget;
957 }
958}