如何使用AsyncTask下载文件?

时间:2012-11-19 21:14:27

标签: android download android-asynctask

我正在使用此类下载文件:

public class DownloadService extends Service {
    String downloadUrl;
    LocalBroadcastManager mLocalBroadcastManager;
    ProgressBar progressBar;
    File sdCard = Environment.getExternalStorageDirectory();
    File dir = new File (sdCard.getAbsolutePath() + "/org.test.download/");
    double fileSize = 0;
    DownloadAsyncTask dat;
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    public DownloadService(String url,Context c, ProgressBar pBar){
        downloadUrl = url;
        mLocalBroadcastManager = LocalBroadcastManager.getInstance(c);
        progressBar = pBar;
        dat = new DownloadAsyncTask();
        dat.execute(new String[]{downloadUrl});

    }

    private boolean checkDirs(){
        if(!dir.exists()){
            return dir.mkdirs();
        }
        return true;
    }
    public void cancel(){
        dat.cancel(true);
    }
    public class DownloadAsyncTask extends AsyncTask<String, Integer, String>{

        @Override
        protected String doInBackground(String... params) {
                String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/")+1);
                if(!checkDirs()){
                    return "Making directories failed!";
                }
                try {
                    URL url = new URL(downloadUrl);
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    urlConnection.setRequestMethod("GET");
                    urlConnection.setDoOutput(true);
                    urlConnection.connect();
                    fileSize = urlConnection.getContentLength();
                    FileOutputStream fos = new FileOutputStream(new File(dir,fileName));
                    InputStream inputStream = urlConnection.getInputStream();
                    byte[] buffer = new byte[500];
                    int bufferLength = 0;
                    int percentage = 0;
                    double downloadedSize = 0;
                    while ( (bufferLength = inputStream.read(buffer)) > 0 ) 
                    {
                        if(isCancelled()){
                            break;
                        }
                        fos.write(buffer, 0, bufferLength);
                        downloadedSize += bufferLength;
                        percentage = (int) ((downloadedSize / fileSize) * 100);
                        publishProgress(percentage);
                    }
                    fos.close();
                    urlConnection.disconnect();
                } catch (Exception e) {
                    Log.e("Download Failed",e.getMessage());
                }
                if(isCancelled()){
                    return "Download cancelled!";
                }
            return "Download complete";
        }
        @Override
        protected void onProgressUpdate(Integer... values){
            super.onProgressUpdate(values[0]);
            if(progressBar != null){
                progressBar.setProgress(values[0]);
            }else{
                Log.w("status", "ProgressBar is null, please supply one!");
            }
        }

        @Override
        protected void onPreExecute(){
            mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_STARTED"));
        }

        @Override
        protected void onPostExecute(String str){
            mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_FINISHED"));
        }

        @Override
        protected void onCancelled(){
            mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_CANCELLED"));
        }

    }

}

我正在使用此功能,因为显然DownloadManagerAPI 9之前无法工作,我的目标是API 7

我有ListView解析XML文件并显示可以下载的包。

如何修改此类以接受包含URL的字符串数组并逐个下载?

或者有没有什么好方法可以下载文件列表?

1 个答案:

答案 0 :(得分:2)

考虑使用IntentService。 IntentService中的线程在后台运行,这意味着您不必处理所有乱七八糟的线程处理。

IntentService一旦完成就会终止其线程,因此您必须保留数据。

要与您的活动进行通信,请使用广播接收器。