NotificationManager.java revision b2278d65714c0dd0a6f94d1913db1ebc8bfc8b06
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.net.Uri;
24import android.os.Bundle;
25import android.os.Handler;
26import android.os.IBinder;
27import android.os.RemoteException;
28import android.os.ServiceManager;
29import android.os.StrictMode;
30import android.os.UserHandle;
31import android.provider.Settings.Global;
32import android.service.notification.IConditionListener;
33import android.service.notification.ZenModeConfig;
34import android.util.Log;
35
36/**
37 * Class to notify the user of events that happen.  This is how you tell
38 * the user that something has happened in the background. {@more}
39 *
40 * Notifications can take different forms:
41 * <ul>
42 *      <li>A persistent icon that goes in the status bar and is accessible
43 *          through the launcher, (when the user selects it, a designated Intent
44 *          can be launched),</li>
45 *      <li>Turning on or flashing LEDs on the device, or</li>
46 *      <li>Alerting the user by flashing the backlight, playing a sound,
47 *          or vibrating.</li>
48 * </ul>
49 *
50 * <p>
51 * Each of the notify methods takes an int id parameter and optionally a
52 * {@link String} tag parameter, which may be {@code null}.  These parameters
53 * are used to form a pair (tag, id), or ({@code null}, id) if tag is
54 * unspecified.  This pair identifies this notification from your app to the
55 * system, so that pair should be unique within your app.  If you call one
56 * of the notify methods with a (tag, id) pair that is currently active and
57 * a new set of notification parameters, it will be updated.  For example,
58 * if you pass a new status bar icon, the old icon in the status bar will
59 * be replaced with the new one.  This is also the same tag and id you pass
60 * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
61 * this notification.
62 *
63 * <p>
64 * You do not instantiate this class directly; instead, retrieve it through
65 * {@link android.content.Context#getSystemService}.
66 *
67 * <div class="special reference">
68 * <h3>Developer Guides</h3>
69 * <p>For a guide to creating notifications, read the
70 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
71 * developer guide.</p>
72 * </div>
73 *
74 * @see android.app.Notification
75 * @see android.content.Context#getSystemService
76 */
77public class NotificationManager
78{
79    private static String TAG = "NotificationManager";
80    private static boolean localLOGV = false;
81
82    /**
83     * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
84     * This broadcast is only sent to registered receivers.
85     *
86     * @hide
87     */
88    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
89    public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
90            = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
91
92    private static INotificationManager sService;
93
94    /** @hide */
95    static public INotificationManager getService()
96    {
97        if (sService != null) {
98            return sService;
99        }
100        IBinder b = ServiceManager.getService("notification");
101        sService = INotificationManager.Stub.asInterface(b);
102        return sService;
103    }
104
105    /*package*/ NotificationManager(Context context, Handler handler)
106    {
107        mContext = context;
108    }
109
110    /** {@hide} */
111    public static NotificationManager from(Context context) {
112        return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
113    }
114
115    /**
116     * Post a notification to be shown in the status bar. If a notification with
117     * the same id has already been posted by your application and has not yet been canceled, it
118     * will be replaced by the updated information.
119     *
120     * @param id An identifier for this notification unique within your
121     *        application.
122     * @param notification A {@link Notification} object describing what to show the user. Must not
123     *        be null.
124     */
125    public void notify(int id, Notification notification)
126    {
127        notify(null, id, notification);
128    }
129
130    /**
131     * Post a notification to be shown in the status bar. If a notification with
132     * the same tag and id has already been posted by your application and has not yet been
133     * canceled, it will be replaced by the updated information.
134     *
135     * @param tag A string identifier for this notification.  May be {@code null}.
136     * @param id An identifier for this notification.  The pair (tag, id) must be unique
137     *        within your application.
138     * @param notification A {@link Notification} object describing what to
139     *        show the user. Must not be null.
140     */
141    public void notify(String tag, int id, Notification notification)
142    {
143        int[] idOut = new int[1];
144        INotificationManager service = getService();
145        String pkg = mContext.getPackageName();
146        if (notification.sound != null) {
147            notification.sound = notification.sound.getCanonicalUri();
148            if (StrictMode.vmFileUriExposureEnabled()) {
149                notification.sound.checkFileUriExposed("Notification.sound");
150            }
151        }
152        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
153        Notification stripped = notification.clone();
154        Builder.stripForDelivery(stripped);
155        try {
156            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
157                    stripped, idOut, UserHandle.myUserId());
158            if (id != idOut[0]) {
159                Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
160            }
161        } catch (RemoteException e) {
162        }
163    }
164
165    /**
166     * @hide
167     */
168    public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
169    {
170        int[] idOut = new int[1];
171        INotificationManager service = getService();
172        String pkg = mContext.getPackageName();
173        if (notification.sound != null) {
174            notification.sound = notification.sound.getCanonicalUri();
175            if (StrictMode.vmFileUriExposureEnabled()) {
176                notification.sound.checkFileUriExposed("Notification.sound");
177            }
178        }
179        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
180        Notification stripped = notification.clone();
181        Builder.stripForDelivery(stripped);
182        try {
183            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
184                    stripped, idOut, user.getIdentifier());
185            if (id != idOut[0]) {
186                Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
187            }
188        } catch (RemoteException e) {
189        }
190    }
191
192    /**
193     * Cancel a previously shown notification.  If it's transient, the view
194     * will be hidden.  If it's persistent, it will be removed from the status
195     * bar.
196     */
197    public void cancel(int id)
198    {
199        cancel(null, id);
200    }
201
202    /**
203     * Cancel a previously shown notification.  If it's transient, the view
204     * will be hidden.  If it's persistent, it will be removed from the status
205     * bar.
206     */
207    public void cancel(String tag, int id)
208    {
209        INotificationManager service = getService();
210        String pkg = mContext.getPackageName();
211        if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
212        try {
213            service.cancelNotificationWithTag(pkg, tag, id, UserHandle.myUserId());
214        } catch (RemoteException e) {
215        }
216    }
217
218    /**
219     * @hide
220     */
221    public void cancelAsUser(String tag, int id, UserHandle user)
222    {
223        INotificationManager service = getService();
224        String pkg = mContext.getPackageName();
225        if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
226        try {
227            service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
228        } catch (RemoteException e) {
229        }
230    }
231
232    /**
233     * Cancel all previously shown notifications. See {@link #cancel} for the
234     * detailed behavior.
235     */
236    public void cancelAll()
237    {
238        INotificationManager service = getService();
239        String pkg = mContext.getPackageName();
240        if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
241        try {
242            service.cancelAllNotifications(pkg, UserHandle.myUserId());
243        } catch (RemoteException e) {
244        }
245    }
246
247    /**
248     * @hide
249     */
250    public ComponentName getEffectsSuppressor() {
251        INotificationManager service = getService();
252        try {
253            return service.getEffectsSuppressor();
254        } catch (RemoteException e) {
255            return null;
256        }
257    }
258
259    /**
260     * @hide
261     */
262    public boolean matchesCallFilter(Bundle extras) {
263        INotificationManager service = getService();
264        try {
265            return service.matchesCallFilter(extras);
266        } catch (RemoteException e) {
267            return false;
268        }
269    }
270
271    /**
272     * @hide
273     */
274    public boolean isSystemConditionProviderEnabled(String path) {
275        INotificationManager service = getService();
276        try {
277            return service.isSystemConditionProviderEnabled(path);
278        } catch (RemoteException e) {
279            return false;
280        }
281    }
282
283    /**
284     * @hide
285     */
286    public void setZenMode(int mode, Uri conditionId, String reason) {
287        INotificationManager service = getService();
288        try {
289            service.setZenMode(mode, conditionId, reason);
290        } catch (RemoteException e) {
291        }
292    }
293
294    /**
295     * @hide
296     */
297    public boolean setZenModeConfig(ZenModeConfig config, String reason) {
298        INotificationManager service = getService();
299        try {
300            return service.setZenModeConfig(config, reason);
301        } catch (RemoteException e) {
302            return false;
303        }
304    }
305
306    /**
307     * @hide
308     */
309    public void requestZenModeConditions(IConditionListener listener, int relevance) {
310        INotificationManager service = getService();
311        try {
312            service.requestZenModeConditions(listener, relevance);
313        } catch (RemoteException e) {
314        }
315    }
316
317    /**
318     * @hide
319     */
320    public int getZenMode() {
321        INotificationManager service = getService();
322        try {
323            return service.getZenMode();
324        } catch (RemoteException e) {
325        }
326        return Global.ZEN_MODE_OFF;
327    }
328
329    /**
330     * @hide
331     */
332    public ZenModeConfig getZenModeConfig() {
333        INotificationManager service = getService();
334        try {
335            return service.getZenModeConfig();
336        } catch (RemoteException e) {
337        }
338        return null;
339    }
340
341    private Context mContext;
342}
343