【问题标题】:Showing the DownloadManager progress on the activity without polling在没有轮询的情况下显示活动的 DownloadManager 进度
【发布时间】:2014-01-15 15:31:39
【问题描述】:

背景

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

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

问题

是否可以在不进行轮询的情况下显示进度详细信息?也许通过监听器/广播接收器?

【问题讨论】:

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


    【解决方案1】:

    这是不可能的。 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

    【讨论】:

    • 那太糟糕了。所以人们仍然需要创建自己的“引擎”来下载东西......
    • @androiddeveloper 我已经创建了一个下载文件的服务,我会在我的回答中发布这个。希望对你有帮助^^
    • 我已经开始制作一个,因为我发现这个缺少一些功能,但是谢谢。您发布的内容可能会对其他人有所帮助。
    猜你喜欢
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多