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