Example usage for android.support.v4.app TaskStackBuilder getPendingIntent

List of usage examples for android.support.v4.app TaskStackBuilder getPendingIntent

Introduction

In this page you can find the example usage for android.support.v4.app TaskStackBuilder getPendingIntent.

Prototype

public PendingIntent getPendingIntent(int requestCode, int flags) 

Source Link

Document

Obtain a PendingIntent for launching the task constructed by this builder so far.

Usage

From source file:org.restcomm.android.sdk.RCDevice.java

void onNotificationCallCanceled(RCConnection connection) {
    if (activeCallNotification) {
        // Peer has canceled the call and there's an active call ringing, we need to cancel the notification
        String peerUsername = connection.getPeer().replaceAll(".*?sip:", "").replaceAll("@.*$", "");
        NotificationManager notificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        //There's no peer username provided in Push Notification Message, so
        //the callNotifications map cannot be populated with the right key
        notificationManager.cancel(callNotifications.get(peerUsername));

        // And then create a new notification to show that the call is missed, together with a means to call the peer. Notice
        // that if this notification is tapped, the peer will be called using the video preference of
        callIntent.setAction(ACTION_OUTGOING_CALL);
        callIntent.putExtra(RCDevice.EXTRA_DID, peerUsername);
        callIntent.putExtra(RCDevice.EXTRA_VIDEO_ENABLED,
                (connection.getRemoteMediaType() == RCConnection.ConnectionMediaType.AUDIO_VIDEO));

        // We need to create a Task Stack to make sure we maintain proper flow at all times
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        // Adds either call or message intent's Component in the stack together with all its parent activities (remember that for this to work the App Manifest needs to describe their relationship)
        stackBuilder.addParentStack(callIntent.getComponent());
        // Adds the target Intent to the top of the stack
        stackBuilder.addNextIntent(callIntent);
        // Gets a PendingIntent containing the entire back stack, but with Component as the active Activity
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

        // Service is not attached to an activity, let's use a notification instead
        NotificationCompat.Builder builder = getNotificationBuilder(true);
        builder.setSmallIcon(R.drawable.ic_phone_missed_24dp)
                .setContentTitle(connection.getPeer().replaceAll(".*?sip:", "").replaceAll("@.*$", ""))
                .setContentText("Missed call")
                //.setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.ringing_sample)) // audioManager.getResourceIdForKey(ParameterKeys.RESOURCE_SOUND_RINGING)))
                // Need this to show up as Heads-up Notification
                .setPriority(NotificationCompat.PRIORITY_HIGH).setAutoCancel(true) // cancel notification when user acts on it (Important: only applies to default notification area, not additional actions)
                .setContentIntent(resultPendingIntent);

        Notification notification = builder.build();

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            //we need to stop foreground notification
            //if we leave it, the notification 'Missed call' will not be dismissible
            //because foreground notificaiton is shown for id: callNotifications.get(peerUsername)
            stopForeground(true);//from ww  w .  j  a  va  2 s  .c  o m
        }

        notificationManager.notify(callNotifications.get(peerUsername), notification);
        // Remove the call notification, as it will be removed automatically
        //callNotifications.remove(peerUsername);

        activeCallNotification = false;
    }
}

From source file:net.sourceforge.servestream.service.MediaPlaybackService.java

private void updateNotification(boolean updateNotification) {
    String contentText;/*w  ww  . j  ava 2s. c  o  m*/

    String trackName = getTrackName();
    if (trackName == null || trackName.equals(Media.UNKNOWN_STRING)) {
        trackName = getMediaUri();
    }

    String artist = getArtistName();
    if (artist == null || artist.equals(Media.UNKNOWN_STRING)) {
        artist = getString(R.string.unknown_artist_name);
    }

    String album = getAlbumName();
    if (album == null || album.equals(Media.UNKNOWN_STRING)) {
        contentText = getString(R.string.notification_alt_info, artist);
    } else {
        contentText = getString(R.string.notification_artist_album, artist, album);
    }

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    stackBuilder.addNextIntentWithParentStack(
            new Intent(this, MediaPlayerActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
    PendingIntent contentIntent = stackBuilder.getPendingIntent((int) System.currentTimeMillis(), 0);

    NotificationCompat.Builder status = new NotificationCompat.Builder(this).setContentTitle(trackName)
            .setContentText(contentText).setContentIntent(contentIntent).setWhen(0);

    int trackId = getTrackId();
    if (mPreferences.getBoolean(PreferenceConstants.RETRIEVE_ALBUM_ART, false) && trackId != -1) {
        Bitmap bitmap = getAlbumArt(true);
        if (bitmap != null) {
            status.setLargeIcon(bitmap);
        }
    }

    status.setSmallIcon(R.drawable.notification_icon);

    Notification notification = status.build();

    // If the user has a phone running Android 4.0+ show an expanded notification
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        notification = buildExpandedView(notification, updateNotification);
    }

    if (!updateNotification) {
        startForeground(PLAYBACKSERVICE_STATUS, notification);
    } else {
        NotificationManager notificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        notificationManager.notify(PLAYBACKSERVICE_STATUS, notification);
    }
}

From source file:com.tinfoil.sms.utility.MessageService.java

@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

    /*//from w  w  w . j a v  a2  s . c  om
     * Creates a notification if there is one to be created and if the user set the preferences
     * to allow notifications
     */
    if (contentTitle != null && contentText != null
            && sharedPrefs.getBoolean(QuickPrefsActivity.NOTIFICATION_BAR_SETTING_KEY, true)) {
        Intent notifyIntent = null;
        PendingIntent in = null;

        final String address = contentTitle.toString();

        if (dba.getUnreadMessageCount() > 1) {

            MessageService.mNotificationManager.cancel(SINGLE);
            //Might need to change this.
            contentTitle = dba.getRow(address).getName();

            contentTitle = this.getString(R.string.new_message_notification_title);
            contentText = dba.getUnreadMessageCount() + " " + this.getString(R.string.unread_email_message);

            // Extra is added so the user will be brought to the main menu
            notifyIntent = new Intent(this.getApplicationContext(), ConversationView.class);
            //notifyIntent.putExtra(multipleNotificationIntent, true);
            notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

            in = PendingIntent.getActivity(this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            builder.setContentIntent(in).setContentTitle(contentTitle).setContentText(contentText)
                    .setTicker(contentTitle + ": " + contentText).setSmallIcon(R.drawable.tinfoil_logo);

            mNotificationManager.notify(MULTI, builder.build());
        } else {
            contentTitle = dba.getRow(address).getName();

            notifyIntent = new Intent(this.getApplicationContext(), SendMessageActivity.class);
            notifyIntent.putExtra(ConversationView.MESSAGE_INTENT, ConversationView.MESSAGE_VIEW);
            notifyIntent.putExtra(notificationIntent, address);
            notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

            // Adds the back stack
            stackBuilder.addParentStack(SendMessageActivity.class);

            notifyIntent.putExtra(multipleNotificationIntent, false);

            // Adds the Intent to the top of the stack
            stackBuilder.addNextIntent(notifyIntent);

            in = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

            builder.setContentIntent(in).setContentTitle(contentTitle).setContentText(contentText)
                    .setTicker(contentTitle + ": " + contentText).setSmallIcon(R.drawable.tinfoil_logo);

            mNotificationManager.notify(SINGLE, builder.build());
        }
    }

    if (sharedPrefs.getBoolean(QuickPrefsActivity.NOTIFICATION_BAR_SETTING_KEY, true)) {
        ArrayList<Entry> keyMessage = dba.getAllKeyExchangeMessages();
        if (keyMessage != null && keyMessage.size() > 0) {
            Intent notifyIntent = null;
            PendingIntent in = null;

            notifyIntent = new Intent(this.getApplicationContext(), KeyExchangeManager.class);
            notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

            // Adds the back stack
            stackBuilder.addParentStack(KeyExchangeManager.class);

            // Adds the Intent to the top of the stack
            stackBuilder.addNextIntent(notifyIntent);

            in = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

            builder.setContentIntent(in)
                    .setContentTitle(this.getString(R.string.pending_key_exchange_notification))
                    .setContentText(this.getString(R.string.pending_key_exchange_message))
                    .setTicker(this.getString(R.string.pending_key_exchange_notification))
                    .setSmallIcon(R.drawable.key_exchange);

            mNotificationManager.notify(KEY, builder.build());
        } else {
            MessageService.mNotificationManager.cancel(MessageService.KEY);
        }
    }

    this.stopSelf();
    return Service.START_NOT_STICKY;
}

From source file:org.restcomm.android.sdk.RCDevice.java

void onNotificationIntent(Intent intent) {
    String intentAction = intent.getAction();

    //if (!intentAction.equals(ACTION_NOTIFICATION_MESSAGE_DEFAULT)) {
    if (intentAction.equals(ACTION_NOTIFICATION_CALL_DEFAULT)
            || intentAction.equals(ACTION_NOTIFICATION_CALL_ACCEPT_VIDEO)
            || intentAction.equals(ACTION_NOTIFICATION_CALL_ACCEPT_AUDIO)
            || intentAction.equals(ACTION_NOTIFICATION_CALL_DECLINE)
            || intentAction.equals(ACTION_NOTIFICATION_CALL_DELETE)) {
        // The user has acted on a call notification, let's cancel it
        String username = intent.getStringExtra(EXTRA_DID).replaceAll(".*?sip:", "").replaceAll("@.*$", "");

        NotificationManager notificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(callNotifications.get(username));

        //callNotifications.remove(username);

        activeCallNotification = false;/*w  w w  . ja  va 2  s. c  o m*/
    }

    Intent actionIntent = null;
    /*
    if (intentAction.equals(ACTION_NOTIFICATION_CALL_OPEN)) {
       RCConnection connection = getLiveConnection();
       if (connection != null) {
    if (connection.isIncoming()) {
       callIntent.setAction(ACTION_INCOMING_CALL);
    }
    else {
       callIntent.setAction(ACTION_OUTGOING_CALL);
    }
    callIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    // don't forget to copy the extras to callIntent
    callIntent.putExtras(intent);
    actionIntent = callIntent;
       }
    }
    */
    if (intentAction.equals(ACTION_NOTIFICATION_CALL_DEFAULT)) {
        if (callIntent != null) {
            callIntent.setAction(ACTION_INCOMING_CALL);
            // don't forget to copy the extras to callIntent
            callIntent.putExtras(intent);
            actionIntent = callIntent;
        } else {
            Context context = getApplicationContext();
            PackageManager packageManager = context.getPackageManager();
            actionIntent = packageManager.getLaunchIntentForPackage(context.getPackageName());
        }

    } else if (intentAction.equals(ACTION_NOTIFICATION_CALL_ACCEPT_VIDEO)) {
        callIntent.setAction(ACTION_INCOMING_CALL_ANSWER_VIDEO);
        // don't forget to copy the extras
        callIntent.putExtras(intent);
        actionIntent = callIntent;
    } else if (intentAction.equals(ACTION_NOTIFICATION_CALL_ACCEPT_AUDIO)) {
        callIntent.setAction(ACTION_INCOMING_CALL_ANSWER_AUDIO);
        // don't forget to copy the extras
        callIntent.putExtras(intent);

        actionIntent = callIntent;
    } else if (intentAction.equals(ACTION_NOTIFICATION_CALL_DECLINE)
            || intentAction.equals(ACTION_NOTIFICATION_CALL_DELETE)) {
        RCConnection pendingConnection = getPendingConnection();
        if (pendingConnection != null) {
            pendingConnection.reject();
        }

        release();

        // if the call has been requested to be declined, we shouldn't do any UI handling
        return;
    } else if (intentAction.equals(ACTION_NOTIFICATION_CALL_MUTE_AUDIO)) {
        RCConnection liveConnection = getLiveConnection();
        if (liveConnection != null) {
            if (liveConnection.isAudioMuted()) {
                liveConnection.setAudioMuted(false);
            } else {
                liveConnection.setAudioMuted(true);
            }
        }

        // if the call has been requested to be muted, we shouldn't do any UI handling
        return;
    } else if (intentAction.equals(ACTION_NOTIFICATION_CALL_DISCONNECT)) {
        RCConnection liveConnection = getLiveConnection();
        if (liveConnection != null) {
            liveConnection.disconnect();

            if (!isAttached()) {
                // if the call has been requested to be disconnected, we shouldn't do any UI handling
                callIntent.setAction(ACTION_CALL_DISCONNECT);
                //callIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                actionIntent = callIntent;
                startActivity(actionIntent);
            }

            /*
            // Important if we just trigger the call intent, then after the call is disconnected we will land to the previous screen in
            // that Task Stack, which is not what we want. Instead, we want the call activity to be finished and to just remain where
            // we were. To do that we need to create a new Task Stack were we only place the call activity
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
            // Adds the target Intent to the top of the stack
            stackBuilder.addNextIntent(actionIntent);
            // Gets a PendingIntent containing the entire back stack, but with Component as the active Activity
            PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
            try {
               resultPendingIntent.send();
            }
            catch (PendingIntent.CanceledException e) {
               throw new RuntimeException("Pending Intent cancelled", e);
            }
            */
        }

        return;
    } else if (intentAction.equals(ACTION_NOTIFICATION_MESSAGE_DEFAULT)) {
        if (messageIntent == null) {
            storageManagerPreferences = new StorageManagerPreferences(this);
            String messageIntentString = storageManagerPreferences
                    .getString(RCDevice.ParameterKeys.INTENT_INCOMING_MESSAGE, null);
            if (messageIntentString != null) {
                try {
                    messageIntent = Intent.parseUri(messageIntentString, Intent.URI_INTENT_SCHEME);

                    //service was stopped and user taps on Notification case
                    if (!isInitialized()) {
                        HashMap<String, Object> parameters = StorageUtils.getParams(storageManagerPreferences);
                        try {
                            initialize(null, parameters, null);
                        } catch (RCException e) {
                            RCLogger.e(TAG, e.toString());
                        }
                    }
                } catch (URISyntaxException e) {
                    throw new RuntimeException("Failed to handle Notification");
                }
            }
        }
        messageIntent.setAction(ACTION_INCOMING_MESSAGE);

        // don't forget to copy the extras
        messageIntent.putExtras(intent);
        actionIntent = messageIntent;
        //we want to stop foreground (notification is tapped)
        stopForeground(true);
        stopRepeatingTask();
    } else {
        throw new RuntimeException("Failed to handle Notification");
    }

    // We need to create a Task Stack to make sure we maintain proper flow at all times
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    // Adds either call or message intent's Component in the stack together with all its parent activities (remember that for this to work the App Manifest needs to describe their relationship)
    stackBuilder.addParentStack(actionIntent.getComponent());
    // Adds the target Intent to the top of the stack
    stackBuilder.addNextIntent(actionIntent);
    // Gets a PendingIntent containing the entire back stack, but with Component as the active Activity
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    try {
        resultPendingIntent.send();
    } catch (PendingIntent.CanceledException e) {
        throw new RuntimeException("Pending Intent cancelled", e);
    }
}

From source file:com.concentriclivers.mms.com.android.mms.transaction.MessagingNotification.java

/**
 * updateNotification is *the* main function for building the actual notification handed to
 * the NotificationManager/*from   w ww  .j av a2 s.  c om*/
 * @param context
 * @param isNew if we've got a new message, show the ticker
 * @param uniqueThreadCount
 */
private static void updateNotification(Context context, boolean isNew, int uniqueThreadCount) {
    // TDH
    Log.d("NotificationDebug", "updateNotification()");

    // If the user has turned off notifications in settings, don't do any notifying.
    if (!MessagingPreferenceActivity.getNotificationEnabled(context)) {
        if (DEBUG) {
            Log.d(TAG, "updateNotification: notifications turned off in prefs, bailing");
        }
        // TDH
        Log.d("NotificationDebug", "Notifications not enabled!");

        return;
    }

    // Figure out what we've got -- whether all sms's, mms's, or a mixture of both.
    int messageCount = sNotificationSet.size();

    // TDH:
    Log.d("NotificationDebug", "messageCount: " + messageCount);
    if (messageCount == 0) {
        Log.d("NotificationDebug", "WTF. Should have at least one message.");
        return;
    }

    NotificationInfo mostRecentNotification = sNotificationSet.first();

    // TDH: Use NotificationCompat2 (and in other places but it is obvious where).
    final NotificationCompat2.Builder noti = new NotificationCompat2.Builder(context)
            .setWhen(mostRecentNotification.mTimeMillis);

    if (isNew) {
        noti.setTicker(mostRecentNotification.mTicker);
    }
    // TDH
    Log.d("NotificationDebug", "Creating TaskStackBuilder");

    TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
    // TDH
    Log.d("NotificationDebug", "Created TaskStackBuilder. UniqueThreadCount: " + uniqueThreadCount);

    // If we have more than one unique thread, change the title (which would
    // normally be the contact who sent the message) to a generic one that
    // makes sense for multiple senders, and change the Intent to take the
    // user to the conversation list instead of the specific thread.

    // Cases:
    //   1) single message from single thread - intent goes to ComposeMessageActivity
    //   2) multiple messages from single thread - intent goes to ComposeMessageActivity
    //   3) messages from multiple threads - intent goes to ConversationList

    final Resources res = context.getResources();
    String title = null;
    Bitmap avatar = null;
    if (uniqueThreadCount > 1) { // messages from multiple threads
        Intent mainActivityIntent = new Intent(Intent.ACTION_MAIN);

        mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
                | Intent.FLAG_ACTIVITY_CLEAR_TOP);

        mainActivityIntent.setType("vnd.android-dir/mms-sms");
        taskStackBuilder.addNextIntent(mainActivityIntent);
        title = context.getString(R.string.message_count_notification, messageCount);
    } else { // same thread, single or multiple messages
        title = mostRecentNotification.mTitle;
        BitmapDrawable contactDrawable = (BitmapDrawable) mostRecentNotification.mSender.getAvatar(context,
                null);
        if (contactDrawable != null) {
            // Show the sender's avatar as the big icon. Contact bitmaps are 96x96 so we
            // have to scale 'em up to 128x128 to fill the whole notification large icon.
            avatar = contactDrawable.getBitmap();
            if (avatar != null) {
                final int idealIconHeight = res
                        .getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
                final int idealIconWidth = res
                        .getDimensionPixelSize(android.R.dimen.notification_large_icon_width);
                if (avatar.getHeight() < idealIconHeight) {
                    // Scale this image to fit the intended size
                    avatar = Bitmap.createScaledBitmap(avatar, idealIconWidth, idealIconHeight, true);
                }
                if (avatar != null) {
                    noti.setLargeIcon(avatar);
                }
            }
        }

        taskStackBuilder.addParentStack(ComposeMessageActivity.class);
        taskStackBuilder.addNextIntent(mostRecentNotification.mClickIntent);
    }

    // TDH
    Log.d("NotificationDebug", "title: " + title);

    // Always have to set the small icon or the notification is ignored
    noti.setSmallIcon(R.drawable.stat_notify_sms);

    NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    // Update the notification.
    noti.setContentTitle(title)
            .setContentIntent(taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT));
    // TDH: Can't do these yet.
    //            .addKind(Notification.KIND_MESSAGE)
    //            .setPriority(Notification.PRIORITY_DEFAULT);     // TODO: set based on contact coming
    //                                                             // from a favorite.

    int defaults = 0;

    if (isNew) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        String vibrateWhen;
        if (sp.contains(MessagingPreferenceActivity.NOTIFICATION_VIBRATE_WHEN)) {
            vibrateWhen = sp.getString(MessagingPreferenceActivity.NOTIFICATION_VIBRATE_WHEN, null);
        } else if (sp.contains(MessagingPreferenceActivity.NOTIFICATION_VIBRATE)) {
            vibrateWhen = sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, false)
                    ? context.getString(R.string.prefDefault_vibrate_true)
                    : context.getString(R.string.prefDefault_vibrate_false);
        } else {
            vibrateWhen = context.getString(R.string.prefDefault_vibrateWhen);
        }

        boolean vibrateAlways = vibrateWhen.equals("always");
        boolean vibrateSilent = vibrateWhen.equals("silent");
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        boolean nowSilent = audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE;

        if (vibrateAlways || vibrateSilent && nowSilent) {
            defaults |= Notification.DEFAULT_VIBRATE;
        }

        String ringtoneStr = sp.getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, null);
        noti.setSound(TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr));
        if (DEBUG) {
            Log.d(TAG, "updateNotification: new message, adding sound to the notification");
        }
    }

    defaults |= Notification.DEFAULT_LIGHTS;

    noti.setDefaults(defaults);

    // set up delete intent
    noti.setDeleteIntent(PendingIntent.getBroadcast(context, 0, sNotificationOnDeleteIntent, 0));

    final Notification notification;

    if (messageCount == 1) {
        // We've got a single message

        // TDH
        Log.d("NotificationDebug",
                "Single message, with text: " + mostRecentNotification.formatBigMessage(context));

        // This sets the text for the collapsed form:
        noti.setContentText(mostRecentNotification.formatBigMessage(context));

        if (mostRecentNotification.mAttachmentBitmap != null) {
            // The message has a picture, show that

            notification = new NotificationCompat2.BigPictureStyle(noti)
                    .bigPicture(mostRecentNotification.mAttachmentBitmap)
                    // This sets the text for the expanded picture form:
                    .setSummaryText(mostRecentNotification.formatPictureMessage(context)).build();
        } else {
            // Show a single notification -- big style with the text of the whole message
            notification = new NotificationCompat2.BigTextStyle(noti)
                    .bigText(mostRecentNotification.formatBigMessage(context)).build();
        }
    } else {
        // We've got multiple messages
        if (uniqueThreadCount == 1) {
            // We've got multiple messages for the same thread.
            // Starting with the oldest new message, display the full text of each message.
            // Begin a line for each subsequent message.
            SpannableStringBuilder buf = new SpannableStringBuilder();
            NotificationInfo infos[] = sNotificationSet.toArray(new NotificationInfo[sNotificationSet.size()]);
            int len = infos.length;
            for (int i = len - 1; i >= 0; i--) {
                NotificationInfo info = infos[i];

                buf.append(info.formatBigMessage(context));

                if (i != 0) {
                    buf.append('\n');
                }
            }

            noti.setContentText(context.getString(R.string.message_count_notification, messageCount));

            // Show a single notification -- big style with the text of all the messages
            notification = new NotificationCompat2.BigTextStyle(noti).bigText(buf)
                    // Forcibly show the last line, with the app's smallIcon in it, if we 
                    // kicked the smallIcon out with an avatar bitmap
                    .setSummaryText((avatar == null) ? null : " ").build();
        } else {
            // Build a set of the most recent notification per threadId.
            HashSet<Long> uniqueThreads = new HashSet<Long>(sNotificationSet.size());
            ArrayList<NotificationInfo> mostRecentNotifPerThread = new ArrayList<NotificationInfo>();
            Iterator<NotificationInfo> notifications = sNotificationSet.iterator();
            while (notifications.hasNext()) {
                NotificationInfo notificationInfo = notifications.next();
                if (!uniqueThreads.contains(notificationInfo.mThreadId)) {
                    uniqueThreads.add(notificationInfo.mThreadId);
                    mostRecentNotifPerThread.add(notificationInfo);
                }
            }
            // When collapsed, show all the senders like this:
            //     Fred Flinstone, Barry Manilow, Pete...
            noti.setContentText(formatSenders(context, mostRecentNotifPerThread));
            NotificationCompat2.InboxStyle inboxStyle = new NotificationCompat2.InboxStyle(noti);

            // We have to set the summary text to non-empty so the content text doesn't show
            // up when expanded.
            inboxStyle.setSummaryText(" ");

            // At this point we've got multiple messages in multiple threads. We only
            // want to show the most recent message per thread, which are in
            // mostRecentNotifPerThread.
            int uniqueThreadMessageCount = mostRecentNotifPerThread.size();
            int maxMessages = Math.min(MAX_MESSAGES_TO_SHOW, uniqueThreadMessageCount);

            for (int i = 0; i < maxMessages; i++) {
                NotificationInfo info = mostRecentNotifPerThread.get(i);
                inboxStyle.addLine(info.formatInboxMessage(context));
            }
            notification = inboxStyle.build();
            if (DEBUG) {
                Log.d(TAG, "updateNotification: multi messages," + " showing inboxStyle notification");
            }
        }
    }

    // TDH
    Log.d("NotificationDebug", "Showing notification: " + notification);

    nm.notify(NOTIFICATION_ID, notification);
}