NotificationListenerService.java revision 25cf8cee6f304a286d321204e448b18ce733a60c
1/*
2 * Copyright (C) 2013 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.service.notification;
18
19import android.annotation.SdkConstant;
20import android.app.INotificationManager;
21import android.app.Service;
22import android.content.Context;
23import android.content.Intent;
24import android.os.IBinder;
25import android.os.ServiceManager;
26import android.util.Log;
27
28public abstract class NotificationListenerService extends Service {
29    // TAG = "NotificationListenerService[MySubclass]"
30    private final String TAG = NotificationListenerService.class.getSimpleName()
31            + "[" + getClass().getSimpleName() + "]";
32
33    private INotificationListenerWrapper mWrapper = null;
34
35    private INotificationManager mNoMan;
36
37    /**
38     * The {@link Intent} that must be declared as handled by the service.
39     */
40    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
41    public static final String SERVICE_INTERFACE
42            = "android.service.notification.NotificationListenerService";
43
44    /**
45     * Implement this method to learn about new notifications as they are posted by apps.
46     *
47     * @param sbn A data structure encapsulating the original {@link android.app.Notification}
48     *            object as well as its identifying information (tag and id) and source
49     *            (package name).
50     */
51    public abstract void onNotificationPosted(StatusBarNotification sbn);
52
53    /**
54     * Implement this method to learn when notifications are removed.
55     * <P>
56     * This might occur because the user has dismissed the notification using system UI (or another
57     * notification listener) or because the app has withdrawn the notification.
58     * <P>
59     * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
60     * {@link StatusBarNotification#notification} member may be missing some heavyweight
61     * fields such as {@link android.app.Notification#contentView} and
62     * {@link android.app.Notification#largeIcon}. However, all other fields on
63     * {@link StatusBarNotification}, sufficient to match this call with a prior call to
64     * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
65     *
66     * @param sbn A data structure encapsulating at least the original information (tag and id)
67     *            and source (package name) used to post the {@link android.app.Notification} that
68     *            was just removed.
69     */
70    public abstract void onNotificationRemoved(StatusBarNotification sbn);
71
72    private final INotificationManager getNotificationInterface() {
73        if (mNoMan == null) {
74            mNoMan = INotificationManager.Stub.asInterface(
75                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
76        }
77        return mNoMan;
78    }
79
80    /**
81     * Inform the notification manager about dismissal of a single notification.
82     * <p>
83     * Use this if your listener has a user interface that allows the user to dismiss individual
84     * notifications, similar to the behavior of Android's status bar and notification panel.
85     * It should be called after the user dismisses a single notification using your UI;
86     * upon being informed, the notification manager will actually remove the notification
87     * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
88     * <P>
89     * <b>Note:</b> If your listener allows the user to fire a notification's
90     * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
91     * this method at that time <i>if</i> the Notification in question has the
92     * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
93     *
94     * @param pkg Package of the notifying app.
95     * @param tag Tag of the notification as specified by the notifying app in
96     *     {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
97     * @param id  ID of the notification as specified by the notifying app in
98     *     {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
99     */
100    public final void clearNotification(String pkg, String tag, int id) {
101        try {
102            getNotificationInterface().clearNotificationFromListener(mWrapper, pkg, tag, id);
103        } catch (android.os.RemoteException ex) {
104            Log.v(TAG, "Unable to contact notification manager", ex);
105        }
106    }
107
108    /**
109     * Inform the notification manager about dismissal of all notifications.
110     * <p>
111     * Use this if your listener has a user interface that allows the user to dismiss all
112     * notifications, similar to the behavior of Android's status bar and notification panel.
113     * It should be called after the user invokes the "dismiss all" function of your UI;
114     * upon being informed, the notification manager will actually remove all active notifications
115     * and you will get multiple {@link #onNotificationRemoved(StatusBarNotification)} callbacks.
116     *
117     * {@see #clearNotification(String, String, int)}
118     */
119    public final void clearAllNotifications() {
120        try {
121            getNotificationInterface().clearAllNotificationsFromListener(mWrapper);
122        } catch (android.os.RemoteException ex) {
123            Log.v(TAG, "Unable to contact notification manager", ex);
124        }
125    }
126
127    /**
128     * Request the list of outstanding notifications (that is, those that are visible to the
129     * current user). Useful when starting up and you don't know what's already been posted.
130     *
131     * @return An array of active notifications.
132     */
133    public StatusBarNotification[] getActiveNotifications() {
134        try {
135            return getNotificationInterface().getActiveNotificationsFromListener(mWrapper);
136        } catch (android.os.RemoteException ex) {
137            Log.v(TAG, "Unable to contact notification manager", ex);
138        }
139        return null;
140    }
141
142    @Override
143    public IBinder onBind(Intent intent) {
144        if (mWrapper == null) {
145            mWrapper = new INotificationListenerWrapper();
146        }
147        return mWrapper;
148    }
149
150    private class INotificationListenerWrapper extends INotificationListener.Stub {
151        @Override
152        public void onNotificationPosted(StatusBarNotification sbn) {
153            NotificationListenerService.this.onNotificationPosted(sbn);
154        }
155        @Override
156        public void onNotificationRemoved(StatusBarNotification sbn) {
157            NotificationListenerService.this.onNotificationRemoved(sbn);
158        }
159    }
160}
161