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