1 package com.example.android.activenotifications;
2 /*
3 * Copyright 2015 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 
18 import android.app.Notification;
19 import android.app.NotificationManager;
20 import android.app.PendingIntent;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.Bundle;
24 import android.service.notification.StatusBarNotification;
25 import android.support.v4.app.Fragment;
26 import android.support.v4.app.NotificationCompat;
27 import android.view.LayoutInflater;
28 import android.view.View;
29 import android.view.ViewGroup;
30 import android.widget.TextView;
31 
32 import com.example.android.common.logger.Log;
33 
34 /**
35  * A fragment that allows notifications to be enqueued.
36  */
37 public class ActiveNotificationsFragment extends Fragment {
38 
39     /**
40      * The request code can be any number as long as it doesn't match another request code used
41      * in the same app.
42      */
43     private static final int REQUEST_CODE = 2323;
44 
45     private static final String TAG = "ActiveNotificationsFragment";
46 
47     private static final String NOTIFICATION_GROUP =
48             "com.example.android.activenotifications.notification_type";
49 
50     private static final int NOTIFICATION_GROUP_SUMMARY_ID = 1;
51 
52     private NotificationManager mNotificationManager;
53 
54     private TextView mNumberOfNotifications;
55 
56     // Every notification needs a unique ID otherwise the previous one would be overwritten. This
57     // variable is incremented when used.
58     private static int sNotificationId = NOTIFICATION_GROUP_SUMMARY_ID + 1;
59 
60     private PendingIntent mDeletePendingIntent;
61 
62     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)63     public View onCreateView(LayoutInflater inflater, ViewGroup container,
64             Bundle savedInstanceState) {
65         return inflater.inflate(R.layout.fragment_notification_builder, container, false);
66     }
67 
68     @Override
onResume()69     public void onResume() {
70         super.onResume();
71         updateNumberOfNotifications();
72     }
73 
74     @Override
onViewCreated(View view, Bundle savedInstanceState)75     public void onViewCreated(View view, Bundle savedInstanceState) {
76         super.onViewCreated(view, savedInstanceState);
77         mNotificationManager = (NotificationManager) getActivity().getSystemService(
78                 Context.NOTIFICATION_SERVICE);
79         mNumberOfNotifications = (TextView) view.findViewById(R.id.number_of_notifications);
80 
81         // Supply actions to the button that is displayed on screen.
82         View.OnClickListener onClickListener = new View.OnClickListener() {
83             @Override
84             public void onClick(View v) {
85                 switch (v.getId()) {
86                     case R.id.add_notification: {
87                         addNotificationAndUpdateSummaries();
88                         break;
89                     }
90                 }
91             }
92         };
93         view.findViewById(R.id.add_notification).setOnClickListener(onClickListener);
94 
95         // [BEGIN create_pending_intent_for_deletion]
96         // Create a PendingIntent to be fired upon deletion of a Notification.
97         Intent deleteIntent = new Intent(ActiveNotificationsActivity.ACTION_NOTIFICATION_DELETE);
98         mDeletePendingIntent = PendingIntent.getBroadcast(getActivity(),
99                 REQUEST_CODE, deleteIntent, 0);
100         // [END create_pending_intent_for_deletion]
101     }
102 
103     /**
104      * Adds a new {@link Notification} with sample data and sends it to the system.
105      * Then updates the current number of displayed notifications for this application and
106      * creates a notification summary if more than one notification exists.
107      */
addNotificationAndUpdateSummaries()108     private void addNotificationAndUpdateSummaries() {
109         // [BEGIN create_notification]
110         // Create a Notification and notify the system.
111         final NotificationCompat.Builder builder = new NotificationCompat.Builder(getActivity())
112                 .setSmallIcon(R.mipmap.ic_notification)
113                 .setContentTitle(getString(R.string.app_name))
114                 .setContentText(getString(R.string.sample_notification_content))
115                 .setAutoCancel(true)
116                 .setDeleteIntent(mDeletePendingIntent)
117                 .setGroup(NOTIFICATION_GROUP);
118 
119         final Notification notification = builder.build();
120         mNotificationManager.notify(getNewNotificationId(), notification);
121         // [END create_notification]
122         Log.i(TAG, "Add a notification");
123 
124         updateNotificationSummary();
125         updateNumberOfNotifications();
126     }
127 
128     /**
129      * Adds/updates/removes the notification summary as necessary.
130      */
updateNotificationSummary()131     protected void updateNotificationSummary() {
132         final StatusBarNotification[] activeNotifications = mNotificationManager
133                 .getActiveNotifications();
134 
135         int numberOfNotifications = activeNotifications.length;
136         // Since the notifications might include a summary notification remove it from the count if
137         // it is present.
138         for (StatusBarNotification notification : activeNotifications) {
139           if (notification.getId() == NOTIFICATION_GROUP_SUMMARY_ID) {
140             numberOfNotifications--;
141             break;
142           }
143         }
144 
145         if (numberOfNotifications > 1) {
146             // Add/update the notification summary.
147             String notificationContent = getString(R.string.sample_notification_summary_content,
148                     "" + numberOfNotifications);
149             final NotificationCompat.Builder builder = new NotificationCompat.Builder(getActivity())
150                     .setSmallIcon(R.mipmap.ic_notification)
151                     .setStyle(new NotificationCompat.BigTextStyle()
152                             .setSummaryText(notificationContent))
153                     .setGroup(NOTIFICATION_GROUP)
154                     .setGroupSummary(true);
155             final Notification notification = builder.build();
156             mNotificationManager.notify(NOTIFICATION_GROUP_SUMMARY_ID, notification);
157         } else {
158             // Remove the notification summary.
159             mNotificationManager.cancel(NOTIFICATION_GROUP_SUMMARY_ID);
160         }
161     }
162 
163     /**
164      * Requests the current number of notifications from the {@link NotificationManager} and
165      * display them to the user.
166      */
updateNumberOfNotifications()167     protected void updateNumberOfNotifications() {
168         // [BEGIN get_active_notifications]
169         // Query the currently displayed notifications.
170         final StatusBarNotification[] activeNotifications = mNotificationManager
171                 .getActiveNotifications();
172         // [END get_active_notifications]
173         final int numberOfNotifications = activeNotifications.length;
174         mNumberOfNotifications.setText(getString(R.string.active_notifications,
175                 numberOfNotifications));
176         Log.i(TAG, getString(R.string.active_notifications, numberOfNotifications));
177     }
178 
179     /**
180      * Retrieves a unique notification ID.
181      */
getNewNotificationId()182     public int getNewNotificationId() {
183         int notificationId = sNotificationId++;
184 
185         // Unlikely in the sample, but the int will overflow if used enough so we skip the summary
186         // ID. Most apps will prefer a more deterministic way of identifying an ID such as hashing
187         // the content of the notification.
188         if (notificationId == NOTIFICATION_GROUP_SUMMARY_ID) {
189             notificationId = sNotificationId++;
190         }
191         return notificationId;
192     }
193 }
194