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