使用AsyncTask下载远端资源到SD卡

来源:互联网 发布:java网络编程视频教程 编辑:程序博客网 时间:2024/06/05 19:04

下载远端资源,需要INTERNET权限;
将文件写入到SD,需要WRITE_EXTERNAL_STORAGE权限;

在AndroidManifest.xml中进行如下配置:

?
1
2
<uses-permissionandroid:name="android.permission.INTERNET"/>
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Android AsyncTask提供了简单易用的方式,执行后台操作并更新UI。

AsyncTask的3个泛型

• Param  传入数据类型
• Progress  更新UI数据类型
• Result  处理结果类型

AsyncTask的4个步骤

1、onPreExecute  执行前的操作
2、doInBackGround  后台执行的操作
3、onProgressUpdate  更新UI操作
4、onPostExecute  执行后的操作

从网络下载资源到SD卡的步骤:

1、HTTP请求资源InputStream
2、在SD中创建一个空文件
3、创建该文件的FileOutputStream
4、使用while循环,InputStream每次循环读入数据到字节数组buffer中(buffer字节数组的大小一般为1024的整数倍),FileOutputStream将buffer中的数据写入文件,直到EOF,read()方法返回-1

示例代码:
功能:下载网络资源到本地

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package lizhen.download;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
 
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
 
import android.os.AsyncTask;
 
public class DownloadAsyncTask extendsAsyncTask<String, Integer, Boolean> {
 
    protectedint size;
    protectedString errorMessage;
 
    @Override
    protectedBoolean doInBackground(String... params) {
        String url = params[0];// 资源地址
        String path = params[1];// 目标路径
        try{
            InputStream source = requestInputStream(url);// 请求源文件InputStream
            /**
             * 创建文件写入数据,并更新进度
             */
            fileWrite(source, path,new OnProgressUpdateListener() {
 
                @Override
                publicvoid onProgressUpdate(intprogress) {
                    publishProgress(progress);
                }
            });
 
        }catch (ClientProtocolException e) {
            errorMessage = e.getMessage();
            cancel(true);
            returnfalse;
        }catch (IOException e) {
            errorMessage = e.getMessage();
            cancel(true);
            returnfalse;
        }
        returntrue;
    }
 
    /**
     * 文件写入
     *
     * @param in
     *            数据源输出流
     * @param path
     *            文件路径
     * @param listener
     *            下载进度监听器
     * */
    privatevoid fileWrite(InputStream in, String path,
            OnProgressUpdateListener listener)throws IOException {
        File file = createFile(path);
        FileOutputStream fileOutputStream =new FileOutputStream(file);
        bytebuffer[] = new byte[1024];
        intprogress = 0;
        intreadBytes = 0;
        while((readBytes = in.read(buffer)) != -1) {
            progress += readBytes;
            fileOutputStream.write(buffer,0, readBytes);
            if(listener != null) {
                listener.onProgressUpdate(progress);
            }
        }
        in.close();
        fileOutputStream.close();
    }
 
    /**
     * 下载进度监听器
     * */
    privateinterface OnProgressUpdateListener {
        /**
         * 下载进度更新
         *
         * @param progress
         *            进度
         * */
        publicvoid onProgressUpdate(intprogress);
    }
 
    /**
     * 根据资源URL地址取得资源输入流
     *
     * @param url
     *            URL地址
     * @return 资源输入流
     * @throws ClientProtocolException
     * @throws IOException
     * */
    privateInputStream requestInputStream(String url)
            throwsClientProtocolException, IOException {
        InputStream result =null;
        HttpGet httpGet =new HttpGet(url);
        HttpClient httpClient =new DefaultHttpClient();
        HttpResponse httpResponse = httpClient.execute(httpGet);
        inthttpStatusCode = httpResponse.getStatusLine().getStatusCode();
        if(httpStatusCode == HttpStatus.SC_OK) {
            HttpEntity httpEntity = httpResponse.getEntity();
            size = (int) httpEntity.getContentLength();
            result = httpEntity.getContent();
        }
        returnresult;
    }
 
    /**
     * 根据文件路径创建文件
     *
     * @param path
     *            文件路径
     * @return 文件File实例
     * @return IOException
     * */
    privateFile createFile(String path) throwsIOException {
        File file =new File(path);
        file.createNewFile();
        returnfile;
    }
 
    /**
     * 返回错误信息
     *
     * @return 错误信息
     * */
    publicString getErrorString() {
        returnthis.errorMessage;
    }
 
}

功能:用户界面,更新进度条和下载进度,显示下载图片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package lizhen.download;
 
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
 
public class Download extendsActivity {
 
    privateButton startButton;
    privateProgressBar downloadProgressBar;
    privateTextView progressTextView;
    privateImageView downloadImageView;
 
    privatefinal String source = "http://www.android-study.com/resource/atm.gif"; // 源文件地址
    privatefinal String path = Environment.getExternalStorageDirectory()
            .toString() +"/atm.gif"; // 目标文件地址
 
    @Override
    publicvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.download);
 
        startButton = (Button) findViewById(R.id.download_StartButton);
        downloadProgressBar = (ProgressBar) findViewById(R.id.download_ProgressBar);
        progressTextView = (TextView) findViewById(R.id.download_ProgressTextView);
        downloadImageView = (ImageView) findViewById(R.id.download_ImageView);
 
        startButton.setOnClickListener(newView.OnClickListener() {
 
            @Override
            publicvoid onClick(View v) {
                newDownloadTask().execute(source, path);
            }
        });
    }
 
    privateclass DownloadTask extends DownloadAsyncTask {
 
        @Override
        protectedvoid onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            intprogress = values[0];
            /*
             * 更新进度条和下载百分率
             */
            downloadProgressBar.setMax(size);
            downloadProgressBar.setProgress(progress);
            intpercentage = progress * 100/ size;
            progressTextView.setText("已完成"+ percentage + "%");
        }
 
        @Override
        protectedvoid onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if(result) {
                Bitmap bitmap = BitmapFactory.decodeFile(path);
                downloadImageView.setImageBitmap(bitmap);
            }else {
                Toast.makeText(Download.this,"Error: " + errorMessage,1000)
                        .show();
            }
        }
    }
}

运行结果:

远程下载效果图


原创粉丝点击