在没有轮询的情况下显示活动的DownloadManager进度

时间:2014-01-15 15:31:40

标签: android android-activity broadcastreceiver polling android-download-manager

背景

我希望使用DownloadManager将多个文件下载到设备,并且还能够显示活动的进度,并提供比通知中显示的更多详细信息。

我知道之前曾问过这个问题(here之后),但是他们使用后台线程进行轮询,而且我不确定我能从中得到什么样的数据。

问题

是否可以在不轮询的情况下显示进度详情?也许通过监听器/ broadcastReceiver?

1 个答案:

答案 0 :(得分:0)

这是不可能的。 DownloadManager只有3个广播:

ACTION_DOWNLOAD_COMPLETE(完成) ACTION_NOTIFICATION_CLICKED(点击其通知) ACTION_VIEW_DOWNLOADS(查看文件下载)

所以,我认为有必要进行民意调查来监控进展情况。

我的下载服务:

package com.codebrew.govideodownloader;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Environment;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

public class DownloadService extends IntentService {
String urlD, name, sole;
Context conte;
static int q = -1, counter = -1;
int progress = 0, nin;
double tmp = 0;
int oldP = 0;
File file;
public static final String NOTIFICATION = "com.codebrewlabs.vidbox.ShowDownloadsActivity";
SharedPreferences pre;
NotificationManager notificationManager;
NotificationCompat.Builder mBuilder;

public DownloadService(String name) {
    super("Downloading");
}

public DownloadService() {
    super("Downloading");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    q = q + 1;
    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onCreate() {
    super.onCreate();
    conte = this;
}

@Override
protected void onHandleIntent(Intent intent) {
    try {
        notificationManager = (NotificationManager) conte
                .getSystemService(Context.NOTIFICATION_SERVICE);
        mBuilder = new NotificationCompat.Builder(conte)
                .setSmallIcon(R.drawable.vidbox_icon)
                .setContentTitle("My notification")
                .setContentText("Hello World!");
        pre = getSharedPreferences("VidBoxPref", 0);
        urlD = intent.getExtras().getString("url");
        name = intent.getExtras().getString("name");
        nin = intent.getExtras().getInt("nin");
        progress = 0;
        sole = name;
    } catch (Exception e) {
        e.printStackTrace();
    }
    try {
        double size = 0;
        final int TIMEOUT_CONNECTION = 30000;// 30sec
        final int TIMEOUT_SOCKET = 30000;// 30sec
        String imageURL = urlD;
        URL url = new URL(imageURL);
        long startTime = System.currentTimeMillis();
        Log.e("Note: ", "image download beginning: " + imageURL);
        // Open a connection to that URL.
        URLConnection ucon = url.openConnection();

        // this timeout affects how long it takes for the app to realize
        // there's a connection problem
        ucon.setReadTimeout(TIMEOUT_CONNECTION);
        ucon.setConnectTimeout(TIMEOUT_SOCKET);

        // Define InputStreams to read from the URLConnection.
        // uses 3KB download buffer
        InputStream is = ucon.getInputStream();
        size = ucon.getContentLength();
        BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
        File wallpaperDirectory = new File(
                Environment.getExternalStorageDirectory()
                        + "/Video/GoVideoDownloader");
        wallpaperDirectory.mkdirs();
        // sole = sole.replace("?", "_");
        // sole = sole.replace("|", "_");
        // sole = sole.replace("/", "_");
        // sole = sole.replace(":", "_");
        // sole = sole.replace("$", "_");
        file = new File(wallpaperDirectory + File.separator + sole);
        if (file.exists()) {
            file.delete();
        }
        file.createNewFile();
        pre.edit().putBoolean("inDownload", true).commit();
        publishP();
        FileOutputStream outStream = new FileOutputStream(file);
        byte[] buff = new byte[5 * 1024];

        // Read bytes (and store them) until there is nothing more to
        // read(-1)
        int len;
        tmp = 0;
        while ((len = inStream.read(buff)) != -1) {
            if (pre.getBoolean("cont", false)) {
                pre.edit().putBoolean("cont", false).commit();
                pre.edit().putBoolean("inDownload", false).commit();
                q--;
                pre.edit().putInt("progress", progress).commit();
                sendNotification(7, nin, sole);
                Intent in2 = new Intent(NOTIFICATION);
                in2.putExtra("progress", progress);
                in2.putExtra("running", 0);
                in2.putExtra("name", sole);
                in2.putExtra("resume", "0");
                sendBroadcast(in2);
                progress = 0;
                outStream.close();
                stopSelf();
                return;
            }
            tmp = tmp + len;
            progress = (int) (((double) tmp / size) * 100);
            pre.edit().putInt("progress", progress).commit();
            if (progress < 0)
                progress = -1 * progress;
            outStream.write(buff, 0, len);
            if (progress != oldP)
                publishP();
            oldP = progress;
        }
        tmp = size;
        progress = 100;
        q = q + 1;
        publishP();
        // clean up

        outStream.flush();
        outStream.close();
        inStream.close();
        Log.e("Note: ",
                "Download completed in "
                        + ((System.currentTimeMillis() - startTime) / 1000)
                        + " secs.");
    } catch (Exception e) {
        if (file != null) {
            if (file.exists()) {
                file.delete();
            }
        }
        pre.edit().putBoolean("inDownload", false).commit();
        int innn;
        if (e.toString()
                .equals("java.io.IOException: open failed: EACCES (Permission denied)")) {
            innn = 5;
        } else {
            innn = 1;
        }
        if (!e.toString().equals(
                "java.io.IOException: close failed: EIO (I/O error)")) {
            sendNotification(innn, nin, sole);
        }
        Intent in2 = new Intent(NOTIFICATION);
        in2.putExtra("progress", progress);
        in2.putExtra("running", 0);
        in2.putExtra("name", sole);
        q--;
        in2.putExtra("resume", "0");

        sendBroadcast(in2);
        progress = 0;
        Log.e("Error: ", "Error is:" + e.toString());
    }
}

protected void publishP() {
    try {
        pre.edit().putInt("progress", progress).commit();
        sendNotification(0, nin, sole);
        Intent in2 = new Intent(NOTIFICATION);
        if (progress == 100) {
            q--;
            pre.edit().putBoolean("inDownload", false).commit();
        }
        in2.putExtra("progress", progress);
        in2.putExtra("resume", "0");
        in2.putExtra("running", 1);
        in2.putExtra("name", sole);
        in2.putExtra("queue", q);
        pre.edit().putInt("progress", progress).commit();
        pre.edit().putInt("running", 1).commit();
        pre.edit().putString("currName", sole).commit();
        pre.edit().putInt("nowQueue", q).commit();
        sendBroadcast(in2);
    } catch (Exception e) {
        Log.e("Shit", e.toString());
    }
}

@Override
public boolean stopService(Intent name) {
    return super.stopService(name);
}

public void sendNotification(int tmout, int nin, String name) {
    if (tmout == 0) {

        // notificationManager.notify(nin, mBuilder.build());
        if (progress >= 100) {
            // notificationManager.cancel(nin);
            mBuilder.setSmallIcon(R.drawable.vidbox_icon)
                    .setContentTitle("Completed").setContentText(name)
                    .setAutoCancel(true).setOngoing(false);
            Uri ttt = Uri.parse(Environment.getExternalStorageDirectory()
                    + File.separator + "Video/GoVideoDownloader/" + name);
            Uri uri = RingtoneManager
                    .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            mBuilder.setSound(uri);
            pre.edit().putInt("retry", 1).commit();
            Intent inten = new Intent(Intent.ACTION_VIEW, ttt);
            String arr[] = name.split("\\.");
            inten.setDataAndType(ttt, "video/" + arr[arr.length - 1]);
            PendingIntent i = PendingIntent.getActivity(conte, 0, inten, 0);
            mBuilder.setContentIntent(i);
            notificationManager.notify(nin, mBuilder.build());
        } else {
            mBuilder.setContentTitle("Downloading: " + name)
                    .setContentText(progress + " %")
                    .setSmallIcon(R.drawable.vidbox_icon)
                    .setAutoCancel(false).setOngoing(true);
            mBuilder.setProgress(100, progress, false);
            notificationManager.notify(nin, mBuilder.build());
        }
    } else {
        if (tmout == 1) {
            mBuilder.setSmallIcon(R.drawable.vidbox_icon)
                    .setContentTitle("Failed").setContentText(name)
                    .setContentText(progress + " %").setAutoCancel(true)
                    .setProgress(100, progress, false).setOngoing(false);
            Uri uri = RingtoneManager
                    .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            mBuilder.setSound(uri);
            Intent intnt = new Intent(NOTIFICATION);
            intnt.putExtra("resume", "1");
            intnt.putExtra("url", urlD);
            intnt.putExtra("name", name);
            intnt.putExtra("nin", nin);
            // PendingIntent i = PendingIntent
            // .getBroadcast(conte, 0, intnt, 0);
            // mBuilder.setContentIntent(i);
        } else if (tmout == 7) {
            mBuilder.setSmallIcon(R.drawable.vidbox_icon)
                    .setContentTitle("Cancelled").setContentText(name)
                    .setAutoCancel(true).setProgress(100, progress, false)
                    .setOngoing(false);
            Intent intnt = new Intent(NOTIFICATION);
            intnt.putExtra("resume", "1");
            intnt.putExtra("url", urlD);
            intnt.putExtra("name", name);
            intnt.putExtra("nin", nin);
            // PendingIntent i = PendingIntent
            // .getBroadcast(conte, 0, intnt, 0);
            // mBuilder.setContentIntent(i);
            Uri uri = RingtoneManager
                    .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            mBuilder.setSound(uri);
        } else {
            mBuilder.setSmallIcon(R.drawable.vidbox_icon)
                    .setContentTitle("Interrupted").setContentText(name)
                    .setContentText("No storage found").setAutoCancel(true)
                    .setOngoing(false);
            Uri uri = RingtoneManager
                    .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            mBuilder.setSound(uri);
        }

        notificationManager.notify(nin, mBuilder.build());
    }
}

@Override
public void onTaskRemoved(Intent rootIntent) {
    super.onTaskRemoved(rootIntent);
    try {
        notificationManager.cancel(nin);
        pre.edit().putBoolean("inDownload", false).commit();
    } catch (Exception e) {
    }
}
}

我正在使用循环下载文件的字节,并为下载的每个字节发送广播和通知(或者每当进度增加时)。希望它有所帮助:3