1

我正在尝试使用AsyncTaskAndroid 下载文件。我想显示一个ProgressDialog应该有一个进度条来显示下载状态的。我正在为此使用该函数并在我的函数onProgressUpdate()中实现了对的调用。但是,只有在下载文件才会弹出进度对话框。我的代码:publishProgress()doInBackground()

protected Long doInBackground(URL...urls) {
    for (int i = 0; i < urls.length; i++) {
        url = urls[i];
        try {
            URLConnection conn = url.openConnection();
            conn.connect();
            totalSize = conn.getContentLength();

            BufferedInputStream bis = new BufferedInputStream(url.openStream());
            FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/forvo_temp.mp3");
            BufferedOutputStream bos = new BufferedOutputStream(fos,1024);
            byte [] data = new byte[1024];

            int x=0; int c=0;
            while((x=bis.read(data,0,1024))>=0){
                bos.write(data,0,x);
                c += 1024;
                publishProgress(c);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return 0L; // Don't know what to do with this
}

protected void onProgressUpdate(Integer...args) {
    pd = ProgressDialog.show(context, "Downloading...", "Downloading...", true, false);
    pd.setProgress(args[0] / totalSize);
}

我猜我打电话时会下载整个文件new BufferedInputStream(url.openStream())。如何监控下载进度?

4

2 回答 2

2

用你自己的 InputStream 包装 URL 输入流,它只读取字节并“监视”状态,例如发送通知。

很简单:InputStream是一个只有一个抽象方法的抽象类:

public abstract int read() throws IOException;

在您的情况下,它应该从它包装的流中读取字节。

public class NotifcationInputStream extends InputStream {
    private InputStream in;
    private int count;
    private Collection<ByteListener> listeners = new ArrayList<ByteListener>();

    NotificationInputStream(InputStream in) {
         this.in = in;
    }

    public int read() throws IOException {
        int b = in.read(); 
        byteReceived(b);
        return b;
    }

    public void addListener(ByteListener listener) {
        listeners.add(listener);
    }

    private void byteReceived(int b) {
        for (ByteListener l : listeners) {
             l.byteReceived(b, ++count);
        }
    }
}


public interface ByteListener extends EventListener {
    public void byteReceived(int b, int count);
}

这里的问题是如何显示进程栏:您必须知道总字节数。content-length如果您的资源是静态的,您可以从 HTTP 标头获取它。否则,您需要适当的服务器支持或启发式方法。

于 2013-05-13T09:20:38.713 回答
0

此代码用于显示下载项目的总大小和下载大小。

private static final int DOWNLOAD_ONPROGRESS = 1;

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DOWNLOAD_ONPROGRESS:
        progressDialog = new ProgressDialog(this);

        progressDialog.setMessage("Downloading latest ...");
        progressDialog.setCancelable(true);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        try {
            progressDialog.show();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return progressDialog;
    default:
        return null;
    }
}

您可以使用 AsyncTask 在后台下载版本。

private class DownLoad extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        logger.info("LoadDataAsync onPreExecute");
        showDialog(DOWNLOAD_ONPROGRESS);
    }

    @Override
    protected String doInBackground(String... aurl) {
        int count = 0;

        try {
            URL url = new URL(aurl[0]);
            URLConnection urlConnection = url.openConnection();
            urlConnection.connect();

            int contentlength = urlConnection.getContentLength();
            progressDialog.setMax(contentlength);
            String PATH = "";
            File file = null;
            if (android.os.Environment.getExternalStorageState().equals(
                    android.os.Environment.MEDIA_MOUNTED)) {
                PATH = Environment.getExternalStorageDirectory()
                        + "/download/";
                file = new File(PATH);

                file.mkdirs();

                File outputFile = new File(file, "telfaz.apk");
                OutputStream fos = new FileOutputStream(outputFile);

                InputStream is = new BufferedInputStream(url.openStream());

                byte[] buffer = new byte[1024];
                long len1 = 0;
                while ((count = is.read(buffer)) != -1
                        && !downLoad.isCancelled()) {
                    len1 += count;
                    publishProgress("" + len1);
                    fos.write(buffer, 0, count);
                }
                fos.flush();
                fos.close();
                is.close();

            }
            logger.info("Success -> file downloaded succesfully. returning 'success' code");
            return Util.APK_DOWNLOAD_SUCCESS;

        } catch (IOException e) {
            logger.error("Exception in update process : "
                    + Util.getStackTrace(e));
        }
        logger.info("Failed -> file download failed. returning 'error' code");
        return Util.APK_DOWNLOAD_FAILED;
    }

    @Override
    protected void onPostExecute(String result) {
        logger.info("on DownLoad onPostExecute. result : " + result);
        progressDialog.dismiss();
        removeDialog(DOWNLOAD_ONPROGRESS);
        if (result.equalsIgnoreCase(Util.APK_DOWNLOAD_SUCCESS)) {
            Update();

        } else {
            Toast.makeText(DownloadAllContentsActivity.this,
                    getString(R.string.updateApplicationFailed),
                    Toast.LENGTH_LONG).show();

            loadDataAsync.execute();

        }

    }

    @Override
    protected void onProgressUpdate(String... values) {
        if (values != null && values.length > 0) {
            progressDialog.setProgress(Integer.parseInt(values[0]));
        }

    }


}
于 2013-05-13T12:52:25.997 回答