Example usage for android.text SpannableStringBuilder SpannableStringBuilder

List of usage examples for android.text SpannableStringBuilder SpannableStringBuilder

Introduction

In this page you can find the example usage for android.text SpannableStringBuilder SpannableStringBuilder.

Prototype

public SpannableStringBuilder() 

Source Link

Document

Create a new SpannableStringBuilder with empty contents

Usage

From source file:com.tct.mail.browse.ConversationItemView.java

private void calculateTextsAndBitmaps() {
    startTimer(PERF_TAG_CALCULATE_TEXTS_BITMAPS);

    if (mSelectedConversationSet != null) {
        mSelected = mSelectedConversationSet.contains(mHeader.conversation);
    }/*from w  ww .  ja va 2 s.c  om*/
    setSelected(mSelected);
    mHeader.gadgetMode = mGadgetMode;

    updateBackground();

    mHeader.sendersDisplayText = new SpannableStringBuilder();

    mHeader.hasDraftMessage = mHeader.conversation.numDrafts() > 0;

    // Parse senders fragments.
    if (mHeader.preserveSendersText) {
        // This is a special view that doesn't need special sender formatting
        mHeader.sendersDisplayText = new SpannableStringBuilder(mHeader.sendersText);
        loadImages();
    } else if (mHeader.conversation.conversationInfo != null) {
        Context context = getContext();
        mHeader.messageInfoString = SendersView.createMessageInfo(context, mHeader.conversation, true);
        int maxChars = ConversationItemViewCoordinates.getSendersLength(context, mCoordinates.getMode(),
                mHeader.conversation.hasAttachments);
        mHeader.displayableEmails = new ArrayList<String>();
        mHeader.displayableNames = new ArrayList<String>();
        mHeader.styledNames = new ArrayList<SpannableString>();

        SendersView.format(context, mHeader.conversation.conversationInfo, mHeader.messageInfoString.toString(),
                maxChars, mHeader.styledNames, mHeader.displayableNames, mHeader.displayableEmails, mAccount,
                mDisplayedFolder.shouldShowRecipients(), true);

        if (mHeader.displayableEmails.isEmpty() || mHeader.hasDraftMessage) {//TS: junwei-xu 2015-1-22 EMAIL BUGFIX_900708 MOD
            mHeader.displayableEmails.add(mAccount);
            mHeader.displayableNames.add(mAccount);
        }

        // If we have displayable senders, load their thumbnails
        loadImages();
    } else {
        LogUtils.wtf(LOG_TAG, "Null conversationInfo");
    }

    if (mHeader.isLayoutValid()) {
        pauseTimer(PERF_TAG_CALCULATE_TEXTS_BITMAPS);
        return;
    }
    startTimer(PERF_TAG_CALCULATE_FOLDERS);

    pauseTimer(PERF_TAG_CALCULATE_FOLDERS);

    // Paper clip icon.
    mHeader.paperclip = null;
    if (mHeader.conversation.hasAttachments) {
        mHeader.paperclip = ATTACHMENT;
    }

    startTimer(PERF_TAG_CALCULATE_SENDER_SUBJECT);

    pauseTimer(PERF_TAG_CALCULATE_SENDER_SUBJECT);
    pauseTimer(PERF_TAG_CALCULATE_TEXTS_BITMAPS);
}

From source file:org.getlantern.firetweet.provider.FiretweetDataProvider.java

private void showMentionsNotification(AccountPreferences pref, long position) {
    final long accountId = pref.getAccountId();
    final Context context = getContext();
    final Resources resources = context.getResources();
    final NotificationManager nm = getNotificationManager();
    final Expression selection;
    if (pref.isNotificationFollowingOnly()) {
        selection = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId),
                Expression.greaterThan(Statuses.STATUS_ID, position),
                Expression.equals(Statuses.IS_FOLLOWING, 1));
    } else {//from   w  w  w. j a  v a2 s.co  m
        selection = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId),
                Expression.greaterThan(Statuses.STATUS_ID, position));
    }
    final String filteredSelection = Utils.buildStatusFilterWhereClause(Mentions.TABLE_NAME, selection)
            .getSQL();
    final String[] userProjection = { Statuses.USER_ID, Statuses.USER_NAME, Statuses.USER_SCREEN_NAME };
    final String[] statusProjection = { Statuses.STATUS_ID, Statuses.USER_ID, Statuses.USER_NAME,
            Statuses.USER_SCREEN_NAME, Statuses.TEXT_UNESCAPED, Statuses.STATUS_TIMESTAMP };
    final Cursor statusCursor = mDatabaseWrapper.query(Mentions.TABLE_NAME, statusProjection, filteredSelection,
            null, null, null, Statuses.SORT_ORDER_TIMESTAMP_DESC);
    final Cursor userCursor = mDatabaseWrapper.query(Mentions.TABLE_NAME, userProjection, filteredSelection,
            null, Statuses.USER_ID, null, Statuses.SORT_ORDER_TIMESTAMP_DESC);
    try {
        final int usersCount = userCursor.getCount();
        final int statusesCount = statusCursor.getCount();
        if (statusesCount == 0 || usersCount == 0)
            return;
        final String accountName = Utils.getAccountName(context, accountId);
        final String accountScreenName = Utils.getAccountScreenName(context, accountId);
        final int idxStatusText = statusCursor.getColumnIndex(Statuses.TEXT_UNESCAPED),
                idxStatusId = statusCursor.getColumnIndex(Statuses.STATUS_ID),
                idxStatusTimestamp = statusCursor.getColumnIndex(Statuses.STATUS_TIMESTAMP),
                idxStatusUserName = statusCursor.getColumnIndex(Statuses.USER_NAME),
                idxStatusUserScreenName = statusCursor.getColumnIndex(Statuses.USER_SCREEN_NAME),
                idxUserName = userCursor.getColumnIndex(Statuses.USER_NAME),
                idxUserScreenName = userCursor.getColumnIndex(Statuses.USER_NAME),
                idxUserId = userCursor.getColumnIndex(Statuses.USER_NAME);

        final CharSequence notificationTitle = resources.getQuantityString(R.plurals.N_new_mentions,
                statusesCount, statusesCount);
        final String notificationContent;
        userCursor.moveToFirst();
        final String displayName = UserColorNameUtils.getUserNickname(context, userCursor.getLong(idxUserId),
                mNameFirst ? userCursor.getString(idxUserName) : userCursor.getString(idxUserScreenName));
        if (usersCount == 1) {
            notificationContent = context.getString(R.string.notification_mention, displayName);
        } else {
            notificationContent = context.getString(R.string.notification_mention_multiple, displayName,
                    usersCount - 1);
        }

        // Add rich notification and get latest tweet timestamp
        long when = -1, statusId = -1;
        final InboxStyle style = new InboxStyle();
        for (int i = 0, j = Math.min(statusesCount, 5); statusCursor.moveToPosition(i) && i < j; i++) {
            if (when == -1) {
                when = statusCursor.getLong(idxStatusTimestamp);
            }
            if (statusId == -1) {
                statusId = statusCursor.getLong(idxStatusId);
            }
            final SpannableStringBuilder sb = new SpannableStringBuilder();
            sb.append(UserColorNameUtils.getUserNickname(context, statusCursor.getLong(idxUserId),
                    mNameFirst ? statusCursor.getString(idxStatusUserName)
                            : statusCursor.getString(idxStatusUserScreenName)));
            sb.setSpan(new StyleSpan(Typeface.BOLD), 0, sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            sb.append(' ');
            sb.append(statusCursor.getString(idxStatusText));
            style.addLine(sb);
        }
        if (mNameFirst) {
            style.setSummaryText(accountName);
        } else {
            style.setSummaryText("@" + accountScreenName);
        }

        // Setup notification
        final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
        builder.setAutoCancel(true);
        builder.setSmallIcon(R.drawable.ic_stat_mention);
        builder.setTicker(notificationTitle);
        builder.setContentTitle(notificationTitle);
        builder.setContentText(notificationContent);
        builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
        builder.setContentIntent(getContentIntent(context, AUTHORITY_MENTIONS, accountId));
        builder.setDeleteIntent(getDeleteIntent(context, AUTHORITY_MENTIONS, accountId, statusId));
        builder.setNumber(statusesCount);
        builder.setWhen(when);
        builder.setStyle(style);
        builder.setColor(pref.getNotificationLightColor());
        setNotificationPreferences(builder, pref, pref.getMentionsNotificationType());
        nm.notify("mentions_" + accountId, NOTIFICATION_ID_MENTIONS_TIMELINE, builder.build());
        Utils.sendPebbleNotification(context, notificationContent);
    } finally {
        statusCursor.close();
        userCursor.close();
    }
}

From source file:com.android.messaging.datamodel.BugleNotifications.java

/**
 * buildBoldedMessage - build a formatted message where the title is bold, there's a
 * separator, then the message./*  www  .  j  ava2  s.c  o m*/
 */
private static CharSequence buildBoldedMessage(final String title, final CharSequence message,
        final Uri attachmentUri, final String attachmentType, final int separatorId) {
    final Context context = Factory.get().getApplicationContext();
    final SpannableStringBuilder spanBuilder = new SpannableStringBuilder();

    // Boldify the title (which is the sender's name)
    if (!TextUtils.isEmpty(title)) {
        spanBuilder.append(title);
        spanBuilder.setSpan(new StyleSpan(Typeface.BOLD), 0, title.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    if (!TextUtils.isEmpty(message)) {
        if (spanBuilder.length() > 0) {
            spanBuilder.append(context.getString(separatorId));
        }
        spanBuilder.append(message);
    }
    if (attachmentUri != null) {
        if (spanBuilder.length() > 0) {
            final String separator = context.getString(R.string.notification_separator);
            spanBuilder.append(separator);
        }
        spanBuilder.append(formatAttachmentTag(null, attachmentType));
    }
    return spanBuilder;
}

From source file:com.android.messaging.datamodel.BugleNotifications.java

static CharSequence formatAttachmentTag(final String author, final String attachmentType) {
    final Context context = Factory.get().getApplicationContext();
    final TextAppearanceSpan notificationSecondaryText = new TextAppearanceSpan(context,
            R.style.NotificationSecondaryText);
    final SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
    if (!TextUtils.isEmpty(author)) {
        final TextAppearanceSpan notificationSenderSpan = new TextAppearanceSpan(context,
                R.style.NotificationSenderText);
        spannableStringBuilder.append(author);
        spannableStringBuilder.setSpan(notificationSenderSpan, 0, author.length(), 0);
        final String separator = context.getString(R.string.notification_separator);
        spannableStringBuilder.append(separator);
    }//from   ww  w.java2s . co  m
    final int start = spannableStringBuilder.length();
    // The default attachment type is an image, since that's what was originally
    // supported. When there's no content type, assume it's an image.
    int message = R.string.notification_picture;
    if (ContentType.isAudioType(attachmentType)) {
        message = R.string.notification_audio;
    } else if (ContentType.isVideoType(attachmentType)) {
        message = R.string.notification_video;
    } else if (ContentType.isVCardType(attachmentType)) {
        message = R.string.notification_vcard;
    }
    spannableStringBuilder.append(context.getText(message));
    spannableStringBuilder.setSpan(notificationSecondaryText, start, spannableStringBuilder.length(), 0);
    return spannableStringBuilder;
}

From source file:com.android.messaging.datamodel.MessageNotificationState.java

static CharSequence applyWarningTextColor(final Context context, final CharSequence text) {
    if (text == null) {
        return null;
    }//  w w  w .ja  va  2s  .c  o m
    final SpannableStringBuilder spanBuilder = new SpannableStringBuilder();
    spanBuilder.append(text);
    spanBuilder.setSpan(
            new ForegroundColorSpan(context.getResources().getColor(R.color.notification_warning_color)), 0,
            text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return spanBuilder;
}

From source file:kr.wdream.storyshop.AndroidUtilities.java

public static CharSequence generateSearchName(String name, String name2, String q) {
    if (name == null && name2 == null) {
        return "";
    }//  w w w .  ja v a  2 s  . com
    SpannableStringBuilder builder = new SpannableStringBuilder();
    String wholeString = name;
    if (wholeString == null || wholeString.length() == 0) {
        wholeString = name2;
    } else if (name2 != null && name2.length() != 0) {
        wholeString += " " + name2;
    }
    wholeString = wholeString.trim();
    String lower = " " + wholeString.toLowerCase();

    int index;
    int lastIndex = 0;
    while ((index = lower.indexOf(" " + q, lastIndex)) != -1) {
        int idx = index - (index == 0 ? 0 : 1);
        int end = q.length() + (index == 0 ? 0 : 1) + idx;

        if (lastIndex != 0 && lastIndex != idx + 1) {
            builder.append(wholeString.substring(lastIndex, idx));
        } else if (lastIndex == 0 && idx != 0) {
            builder.append(wholeString.substring(0, idx));
        }

        String query = wholeString.substring(idx, end);
        if (query.startsWith(" ")) {
            builder.append(" ");
        }
        query = query.trim();
        builder.append(AndroidUtilities.replaceTags("<c#ff4d83b3>" + query + "</c>"));

        lastIndex = end;
    }

    if (lastIndex != -1 && lastIndex != wholeString.length()) {
        builder.append(wholeString.substring(lastIndex, wholeString.length()));
    }

    return builder;
}

From source file:com.ferdi2005.secondgram.AndroidUtilities.java

public static CharSequence generateSearchName(String name, String name2, String q) {
    if (name == null && name2 == null) {
        return "";
    }/*from w w w .jav a2s . co m*/
    SpannableStringBuilder builder = new SpannableStringBuilder();
    String wholeString = name;
    if (wholeString == null || wholeString.length() == 0) {
        wholeString = name2;
    } else if (name2 != null && name2.length() != 0) {
        wholeString += " " + name2;
    }
    wholeString = wholeString.trim();
    String lower = " " + wholeString.toLowerCase();

    int index;
    int lastIndex = 0;
    while ((index = lower.indexOf(" " + q, lastIndex)) != -1) {
        int idx = index - (index == 0 ? 0 : 1);
        int end = q.length() + (index == 0 ? 0 : 1) + idx;

        if (lastIndex != 0 && lastIndex != idx + 1) {
            builder.append(wholeString.substring(lastIndex, idx));
        } else if (lastIndex == 0 && idx != 0) {
            builder.append(wholeString.substring(0, idx));
        }

        String query = wholeString.substring(idx, Math.min(wholeString.length(), end));
        if (query.startsWith(" ")) {
            builder.append(" ");
        }
        query = query.trim();

        int start = builder.length();
        builder.append(query);
        builder.setSpan(new ForegroundColorSpan(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4)),
                start, start + query.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        lastIndex = end;
    }

    if (lastIndex != -1 && lastIndex != wholeString.length()) {
        builder.append(wholeString.substring(lastIndex, wholeString.length()));
    }

    return builder;
}

From source file:org.brandroid.openmanager.activities.OpenExplorer.java

@SuppressWarnings("unused")
public void updatePagerTitle(int page) {
    TextView tvLeft = null; // (TextView)findViewById(R.id.title_left);
    TextView tvRight = null; //(TextView)findViewById(R.id.title_right);
    String left = "";
    SpannableStringBuilder ssb = new SpannableStringBuilder();
    for (int i = 0; i < page; i++) {
        OpenFragment f = mViewPagerAdapter.getItem(i);
        if (f instanceof ContentFragment) {
            OpenPath p = ((ContentFragment) f).getPath();
            left += p.getName();/*w  w w .  jav a  2s  . com*/
            if (p.isDirectory() && !left.endsWith("/"))
                left += "/";
        }
    }
    SpannableString srLeft = new SpannableString(left);
    srLeft.setSpan(new ForegroundColorSpan(Color.GRAY), 0, left.length(), Spanned.SPAN_COMPOSING);
    ssb.append(srLeft);
    //ssb.setSpan(new ForegroundColorSpan(Color.GRAY), 0, left.length(), Spanned.SPAN_COMPOSING);
    OpenFragment curr = mViewPagerAdapter.getItem(page);
    if (curr instanceof ContentFragment) {
        OpenPath pCurr = ((ContentFragment) curr).getPath();
        ssb.append(pCurr.getName());
        if (pCurr.isDirectory())
            ssb.append("/");
    }
    String right = "";
    for (int i = page + 1; i < mViewPagerAdapter.getCount(); i++) {
        OpenFragment f = mViewPagerAdapter.getItem(i);
        if (f instanceof ContentFragment) {
            OpenPath p = ((ContentFragment) f).getPath();
            right += p.getName();
            if (p.isDirectory() && !right.endsWith("/"))
                right += "/";
        }
    }
    SpannableString srRight = new SpannableString(right);
    srRight.setSpan(new ForegroundColorSpan(Color.GRAY), 0, right.length(), Spanned.SPAN_COMPOSING);
    ssb.append(srRight);
    updateTitle(ssb);
}

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

/**
 * updateNotification is *the* main function for building the actual notification handed to
 * the NotificationManager//from  w ww.  j  a  va  2s.c  o m
 * @param context
 * @param newThreadId the new thread id
 * @param uniqueThreadCount
 * @param notificationSet the set of notifications to display
 */
private static void updateNotification(Context context, long newThreadId, int uniqueThreadCount,
        SortedSet<NotificationInfo> notificationSet) {
    boolean isNew = newThreadId != THREAD_NONE;
    CMConversationSettings conversationSettings = CMConversationSettings.getOrNew(context, newThreadId);

    // If the user has turned off notifications in settings, don't do any notifying.
    if ((isNew && !conversationSettings.getNotificationEnabled())
            || !MessagingPreferenceActivity.getNotificationEnabled(context)) {
        if (DEBUG) {
            Log.d(TAG, "updateNotification: notifications turned off in prefs, bailing");
        }
        return;
    }

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

    final NotificationCompat.Builder noti = new NotificationCompat.Builder(context)
            .setWhen(mostRecentNotification.mTimeMillis);

    if (isNew) {
        noti.setTicker(mostRecentNotification.mTicker);
    }

    // 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;
    PendingIntent pendingIntent = null;
    boolean isMultiNewMessages = MessageUtils.isMailboxMode() ? messageCount > 1 : uniqueThreadCount > 1;
    if (isMultiNewMessages) { // messages from multiple threads
        Intent mainActivityIntent = getMultiThreadsViewIntent(context);
        pendingIntent = PendingIntent.getActivity(context, 0, mainActivityIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        title = context.getString(R.string.message_count_notification, messageCount);
    } else { // same thread, single or multiple messages
        title = mostRecentNotification.mTitle;
        avatar = mostRecentNotification.mSender.getAvatar(context);
        noti.setSubText(mostRecentNotification.mSimName); // no-op in single SIM case
        if (avatar != 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.
            final int idealIconHeight = res
                    .getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
            final int idealIconWidth = res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width);
            noti.setLargeIcon(BitmapUtil.getRoundedBitmap(avatar, idealIconWidth, idealIconHeight));
        }

        pendingIntent = PendingIntent.getActivity(context, 0, mostRecentNotification.mClickIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }
    // Always have to set the small icon or the notification is ignored
    noti.setSmallIcon(R.drawable.stat_notify_sms);

    NotificationManagerCompat nm = NotificationManagerCompat.from(context);

    // Update the notification.
    noti.setContentTitle(title).setContentIntent(pendingIntent)
            .setColor(context.getResources().getColor(R.color.mms_theme_color))
            .setCategory(Notification.CATEGORY_MESSAGE).setPriority(Notification.PRIORITY_DEFAULT); // TODO: set based on contact coming
                                                                                                                                                                                                                                  // from a favorite.

    // Tag notification with all senders.
    for (NotificationInfo info : notificationSet) {
        Uri peopleReferenceUri = info.mSender.getPeopleReferenceUri();
        if (peopleReferenceUri != null) {
            noti.addPerson(peopleReferenceUri.toString());
        }
    }

    int defaults = 0;

    if (isNew) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);

        if (conversationSettings.getVibrateEnabled()) {
            String pattern = conversationSettings.getVibratePattern();

            if (!TextUtils.isEmpty(pattern)) {
                noti.setVibrate(parseVibratePattern(pattern));
            } else {
                defaults |= Notification.DEFAULT_VIBRATE;
            }
        }

        String ringtoneStr = conversationSettings.getNotificationTone();
        noti.setSound(TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr));
        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));

    // See if QuickMessage pop-up support is enabled in preferences
    boolean qmPopupEnabled = MessagingPreferenceActivity.getQuickMessageEnabled(context);

    // Set up the QuickMessage intent
    Intent qmIntent = null;
    if (mostRecentNotification.mIsSms) {
        // QuickMessage support is only for SMS
        qmIntent = new Intent();
        qmIntent.setClass(context, QuickMessagePopup.class);
        qmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
                | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        qmIntent.putExtra(QuickMessagePopup.SMS_FROM_NAME_EXTRA, mostRecentNotification.mSender.getName());
        qmIntent.putExtra(QuickMessagePopup.SMS_FROM_NUMBER_EXTRA, mostRecentNotification.mSender.getNumber());
        qmIntent.putExtra(QuickMessagePopup.SMS_NOTIFICATION_OBJECT_EXTRA, mostRecentNotification);
    }

    // Start getting the notification ready
    final Notification notification;

    //Create a WearableExtender to add actions too
    WearableExtender wearableExtender = new WearableExtender();

    if (messageCount == 1 || uniqueThreadCount == 1) {
        // Add the Quick Reply action only if the pop-up won't be shown already
        if (!qmPopupEnabled && qmIntent != null) {

            // This is a QR, we should show the keyboard when the user taps to reply
            qmIntent.putExtra(QuickMessagePopup.QR_SHOW_KEYBOARD_EXTRA, true);

            // Create the pending intent and add it to the notification
            CharSequence qmText = context.getText(R.string.menu_reply);
            PendingIntent qmPendingIntent = PendingIntent.getActivity(context, 0, qmIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            noti.addAction(R.drawable.ic_reply, qmText, qmPendingIntent);

            //Wearable
            noti.extend(wearableExtender.addAction(
                    new NotificationCompat.Action.Builder(R.drawable.ic_reply, qmText, qmPendingIntent)
                            .build()));
        }

        // Add the 'Mark as read' action
        CharSequence markReadText = context.getText(R.string.qm_mark_read);
        Intent mrIntent = new Intent();
        mrIntent.setClass(context, QmMarkRead.class);
        mrIntent.putExtra(QmMarkRead.SMS_THREAD_ID, mostRecentNotification.mThreadId);
        PendingIntent mrPendingIntent = PendingIntent.getBroadcast(context, 0, mrIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        noti.addAction(R.drawable.ic_mark_read, markReadText, mrPendingIntent);

        // Add the Call action
        CharSequence callText = context.getText(R.string.menu_call);
        Intent callIntent = new Intent(Intent.ACTION_CALL);
        callIntent.setData(Uri.parse("tel:" + mostRecentNotification.mSender.getNumber()));
        PendingIntent callPendingIntent = PendingIntent.getActivity(context, 0, callIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        noti.addAction(R.drawable.ic_menu_call, callText, callPendingIntent);

        //Wearable
        noti.extend(wearableExtender.addAction(
                new NotificationCompat.Action.Builder(R.drawable.ic_menu_call, callText, callPendingIntent)
                        .build()));

        //Set up remote input
        String replyLabel = context.getString(R.string.qm_wear_voice_reply);
        RemoteInput remoteInput = new RemoteInput.Builder(QuickMessageWear.EXTRA_VOICE_REPLY)
                .setLabel(replyLabel).build();
        //Set up pending intent for voice reply
        Intent voiceReplyIntent = new Intent(context, QuickMessageWear.class);
        voiceReplyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
                | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        voiceReplyIntent.putExtra(QuickMessageWear.SMS_CONATCT, mostRecentNotification.mSender.getName());
        voiceReplyIntent.putExtra(QuickMessageWear.SMS_SENDER, mostRecentNotification.mSender.getNumber());
        voiceReplyIntent.putExtra(QuickMessageWear.SMS_THEAD_ID, mostRecentNotification.mThreadId);
        PendingIntent voiceReplyPendingIntent = PendingIntent.getActivity(context, 0, voiceReplyIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        //Wearable voice reply action
        NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply,
                context.getString(R.string.qm_wear_reply_by_voice), voiceReplyPendingIntent)
                        .addRemoteInput(remoteInput).build();
        noti.extend(wearableExtender.addAction(action));
    }

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

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

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

            NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(noti)
                    .bigPicture(mostRecentNotification.mAttachmentBitmap)
                    .setSummaryText(mostRecentNotification.formatPictureMessage(context));

            notification = noti.setStyle(bigPictureStyle).build();
        } else {
            // Show a single notification -- big style with the text of the whole message
            NotificationCompat.BigTextStyle bigTextStyle1 = new NotificationCompat.BigTextStyle(noti)
                    .bigText(mostRecentNotification.formatBigMessage(context));

            notification = noti.setStyle(bigTextStyle1).build();
        }
        if (DEBUG) {
            Log.d(TAG, "updateNotification: single message notification");
        }
    } else {
        // We've got multiple messages
        if (!isMultiNewMessages) {
            // 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[] = notificationSet.toArray(new NotificationInfo[messageCount]);
            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
            NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
            bigTextStyle.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 : " ");
            notification = noti.setStyle(bigTextStyle).build();
            if (DEBUG) {
                Log.d(TAG, "updateNotification: multi messages for single thread");
            }
        } else {
            // Build a set of the most recent notification per threadId.
            HashSet<Long> uniqueThreads = new HashSet<Long>(messageCount);
            ArrayList<NotificationInfo> mostRecentNotifPerThread = new ArrayList<NotificationInfo>();
            Iterator<NotificationInfo> notifications = notificationSet.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));
            NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.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();

            uniqueThreads.clear();
            mostRecentNotifPerThread.clear();

            if (DEBUG) {
                Log.d(TAG, "updateNotification: multi messages," + " showing inboxStyle notification");
            }
        }
    }

    notifyUserIfFullScreen(context, title);
    nm.notify(NOTIFICATION_ID, notification);

    // Trigger the QuickMessage pop-up activity if enabled
    // But don't show the QuickMessage if the user is in a call or the phone is ringing
    if (qmPopupEnabled && qmIntent != null) {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE && !ConversationList.mIsRunning
                && !ComposeMessageActivity.mIsRunning) {
            context.startActivity(qmIntent);
        }
    }
}

From source file:org.getlantern.firetweet.provider.FiretweetDataProvider.java

private void showMessagesNotification(AccountPreferences pref, StringLongPair[] pairs,
        ContentValues[] valuesArray) {//ww w . ja v a 2 s  .com
    final long accountId = pref.getAccountId();
    final long prevOldestId = mReadStateManager.getPosition(TAG_OLDEST_MESSAGES, String.valueOf(accountId));
    long oldestId = -1;
    for (final ContentValues contentValues : valuesArray) {
        final long messageId = contentValues.getAsLong(DirectMessages.MESSAGE_ID);
        oldestId = oldestId < 0 ? messageId : Math.min(oldestId, messageId);
        if (messageId <= prevOldestId)
            return;
    }
    mReadStateManager.setPosition(TAG_OLDEST_MESSAGES, String.valueOf(accountId), oldestId, false);
    final Context context = getContext();
    final Resources resources = context.getResources();
    final NotificationManager nm = getNotificationManager();
    final ArrayList<Expression> orExpressions = new ArrayList<>();
    final String prefix = accountId + "-";
    final int prefixLength = prefix.length();
    final Set<Long> senderIds = new CompactHashSet<>();
    for (StringLongPair pair : pairs) {
        final String key = pair.getKey();
        if (key.startsWith(prefix)) {
            final long senderId = Long.parseLong(key.substring(prefixLength));
            senderIds.add(senderId);
            final Expression expression = Expression.and(Expression.equals(DirectMessages.SENDER_ID, senderId),
                    Expression.greaterThan(DirectMessages.MESSAGE_ID, pair.getValue()));
            orExpressions.add(expression);
        }
    }
    orExpressions
            .add(Expression.notIn(new Column(DirectMessages.SENDER_ID), new RawItemArray(senderIds.toArray())));
    final Expression selection = Expression.and(Expression.equals(DirectMessages.ACCOUNT_ID, accountId),
            Expression.greaterThan(DirectMessages.MESSAGE_ID, prevOldestId),
            Expression.or(orExpressions.toArray(new Expression[orExpressions.size()])));
    final String filteredSelection = selection.getSQL();
    final String[] userProjection = { DirectMessages.SENDER_ID, DirectMessages.SENDER_NAME,
            DirectMessages.SENDER_SCREEN_NAME };
    final String[] messageProjection = { DirectMessages.MESSAGE_ID, DirectMessages.SENDER_ID,
            DirectMessages.SENDER_NAME, DirectMessages.SENDER_SCREEN_NAME, DirectMessages.TEXT_UNESCAPED,
            DirectMessages.MESSAGE_TIMESTAMP };
    final Cursor messageCursor = mDatabaseWrapper.query(DirectMessages.Inbox.TABLE_NAME, messageProjection,
            filteredSelection, null, null, null, DirectMessages.DEFAULT_SORT_ORDER);
    final Cursor userCursor = mDatabaseWrapper.query(DirectMessages.Inbox.TABLE_NAME, userProjection,
            filteredSelection, null, DirectMessages.SENDER_ID, null, DirectMessages.DEFAULT_SORT_ORDER);
    try {
        final int usersCount = userCursor.getCount();
        final int messagesCount = messageCursor.getCount();
        if (messagesCount == 0 || usersCount == 0)
            return;
        final String accountName = Utils.getAccountName(context, accountId);
        final String accountScreenName = Utils.getAccountScreenName(context, accountId);
        final int idxMessageText = messageCursor.getColumnIndex(DirectMessages.TEXT_UNESCAPED),
                idxMessageTimestamp = messageCursor.getColumnIndex(DirectMessages.MESSAGE_TIMESTAMP),
                idxMessageId = messageCursor.getColumnIndex(DirectMessages.MESSAGE_ID),
                idxMessageUserId = messageCursor.getColumnIndex(DirectMessages.SENDER_ID),
                idxMessageUserName = messageCursor.getColumnIndex(DirectMessages.SENDER_NAME),
                idxMessageUserScreenName = messageCursor.getColumnIndex(DirectMessages.SENDER_SCREEN_NAME),
                idxUserName = userCursor.getColumnIndex(DirectMessages.SENDER_NAME),
                idxUserScreenName = userCursor.getColumnIndex(DirectMessages.SENDER_NAME),
                idxUserId = userCursor.getColumnIndex(DirectMessages.SENDER_NAME);

        final CharSequence notificationTitle = resources.getQuantityString(R.plurals.N_new_messages,
                messagesCount, messagesCount);
        final String notificationContent;
        userCursor.moveToFirst();
        final String displayName = UserColorNameUtils.getUserNickname(context, userCursor.getLong(idxUserId),
                mNameFirst ? userCursor.getString(idxUserName) : userCursor.getString(idxUserScreenName));
        if (usersCount == 1) {
            if (messagesCount == 1) {
                notificationContent = context.getString(R.string.notification_direct_message, displayName);
            } else {
                notificationContent = context.getString(R.string.notification_direct_message_multiple_messages,
                        displayName, messagesCount);
            }
        } else {
            notificationContent = context.getString(R.string.notification_direct_message_multiple_users,
                    displayName, usersCount - 1, messagesCount);
        }

        final LongSparseArray<Long> idsMap = new LongSparseArray<>();
        // Add rich notification and get latest tweet timestamp
        long when = -1;
        final InboxStyle style = new InboxStyle();
        for (int i = 0; messageCursor.moveToPosition(i) && i < messagesCount; i++) {
            if (when < 0) {
                when = messageCursor.getLong(idxMessageTimestamp);
            }
            if (i < 5) {
                final SpannableStringBuilder sb = new SpannableStringBuilder();
                sb.append(UserColorNameUtils.getUserNickname(context, messageCursor.getLong(idxUserId),
                        mNameFirst ? messageCursor.getString(idxMessageUserName)
                                : messageCursor.getString(idxMessageUserScreenName)));
                sb.setSpan(new StyleSpan(Typeface.BOLD), 0, sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                sb.append(' ');
                sb.append(messageCursor.getString(idxMessageText));
                style.addLine(sb);
            }
            final long userId = messageCursor.getLong(idxMessageUserId);
            final long messageId = messageCursor.getLong(idxMessageId);
            idsMap.put(userId, Math.max(idsMap.get(userId, -1L), messageId));
        }
        if (mNameFirst) {
            style.setSummaryText(accountName);
        } else {
            style.setSummaryText("@" + accountScreenName);
        }
        final StringLongPair[] positions = new StringLongPair[idsMap.size()];
        for (int i = 0, j = idsMap.size(); i < j; i++) {
            positions[i] = new StringLongPair(String.valueOf(idsMap.keyAt(i)), idsMap.valueAt(i));
        }

        // Setup notification
        final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
        builder.setAutoCancel(true);
        builder.setSmallIcon(R.drawable.ic_stat_direct_message);
        builder.setTicker(notificationTitle);
        builder.setContentTitle(notificationTitle);
        builder.setContentText(notificationContent);
        builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
        builder.setContentIntent(getContentIntent(context, AUTHORITY_DIRECT_MESSAGES, accountId));
        builder.setContentIntent(getDeleteIntent(context, AUTHORITY_DIRECT_MESSAGES, accountId, positions));
        builder.setNumber(messagesCount);
        builder.setWhen(when);
        builder.setStyle(style);
        builder.setColor(pref.getNotificationLightColor());
        setNotificationPreferences(builder, pref, pref.getDirectMessagesNotificationType());
        nm.notify("messages_" + accountId, NOTIFICATION_ID_DIRECT_MESSAGES, builder.build());
        Utils.sendPebbleNotification(context, notificationContent);
    } finally {
        messageCursor.close();
        userCursor.close();
    }
}