NotificationManager.java revision 530052a2fe3b6a6a4246ce28ab0ced647fe7f470
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
17package android.app;
18
19import android.annotation.SdkConstant;
20import android.app.Notification.Builder;
21import android.content.ComponentName;
22import android.content.Context;
23import android.os.Bundle;
24import android.os.Handler;
25import android.os.IBinder;
26import android.os.RemoteException;
27import android.os.ServiceManager;
28import android.os.StrictMode;
29import android.os.UserHandle;
30import 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 */
73public 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    /**
268     * @hide
269     */
270    public boolean isSystemConditionProviderEnabled(String path) {
271        INotificationManager service = getService();
272        try {
273            return service.isSystemConditionProviderEnabled(path);
274        } catch (RemoteException e) {
275            return false;
276        }
277    }
278
279    private Context mContext;
280}
281