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