Example usage for android.content ContentUris withAppendedId

List of usage examples for android.content ContentUris withAppendedId

Introduction

In this page you can find the example usage for android.content ContentUris withAppendedId.

Prototype

public static Uri withAppendedId(Uri contentUri, long id) 

Source Link

Document

Appends the given ID to the end of the path.

Usage

From source file:com.mail163.email.mail.transport.Rfc822Output.java

/**
 * Write the entire message to an output stream.  This method provides buffering, so it is
 * not necessary to pass in a buffered output stream here.
 *
 * @param context system context for accessing the provider
 * @param messageId the message to write out
 * @param out the output stream to write the message to
 * @param appendQuotedText whether or not to append quoted text if this is a reply/forward
 *
 * TODO alternative parts (e.g. text+html) are not supported here.
 *//*from  w  w  w.  j  ava2  s  . c  om*/
public static void writeTo(Context context, long messageId, OutputStream out, boolean appendQuotedText,
        boolean sendBcc) throws IOException, MessagingException {
    Message message = Message.restoreMessageWithId(context, messageId);
    if (message == null) {
        // throw something?
        return;
    }

    OutputStream stream = new BufferedOutputStream(out, 1024);
    Writer writer = new OutputStreamWriter(stream);

    // Write the fixed headers.  Ordering is arbitrary (the legacy code iterated through a
    // hashmap here).

    String date = DATE_FORMAT.format(new Date(message.mTimeStamp));
    writeHeader(writer, "Date", date);

    writeEncodedHeader(writer, "Subject", message.mSubject);
    writeEncodedHeader(writer, "X-Priority", message.mPriority);
    writeHeader(writer, "Message-ID", message.mMessageId);

    writeAddressHeader(writer, "From", message.mFrom);
    writeAddressHeader(writer, "To", message.mTo);
    writeAddressHeader(writer, "Cc", message.mCc);
    // Address fields.  Note that we skip bcc unless the sendBcc argument is true
    // SMTP should NOT send bcc headers, but EAS must send it!
    if (sendBcc) {
        writeAddressHeader(writer, "Bcc", message.mBcc);
    }
    writeAddressHeader(writer, "Reply-To", message.mReplyTo);
    writeHeader(writer, "MIME-Version", "1.0");

    // Analyze message and determine if we have multiparts
    String text = buildBodyText(context, message, appendQuotedText);

    if (!Global.sendMessage.equals("")) {
        if (text.endsWith(Global.sendMessage)) {//
            text = text.substring(0, text.lastIndexOf(Global.sendMessage));
            text = text + Global.sendMessage;
        } else {
            text = text + "\n\n\n" + Global.sendMessage;
        }
    }
    Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, messageId);
    Cursor attachmentsCursor = context.getContentResolver().query(uri, Attachment.CONTENT_PROJECTION, null,
            null, null);

    try {
        int attachmentCount = attachmentsCursor.getCount();
        boolean multipart = attachmentCount > 0;
        String multipartBoundary = null;
        String multipartType = "mixed";

        // Simplified case for no multipart - just emit text and be done.
        if (!multipart) {
            if (text != null) {
                writeTextWithHeaders(writer, stream, text);
            } else {
                writer.write("\r\n"); // a truly empty message
            }
        } else {
            // continue with multipart headers, then into multipart body
            multipartBoundary = "--_com.warmtel.yimail_" + System.nanoTime();

            // Move to the first attachment; this must succeed because multipart is true
            attachmentsCursor.moveToFirst();
            if (attachmentCount == 1) {
                // If we've got one attachment and it's an ics "attachment", we want to send
                // this as multipart/alternative instead of multipart/mixed
                int flags = attachmentsCursor.getInt(Attachment.CONTENT_FLAGS_COLUMN);
                if ((flags & Attachment.FLAG_ICS_ALTERNATIVE_PART) != 0) {
                    multipartType = "alternative";
                }
            }

            writeHeader(writer, "Content-Type",
                    "multipart/" + multipartType + "; boundary=\"" + multipartBoundary + "\"");
            // Finish headers and prepare for body section(s)
            writer.write("\r\n");

            // first multipart element is the body
            if (text != null) {
                writeBoundary(writer, multipartBoundary, false);
                writeTextWithHeaders(writer, stream, text);
            }

            // Write out the attachments until we run out
            do {
                writeBoundary(writer, multipartBoundary, false);
                Attachment attachment = Attachment.getContent(attachmentsCursor, Attachment.class);
                writeOneAttachment(context, writer, stream, attachment);
                writer.write("\r\n");
            } while (attachmentsCursor.moveToNext());

            // end of multipart section
            writeBoundary(writer, multipartBoundary, true);
        }
    } finally {
        attachmentsCursor.close();
    }

    writer.flush();
    out.flush();
}

From source file:cc.softwarefactory.lokki.android.utilities.Utils.java

public static Bitmap openPhoto(Context context, long contactId) {

    Log.e(TAG, "openPhoto");
    if (context == null) {
        return null;
    }//  w w w  . j  a  v a2s  .c  om

    Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
    Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
    Cursor cursor = context.getContentResolver().query(photoUri,
            new String[] { ContactsContract.Contacts.Photo.PHOTO }, null, null, null);
    if (cursor == null) {
        return null;
    }

    try {
        if (cursor.moveToFirst()) {
            byte[] data = cursor.getBlob(0);
            if (data != null) {
                return BitmapFactory.decodeStream(new ByteArrayInputStream(data));
            }
        }
    } finally {
        cursor.close();
    }
    return null;
}

From source file:com.gzsll.downloads.DownloadNotification.java

private PendingIntent getPendingContentIntent(NotificationItem item) {
    Intent intent = new Intent();
    intent.setAction(Constants.ACTION_LIST);
    intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
    intent.setClassName(mContext.getPackageName(), DownloadReceiver.class.getName());
    intent.setData(ContentUris.withAppendedId(Downloads.ALL_DOWNLOADS_CONTENT_URI, item.mId));
    intent.putExtra("multiple", item.mTitleCount > 1);
    return PendingIntent.getBroadcast(mContext, 0, intent, 0);
}

From source file:com.mutu.gpstracker.breadcrumbs.DownloadBreadcrumbsTrackTask.java

@Override
protected void onPostExecute(Uri result) {
    super.onPostExecute(result);

    long ogtTrackId = Long.parseLong(result.getLastPathSegment());
    Uri metadataUri = Uri.withAppendedPath(ContentUris.withAppendedId(Tracks.CONTENT_URI, ogtTrackId),
            "metadata");

    BreadcrumbsTracks tracks = mAdapter.getBreadcrumbsTracks();
    Integer bcTrackId = mTrack.second;
    Integer bcBundleId = tracks.getBundleIdForTrackId(bcTrackId);
    //TODO Integer bcActivityId = tracks.getActivityIdForBundleId(bcBundleId);
    String bcDifficulty = tracks.getValueForItem(mTrack, BreadcrumbsTracks.DIFFICULTY);
    String bcRating = tracks.getValueForItem(mTrack, BreadcrumbsTracks.RATING);
    String bcPublic = tracks.getValueForItem(mTrack, BreadcrumbsTracks.ISPUBLIC);
    String bcDescription = tracks.getValueForItem(mTrack, BreadcrumbsTracks.DESCRIPTION);

    ArrayList<ContentValues> metaValues = new ArrayList<ContentValues>();
    if (bcTrackId != null) {
        metaValues.add(buildContentValues(BreadcrumbsTracks.TRACK_ID, Long.toString(bcTrackId)));
    }//from   w  w w.j  ava2s. com
    if (bcDescription != null) {
        metaValues.add(buildContentValues(BreadcrumbsTracks.DESCRIPTION, bcDescription));
    }
    if (bcDifficulty != null) {
        metaValues.add(buildContentValues(BreadcrumbsTracks.DIFFICULTY, bcDifficulty));
    }
    if (bcRating != null) {
        metaValues.add(buildContentValues(BreadcrumbsTracks.RATING, bcRating));
    }
    if (bcPublic != null) {
        metaValues.add(buildContentValues(BreadcrumbsTracks.ISPUBLIC, bcPublic));
    }
    if (bcBundleId != null) {
        metaValues.add(buildContentValues(BreadcrumbsTracks.BUNDLE_ID, Integer.toString(bcBundleId)));
    }
    //      if (bcActivityId != null)
    //      {
    //         metaValues.add(buildContentValues(BreadcrumbsTracks.ACTIVITY_ID, Integer.toString(bcActivityId)));
    //      }
    ContentResolver resolver = mContext.getContentResolver();
    resolver.bulkInsert(metadataUri, metaValues.toArray(new ContentValues[1]));

    tracks.addSyncedTrack(ogtTrackId, mTrack.second);

}

From source file:com.jio.appstore.download.DownloadNotifier.java

private void updateWithLocked(Collection<DownloadInfo> downloads) {
    final Resources res = mContext.getResources();

    // Cluster downloads together
    final Multimap<String, DownloadInfo> clustered = ArrayListMultimap.create();
    for (DownloadInfo info : downloads) {
        final String tag = buildNotificationTag(info);
        if (tag != null) {
            clustered.put(tag, info);/*www.j  a  va2 s  . co  m*/
        }
    }

    // Build notification for each cluster
    for (String tag : clustered.keySet()) {
        final int type = getNotificationTagType(tag);
        final Collection<DownloadInfo> cluster = clustered.get(tag);

        final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);

        // Use time when cluster was first shown to avoid shuffling
        final long firstShown;
        if (mActiveNotifs.containsKey(tag)) {
            firstShown = mActiveNotifs.get(tag);
        } else {
            firstShown = System.currentTimeMillis();
            mActiveNotifs.put(tag, firstShown);
        }
        builder.setWhen(firstShown);

        // Show relevant icon
        if (type == TYPE_ACTIVE) {
            builder.setSmallIcon(android.R.drawable.stat_sys_download);
        } else if (type == TYPE_WAITING) {
            builder.setSmallIcon(android.R.drawable.stat_sys_warning);
        } else if (type == TYPE_COMPLETE) {
            builder.setSmallIcon(android.R.drawable.stat_sys_download_done);
        }

        // Build action intents
        if (type == TYPE_ACTIVE || type == TYPE_WAITING) {
            // build a synthetic uri for intent identification purposes
            final Uri uri = new Uri.Builder().scheme("active-dl").appendPath(tag).build();
            final Intent intent = new Intent(Constants.ACTION_LIST, uri, mContext, DownloadReceiver.class);
            intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS, getDownloadIds(cluster));
            builder.setContentIntent(
                    PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
            builder.setOngoing(true);

        } else if (type == TYPE_COMPLETE) {
            final DownloadInfo info = cluster.iterator().next();
            final Uri uri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, info.mId);
            builder.setAutoCancel(true);

            final String action;
            if (Downloads.Impl.isStatusError(info.mStatus)) {
                action = Constants.ACTION_LIST;
            } else {
                action = Constants.ACTION_OPEN;
            }

            final Intent intent = new Intent(action, uri, mContext, DownloadReceiver.class);
            intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS, getDownloadIds(cluster));
            builder.setContentIntent(
                    PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));

            final Intent hideIntent = new Intent(Constants.ACTION_HIDE, uri, mContext, DownloadReceiver.class);
            builder.setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, hideIntent, 0));
        }

        // Calculate and show progress
        String remainingText = null;
        String percentText = null;
        if (type == TYPE_ACTIVE) {
            long current = 0;
            long total = 0;
            long speed = 0;
            synchronized (mDownloadSpeed) {
                for (DownloadInfo info : cluster) {
                    if (info.mTotalBytes != -1) {
                        current += info.mCurrentBytes;
                        total += info.mTotalBytes;
                        Long spd = mDownloadSpeed.get(info.mId);
                        if (spd != null) {
                            speed += spd;
                        }
                        //                            speed += mDownloadSpeed.get(info.mId);
                    }
                }
            }

            if (total > 0) {
                final int percent = (int) ((current * 100) / total);
                percentText = res.getString(R.string.download_percent, percent);

                if (speed > 0) {
                    final long remainingMillis = ((total - current) * 1000) / speed;
                    remainingText = res.getString(R.string.download_remaining,
                            DateUtils.formatElapsedTime(remainingMillis));
                }

                builder.setProgress(100, percent, false);
            } else {
                builder.setProgress(100, 0, true);
            }
        }

        // Build titles and description
        final Notification notif;
        if (cluster.size() == 1) {
            final DownloadInfo info = cluster.iterator().next();

            builder.setContentTitle(getDownloadTitle(res, info));

            if (type == TYPE_ACTIVE) {
                if (!TextUtils.isEmpty(info.mDescription)) {
                    builder.setContentText(info.mDescription);
                } else {
                    builder.setContentText(remainingText);
                }
                builder.setContentInfo(percentText);

            } else if (type == TYPE_WAITING) {
                builder.setContentText(res.getString(R.string.notification_download_waiting));

            } else if (type == TYPE_COMPLETE) {
                if (Downloads.Impl.isStatusError(info.mStatus)) {
                    builder.setContentText(res.getText(R.string.notification_download_failed));
                } else if (Downloads.Impl.isStatusSuccess(info.mStatus)) {
                    builder.setContentText(res.getText(R.string.notification_download_complete));
                }
            }

            notif = builder.build();

        } else {
            final NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(builder);

            for (DownloadInfo info : cluster) {
                inboxStyle.addLine(getDownloadTitle(res, info));
            }

            if (type == TYPE_ACTIVE) {
                builder.setContentTitle(
                        res.getQuantityString(R.plurals.notif_summary_active, cluster.size(), cluster.size()));
                builder.setContentText(remainingText);
                builder.setContentInfo(percentText);
                inboxStyle.setSummaryText(remainingText);

            } else if (type == TYPE_WAITING) {
                builder.setContentTitle(
                        res.getQuantityString(R.plurals.notif_summary_waiting, cluster.size(), cluster.size()));
                builder.setContentText(res.getString(R.string.notification_download_waiting));
                inboxStyle.setSummaryText(res.getString(R.string.notification_download_waiting));
            }

            notif = inboxStyle.build();
        }

        mNotifManager.notify(tag, 0, notif);
    }

    // Remove stale tags that weren't renewed
    final Iterator<String> it = mActiveNotifs.keySet().iterator();
    while (it.hasNext()) {
        final String tag = it.next();
        if (!clustered.containsKey(tag)) {
            mNotifManager.cancel(tag, 0);
            it.remove();
        }
    }
}

From source file:com.android.contacts.common.model.ContactLoaderTest.java

public void testLoadContactWithRawContactIdUri() {
    // Use content Uris that only contain the ID but use the format used in Donut
    final Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, RAW_CONTACT_ID);
    final Uri baseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, CONTACT_ID);
    final Uri lookupUri = ContentUris
            .withAppendedId(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, LOOKUP_KEY), CONTACT_ID);
    final Uri entityUri = Uri.withAppendedPath(lookupUri, Contacts.Entity.CONTENT_DIRECTORY);

    ContactQueries queries = new ContactQueries();
    mContactsProvider.expectTypeQuery(rawContactUri, RawContacts.CONTENT_ITEM_TYPE);
    queries.fetchContactIdAndLookupFromRawContactUri(rawContactUri, CONTACT_ID, LOOKUP_KEY);
    queries.fetchAllData(entityUri, CONTACT_ID, RAW_CONTACT_ID, DATA_ID, LOOKUP_KEY);

    Contact contact = assertLoadContact(rawContactUri);

    assertEquals(CONTACT_ID, contact.getId());
    assertEquals(RAW_CONTACT_ID, contact.getNameRawContactId());
    assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
    assertEquals(LOOKUP_KEY, contact.getLookupKey());
    assertEquals(lookupUri, contact.getLookupUri());
    assertEquals(1, contact.getRawContacts().size());
    assertEquals(1, contact.getStatuses().size());
    mContactsProvider.verify();//from  w w w  .j  ava2 s .  co  m
}

From source file:bander.notepad.NoteListAppCompat.java

@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
    AdapterView.AdapterContextMenuInfo info;
    try {//from w ww.  j a v a 2s  .c o m
        info = (AdapterView.AdapterContextMenuInfo) menuInfo;
    } catch (ClassCastException e) {
        return;
    }

    Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
    if (cursor == null) {
        return;
    }

    menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));

    Uri uri = ContentUris.withAppendedId(getIntent().getData(), cursor.getInt(COLUMN_INDEX_ID));

    Intent[] specifics = new Intent[1];
    specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
    MenuItem[] items = new MenuItem[1];

    Intent intent = new Intent(null, uri);
    intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
    menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0, items);

    menu.add(0, DELETE_ID, 0, R.string.menu_delete);
    // TODO: When you click on this, it crashes. I commented it out for now.
    // menu.add(0, SEND_ID, 0, R.string.menu_send);
}

From source file:at.bitfire.davdroid.resource.LocalTaskList.java

@Override
public void updateMetaData(WebDavResource.Properties properties) throws LocalStorageException {
    ContentValues values = new ContentValues();

    final String displayName = properties.getDisplayName();
    if (displayName != null)
        values.put(TaskContract.TaskLists.LIST_NAME, displayName);

    final Integer color = properties.getColor();
    if (color != null)
        values.put(TaskContract.TaskLists.LIST_COLOR, color);

    try {//  w  ww  .  java 2s .  c om
        if (values.size() > 0)
            providerClient.update(ContentUris.withAppendedId(taskListsURI(account), id), values, null, null);
    } catch (RemoteException e) {
        throw new LocalStorageException(e);
    }
}

From source file:org.gege.caldavsyncadapter.caldav.entities.DavCalendar.java

/**
 * example: content://com.android.calendar/calendars/8
 *//*from ww  w  .j a  v  a2s  .  c o  m*/
public Uri getAndroidCalendarUri() {
    return ContentUris.withAppendedId(Calendars.CONTENT_URI, this.getAndroidCalendarId());
}

From source file:com.android.providers.downloads.DownloadNotifier.java

private void updateWithLocked(Collection<DownloadInfo> downloads) {
    final Resources res = mContext.getResources();

    // Cluster downloads together
    final Multimap<String, DownloadInfo> clustered = ArrayListMultimap.create();
    for (DownloadInfo info : downloads) {
        final String tag = buildNotificationTag(info);
        if (tag != null) {
            clustered.put(tag, info);/*from   w  w  w  . j av a 2 s . c  o  m*/
        }
    }

    // Build notification for each cluster
    for (String tag : clustered.keySet()) {
        final int type = getNotificationTagType(tag);
        final Collection<DownloadInfo> cluster = clustered.get(tag);

        final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);

        // Use time when cluster was first shown to avoid shuffling
        final long firstShown;
        if (mActiveNotifs.containsKey(tag)) {
            firstShown = mActiveNotifs.get(tag);
        } else {
            firstShown = System.currentTimeMillis();
            mActiveNotifs.put(tag, firstShown);
        }
        builder.setWhen(firstShown);

        // Show relevant icon
        if (type == TYPE_ACTIVE) {
            builder.setSmallIcon(android.R.drawable.stat_sys_download);
        } else if (type == TYPE_WAITING) {
            builder.setSmallIcon(android.R.drawable.stat_sys_warning);
        } else if (type == TYPE_COMPLETE) {
            builder.setSmallIcon(android.R.drawable.stat_sys_download_done);
        }

        // Build action intents
        if (type == TYPE_ACTIVE || type == TYPE_WAITING) {
            // build a synthetic uri for intent identification purposes
            final Uri uri = new Uri.Builder().scheme("active-dl").appendPath(tag).build();
            final Intent intent = new Intent(Constants.ACTION_LIST, uri, mContext, DownloadReceiver.class);
            intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS, getDownloadIds(cluster));
            builder.setContentIntent(
                    PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
            builder.setOngoing(true);

        } else if (type == TYPE_COMPLETE) {
            final DownloadInfo info = cluster.iterator().next();
            final Uri uri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, info.mId);
            builder.setAutoCancel(true);

            final String action;
            if (Downloads.Impl.isStatusError(info.mStatus)) {
                action = Constants.ACTION_LIST;
            } else {
                if (info.mDestination != Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION) {
                    action = Constants.ACTION_OPEN;
                } else {
                    action = Constants.ACTION_LIST;
                }
            }

            final Intent intent = new Intent(action, uri, mContext, DownloadReceiver.class);
            intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS, getDownloadIds(cluster));
            builder.setContentIntent(
                    PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));

            final Intent hideIntent = new Intent(Constants.ACTION_HIDE, uri, mContext, DownloadReceiver.class);
            builder.setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, hideIntent, 0));
        }

        // Calculate and show progress
        String remainingText = null;
        String percentText = null;
        if (type == TYPE_ACTIVE) {
            long current = 0;
            long total = 0;
            long speed = 0;
            synchronized (mDownloadSpeed) {
                for (DownloadInfo info : cluster) {
                    if (info.mTotalBytes != -1) {
                        current += info.mCurrentBytes;
                        total += info.mTotalBytes;
                        speed += mDownloadSpeed.get(info.mId);
                    }
                }
            }

            if (total > 0) {
                final int percent = (int) ((current * 100) / total);
                percentText = res.getString(R.string.download_percent, percent);

                if (speed > 0) {
                    final long remainingMillis = ((total - current) * 1000) / speed;
                    remainingText = res.getString(R.string.download_remaining,
                            //                                DateUtils.formatDuration(remainingMillis)); // FIXME 
                            "" + remainingMillis);
                }

                builder.setProgress(100, percent, false);
            } else {
                builder.setProgress(100, 0, true);
            }
        }

        // Build titles and description
        final Notification notif;
        if (cluster.size() == 1) {
            final DownloadInfo info = cluster.iterator().next();

            builder.setContentTitle(getDownloadTitle(res, info));

            if (type == TYPE_ACTIVE) {
                if (!TextUtils.isEmpty(info.mDescription)) {
                    builder.setContentText(info.mDescription);
                } else {
                    builder.setContentText(remainingText);
                }
                builder.setContentInfo(percentText);

            } else if (type == TYPE_WAITING) {
                builder.setContentText(res.getString(R.string.notification_need_wifi_for_size));

            } else if (type == TYPE_COMPLETE) {
                if (Downloads.Impl.isStatusError(info.mStatus)) {
                    builder.setContentText(res.getText(R.string.notification_download_failed));
                } else if (Downloads.Impl.isStatusSuccess(info.mStatus)) {
                    builder.setContentText(res.getText(R.string.notification_download_complete));
                }
            }

            notif = builder.build();

        } else {
            final NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(builder);

            for (DownloadInfo info : cluster) {
                inboxStyle.addLine(getDownloadTitle(res, info));
            }

            if (type == TYPE_ACTIVE) {
                builder.setContentTitle(
                        res.getQuantityString(R.plurals.notif_summary_active, cluster.size(), cluster.size()));
                builder.setContentText(remainingText);
                builder.setContentInfo(percentText);
                inboxStyle.setSummaryText(remainingText);

            } else if (type == TYPE_WAITING) {
                builder.setContentTitle(
                        res.getQuantityString(R.plurals.notif_summary_waiting, cluster.size(), cluster.size()));
                builder.setContentText(res.getString(R.string.notification_need_wifi_for_size));
                inboxStyle.setSummaryText(res.getString(R.string.notification_need_wifi_for_size));
            }

            notif = inboxStyle.build();
        }

        mNotifManager.notify(tag, 0, notif);
    }

    // Remove stale tags that weren't renewed
    final Iterator<String> it = mActiveNotifs.keySet().iterator();
    while (it.hasNext()) {
        final String tag = it.next();
        if (!clustered.containsKey(tag)) {
            mNotifManager.cancel(tag, 0);
            it.remove();
        }
    }
}