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