Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.app;
     18 
     19 import android.annotation.SdkConstant;
     20 import android.app.Notification.Builder;
     21 import android.content.ComponentName;
     22 import android.content.Context;
     23 import android.os.Bundle;
     24 import android.os.Handler;
     25 import android.os.IBinder;
     26 import android.os.RemoteException;
     27 import android.os.ServiceManager;
     28 import android.os.StrictMode;
     29 import android.os.UserHandle;
     30 import android.util.Log;
     31 
     32 /**
     33  * Class to notify the user of events that happen.  This is how you tell
     34  * the user that something has happened in the background. {@more}
     35  *
     36  * Notifications can take different forms:
     37  * <ul>
     38  *      <li>A persistent icon that goes in the status bar and is accessible
     39  *          through the launcher, (when the user selects it, a designated Intent
     40  *          can be launched),</li>
     41  *      <li>Turning on or flashing LEDs on the device, or</li>
     42  *      <li>Alerting the user by flashing the backlight, playing a sound,
     43  *          or vibrating.</li>
     44  * </ul>
     45  *
     46  * <p>
     47  * Each of the notify methods takes an int id parameter and optionally a
     48  * {@link String} tag parameter, which may be {@code null}.  These parameters
     49  * are used to form a pair (tag, id), or ({@code null}, id) if tag is
     50  * unspecified.  This pair identifies this notification from your app to the
     51  * system, so that pair should be unique within your app.  If you call one
     52  * of the notify methods with a (tag, id) pair that is currently active and
     53  * a new set of notification parameters, it will be updated.  For example,
     54  * if you pass a new status bar icon, the old icon in the status bar will
     55  * be replaced with the new one.  This is also the same tag and id you pass
     56  * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
     57  * this notification.
     58  *
     59  * <p>
     60  * You do not instantiate this class directly; instead, retrieve it through
     61  * {@link android.content.Context#getSystemService}.
     62  *
     63  * <div class="special reference">
     64  * <h3>Developer Guides</h3>
     65  * <p>For a guide to creating notifications, read the
     66  * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
     67  * developer guide.</p>
     68  * </div>
     69  *
     70  * @see android.app.Notification
     71  * @see android.content.Context#getSystemService
     72  */
     73 public class NotificationManager
     74 {
     75     private static String TAG = "NotificationManager";
     76     private static boolean localLOGV = false;
     77 
     78     /**
     79      * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
     80      * This broadcast is only sent to registered receivers.
     81      *
     82      * @hide
     83      */
     84     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
     85     public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
     86             = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
     87 
     88     private static INotificationManager sService;
     89 
     90     /** @hide */
     91     static public INotificationManager getService()
     92     {
     93         if (sService != null) {
     94             return sService;
     95         }
     96         IBinder b = ServiceManager.getService("notification");
     97         sService = INotificationManager.Stub.asInterface(b);
     98         return sService;
     99     }
    100 
    101     /*package*/ NotificationManager(Context context, Handler handler)
    102     {
    103         mContext = context;
    104     }
    105 
    106     /** {@hide} */
    107     public static NotificationManager from(Context context) {
    108         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    109     }
    110 
    111     /**
    112      * Post a notification to be shown in the status bar. If a notification with
    113      * the same id has already been posted by your application and has not yet been canceled, it
    114      * will be replaced by the updated information.
    115      *
    116      * @param id An identifier for this notification unique within your
    117      *        application.
    118      * @param notification A {@link Notification} object describing what to show the user. Must not
    119      *        be null.
    120      */
    121     public void notify(int id, Notification notification)
    122     {
    123         notify(null, id, notification);
    124     }
    125 
    126     /**
    127      * Post a notification to be shown in the status bar. If a notification with
    128      * the same tag and id has already been posted by your application and has not yet been
    129      * canceled, it will be replaced by the updated information.
    130      *
    131      * @param tag A string identifier for this notification.  May be {@code null}.
    132      * @param id An identifier for this notification.  The pair (tag, id) must be unique
    133      *        within your application.
    134      * @param notification A {@link Notification} object describing what to
    135      *        show the user. Must not be null.
    136      */
    137     public void notify(String tag, int id, Notification notification)
    138     {
    139         int[] idOut = new int[1];
    140         INotificationManager service = getService();
    141         String pkg = mContext.getPackageName();
    142         if (notification.sound != null) {
    143             notification.sound = notification.sound.getCanonicalUri();
    144             if (StrictMode.vmFileUriExposureEnabled()) {
    145                 notification.sound.checkFileUriExposed("Notification.sound");
    146             }
    147         }
    148         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
    149         Notification stripped = notification.clone();
    150         Builder.stripForDelivery(stripped);
    151         try {
    152             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
    153                     stripped, idOut, UserHandle.myUserId());
    154             if (id != idOut[0]) {
    155                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
    156             }
    157         } catch (RemoteException e) {
    158         }
    159     }
    160 
    161     /**
    162      * @hide
    163      */
    164     public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
    165     {
    166         int[] idOut = new int[1];
    167         INotificationManager service = getService();
    168         String pkg = mContext.getPackageName();
    169         if (notification.sound != null) {
    170             notification.sound = notification.sound.getCanonicalUri();
    171             if (StrictMode.vmFileUriExposureEnabled()) {
    172                 notification.sound.checkFileUriExposed("Notification.sound");
    173             }
    174         }
    175         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
    176         Notification stripped = notification.clone();
    177         Builder.stripForDelivery(stripped);
    178         try {
    179             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
    180                     stripped, idOut, user.getIdentifier());
    181             if (id != idOut[0]) {
    182                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
    183             }
    184         } catch (RemoteException e) {
    185         }
    186     }
    187 
    188     /**
    189      * Cancel a previously shown notification.  If it's transient, the view
    190      * will be hidden.  If it's persistent, it will be removed from the status
    191      * bar.
    192      */
    193     public void cancel(int id)
    194     {
    195         cancel(null, id);
    196     }
    197 
    198     /**
    199      * Cancel a previously shown notification.  If it's transient, the view
    200      * will be hidden.  If it's persistent, it will be removed from the status
    201      * bar.
    202      */
    203     public void cancel(String tag, int id)
    204     {
    205         INotificationManager service = getService();
    206         String pkg = mContext.getPackageName();
    207         if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
    208         try {
    209             service.cancelNotificationWithTag(pkg, tag, id, UserHandle.myUserId());
    210         } catch (RemoteException e) {
    211         }
    212     }
    213 
    214     /**
    215      * @hide
    216      */
    217     public void cancelAsUser(String tag, int id, UserHandle user)
    218     {
    219         INotificationManager service = getService();
    220         String pkg = mContext.getPackageName();
    221         if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
    222         try {
    223             service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
    224         } catch (RemoteException e) {
    225         }
    226     }
    227 
    228     /**
    229      * Cancel all previously shown notifications. See {@link #cancel} for the
    230      * detailed behavior.
    231      */
    232     public void cancelAll()
    233     {
    234         INotificationManager service = getService();
    235         String pkg = mContext.getPackageName();
    236         if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
    237         try {
    238             service.cancelAllNotifications(pkg, UserHandle.myUserId());
    239         } catch (RemoteException e) {
    240         }
    241     }
    242 
    243     /**
    244      * @hide
    245      */
    246     public ComponentName getEffectsSuppressor() {
    247         INotificationManager service = getService();
    248         try {
    249             return service.getEffectsSuppressor();
    250         } catch (RemoteException e) {
    251             return null;
    252         }
    253     }
    254 
    255     /**
    256      * @hide
    257      */
    258     public boolean matchesCallFilter(Bundle extras) {
    259         INotificationManager service = getService();
    260         try {
    261             return service.matchesCallFilter(extras);
    262         } catch (RemoteException e) {
    263             return false;
    264         }
    265     }
    266 
    267     private Context mContext;
    268 }
    269