com.sdk.download.providers.downloads.DownloadNotification.java Source code

Java tutorial

Introduction

Here is the source code for com.sdk.download.providers.downloads.DownloadNotification.java

Source

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sdk.download.providers.downloads;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;

import com.download_sdk.download.provider.R;

import java.util.Collection;
import java.util.HashMap;

/**
 * This class handles the updating of the Notification Manager for the cases
 * where there is an ongoing download. Once the download is complete (be it
 * successful or unsuccessful) it is no longer the responsibility of this
 * component to show the download in the notification manager. 1?setContentTitle
 *  2?setLargeIcon  3?setContentText  4?setContentInfo ?
 * 5?setSmallIcon ? 6?
 */
class DownloadNotification {

    Context mContext;
    HashMap<Long, NotificationItem> mNotifications;
    private SystemFacade mSystemFacade;

    static final String LOGTAG = "DownloadNotification";
    static final String WHERE_RUNNING = "(" + Downloads.COLUMN_STATUS + " >= '100') AND (" + Downloads.COLUMN_STATUS
            + " <= '199') AND (" + Downloads.COLUMN_VISIBILITY + " IS NULL OR " + Downloads.COLUMN_VISIBILITY
            + " == '" + Downloads.VISIBILITY_VISIBLE + "' OR " + Downloads.COLUMN_VISIBILITY + " == '"
            + Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED + "')";
    static final String WHERE_COMPLETED = Downloads.COLUMN_STATUS + " >= '200' AND " + Downloads.COLUMN_VISIBILITY
            + " == '" + Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED + "'";

    /**
     * This inner class is used to collate downloads that are owned by the same
     * application. This is so that only one notification line item is used for
     * all downloads of a given application.
     */
    static class NotificationItem {
        long mId; // This first db _id for the download for the app
        long mTotalCurrent = 0;
        long mTotalTotal = 0;
        int mTitleCount = 0;
        String mPackageName; // App package name
        String mDescription;
        String[] mTitles = new String[2]; // download titles.
        String mPausedText = null;
        int mStatus;

        /*
         * Add a second download to this notification item.
         */
        void addItem(String title, long currentBytes, long totalBytes) {
            mTotalCurrent += currentBytes;
            if (totalBytes <= 0 || mTotalTotal == -1) {
                mTotalTotal = -1;
            } else {
                mTotalTotal += totalBytes;
            }
            if (mTitleCount < 2) {
                mTitles[mTitleCount] = title;
            }
            mTitleCount++;
        }
    }

    /**
     * Constructor
     * 
     * @param ctx
     *            The context to use to obtain access to the Notification
     *            Service
     */
    DownloadNotification(Context ctx, SystemFacade systemFacade) {
        mContext = ctx;
        mSystemFacade = systemFacade;
        mNotifications = new HashMap<Long, NotificationItem>();
    }

    /*
     * Update the notification ui.
     */
    public void updateNotification(Collection<DownloadInfo> downloads) {
        updateActiveNotification(downloads);
        updateCompletedNotification(downloads);
    }

    private void updateActiveNotification(Collection<DownloadInfo> downloads) {
        // Collate the notifications
        mNotifications.clear();

        for (DownloadInfo download : downloads) {
            if (!isActiveAndVisible(download)) {
                continue;
            }

            String packageName = download.mPackage;
            long max = download.mTotalBytes;
            long progress = download.mCurrentBytes;
            long id = download.mId;
            String title = download.mTitle;
            if (title == null || title.length() == 0) {
                title = mContext.getResources().getString(R.string.zuimeia_sdk_download_download_unknown_title);
            }

            synchronized (mNotifications) {
                if (!mNotifications.containsKey(id)) {
                    if (download.mStatus == Downloads.STATUS_RUNNING) {
                        NotificationItem item = new NotificationItem();
                        item.mId = id;
                        item.mPackageName = packageName;
                        item.mDescription = download.mDescription;
                        item.mStatus = download.mStatus;
                        item.addItem(title, progress, max);
                        mNotifications.put(download.mId, item);
                        if (download.mStatus == Downloads.STATUS_QUEUED_FOR_WIFI && item.mPausedText == null) {
                            item.mPausedText = mContext.getResources()
                                    .getString(R.string.zuimeia_sdk_download_notification_need_wifi_for_size);
                        }
                    } else {
                        mSystemFacade.cancelNotification(id);
                    }
                }
            }
        }

        // Add the notifications
        for (NotificationItem item : mNotifications.values()) {
            // Build the notification object
            final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
            builder.setPriority(2);
            boolean hasPausedText = (item.mPausedText != null);
            int iconResource = android.R.drawable.stat_sys_download_done;
            if (hasPausedText) {
                iconResource = android.R.drawable.stat_sys_warning;
            }
            builder.setSmallIcon(iconResource);
            builder.setOngoing(true);

            boolean hasContentText = false;
            StringBuilder title = new StringBuilder(item.mTitles[0]);
            if (item.mTitleCount > 1) {
                title.append(mContext.getString(R.string.zuimeia_sdk_download_notification_filename_separator));
                title.append(item.mTitles[1]);
                if (item.mTitleCount > 2) {
                    title.append(mContext.getString(R.string.zuimeia_sdk_download_notification_filename_extras,
                            new Object[] { Integer.valueOf(item.mTitleCount - 2) }));
                }
            } else if (!TextUtils.isEmpty(item.mDescription)) {
                builder.setContentText(item.mDescription);
                hasContentText = true;
            }
            builder.setContentTitle(title);// 

            if (hasPausedText) {// ??
                builder.setContentText(item.mPausedText);
            } else {
                builder.setProgress((int) item.mTotalTotal, (int) item.mTotalCurrent, item.mTotalTotal == -1);
                if (Build.VERSION.SDK_INT >= 11) {
                    if (hasContentText) {
                        builder.setContentInfo(getDownloadingText(item.mTotalTotal, item.mTotalCurrent));
                    }
                } else {// ?android 3.0
                    builder.setContentText(String.format(mContext.getString(R.string.sdk_download_progress_percent),
                            getDownloadingText(item.mTotalTotal, item.mTotalCurrent)));
                }
            }
            // ?()
            // if (item.mStatus == Downloads.STATUS_PENDING || item.mStatus ==
            // Downloads.STATUS_RUNNING) {
            // Intent pauseIt = new
            // Intent(ZMDownloadReceiver.DOWNLOADRECEIVER_PAUSE);
            // pauseIt.setPackage(mContext.getPackageName());
            // Bundle bundle = new Bundle();
            // bundle.putLong(ZMDownloadReceiver.INTENT_DOWNLOAD_ID, item.mId);
            // bundle.putInt(ZMDownloadReceiver.INTENT_DOWNLOAD_STATUS,
            // item.mStatus);
            // pauseIt.putExtras(bundle);
            // builder.addAction(R.drawable.sdk_download_pause,
            // mContext.getString(R.string.zuimeia_sdk_download_notification_pause),
            // PendingIntent.getBroadcast(mContext, 0, pauseIt,
            // PendingIntent.FLAG_CANCEL_CURRENT));
            // }
            // ?
            if (item.mStatus != Downloads.STATUS_SUCCESS) {
                Intent cancelIt = new Intent(DownloadReceiver.DOWNLOAD_CANCEL);
                cancelIt.setPackage(mContext.getPackageName());
                Bundle bundle = new Bundle();
                bundle.putLong(DownloadReceiver.INTENT_DOWNLOAD_ID, item.mId);
                bundle.putInt(DownloadReceiver.INTENT_DOWNLOAD_STATUS, item.mStatus);
                cancelIt.putExtras(bundle);
                builder.addAction(R.drawable.sdk_download_download_cancel,
                        mContext.getString(R.string.sdk_download_notification_cancel),
                        PendingIntent.getBroadcast(mContext, 0, cancelIt, PendingIntent.FLAG_CANCEL_CURRENT));
            }

            Intent intent = new Intent(Constants.ACTION_LIST);
            intent.setClassName(mContext, DownloadReceiver.class.getName());
            intent.setData(ContentUris.withAppendedId(Downloads.getAllDownloadsContentURI(mContext), item.mId));
            intent.putExtra("multiple", item.mTitleCount > 1);

            builder.setContentIntent(PendingIntent.getBroadcast(mContext, 0, intent, 0));

            mSystemFacade.postNotification(item.mId, builder.build());
        }
    }

    private void updateCompletedNotification(Collection<DownloadInfo> downloads) {
        for (DownloadInfo download : downloads) {
            if (!isCompleteAndVisible(download)) {
                continue;
            }
            // Add the notifications
            Notification n = new Notification();
            n.icon = android.R.drawable.stat_sys_download_done;
            n.flags |= Notification.FLAG_AUTO_CANCEL;
            long id = download.mId;
            String title = download.mTitle;
            if (title == null || title.length() == 0) {
                title = mContext.getResources().getString(R.string.zuimeia_sdk_download_download_unknown_title);
            }
            Uri contentUri = ContentUris.withAppendedId(Downloads.getAllDownloadsContentURI(mContext), id);
            String caption;
            Intent intent;
            if (Downloads.isStatusError(download.mStatus)) {
                caption = mContext.getResources()
                        .getString(R.string.zuimeia_sdk_download_notification_download_failed);
                intent = new Intent(Constants.ACTION_LIST);
            } else {
                caption = mContext.getResources()
                        .getString(R.string.zuimeia_sdk_download_notification_download_complete);
                if (download.mDestination == Downloads.DESTINATION_EXTERNAL) {
                    intent = new Intent(Constants.ACTION_OPEN);
                } else {
                    intent = new Intent(Constants.ACTION_LIST);
                }
            }
            intent.setClassName(mContext.getPackageName(), DownloadReceiver.class.getName());
            intent.setData(contentUri);

            n.when = download.mLastMod;
            n.setLatestEventInfo(mContext, title, caption, PendingIntent.getBroadcast(mContext, 0, intent, 0));

            intent = new Intent(Constants.ACTION_HIDE);
            intent.setClassName(mContext.getPackageName(), DownloadReceiver.class.getName());
            intent.setData(contentUri);
            // n.deleteIntent = PendingIntent.getBroadcast(mContext, 0, intent,
            // 0); //notification??
            mSystemFacade.postNotification(download.mId, n);
        }
    }

    private boolean isActiveAndVisible(DownloadInfo download) {
        return 100 <= download.mStatus && download.mStatus < 200
                && download.mVisibility != Downloads.VISIBILITY_HIDDEN;
    }

    private boolean isCompleteAndVisible(DownloadInfo download) {
        return download.mStatus >= 200 && download.mVisibility == Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED;
    }

    /*
     * Helper function to build the downloading text.
     */
    private String getDownloadingText(long totalBytes, long currentBytes) {
        if (totalBytes <= 0) {
            return "0%";
        }
        long progress = currentBytes * 100 / totalBytes;
        StringBuilder sb = new StringBuilder();
        sb.append(progress);
        sb.append('%');
        return sb.toString();
    }

}