Okhttp下载图片,音频,文件

简单的网络请求

1
2
3
4
5
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();

图片

  1. 首先得到网络的输入流,然后使用BitmapFactory将输入流转换成图片。

    1
    2
    InputStream in = response.body().byteStream();
    Bitmap bitmap = BitmapFactory.decodeStream(in);
  2. 保存到本地。这里首先创建文件夹,然后新创建一个jpg文件,用缓冲流包装文件的输出流,最后利用图片压缩将图片写入到jpg文件中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public void saveBitmap(String path,Bitmap bitmap, String fileName) {
    File dirFile = new File(path);
    BufferedOutputStream bos = null;
    if (!dirFile.exists()) {
    dirFile.mkdirs();
    }
    try {
    File dayFile = new File(path, fileName + ".jpg");
    bos = new BufferedOutputStream(new FileOutputStream(dayFile));
    //图片压缩,100代表不压缩
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);

    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }
    try {
    bos.flush();
    bos.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
  3. 从本地读取照片。从本地读取照片是很简单的,只需要利用BitmapFactory的解析文件的方法,解析目标图片路径即可。

    1
    Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());

音频,文件下载

首先得到输入流,然后读取输入流的字节,写入到对象文件的输出流即可

1
2
3
4
5
6
7
8
9
10
11
12
InputStream in = null;
OutputStream out = null;
if(response != null) {
in = response.body().byteStream();
out = new FileOutputStream(saveFile);
byte[] b = new byte[1024];
int len;
while((len = in.read(b)) != -1) {
out.write(b,0,len);
}
response.body().close();
}

断点下载文件

1
2
3
4
5
6
7
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
//断点下载,指定从哪个字节开始下载
.addHeader("RANGE", "bytes=" + downloadedLength + "-")
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();

下面代码是实现断点下载文件的一个很重要的任务类。实现的任务有下载,暂停下载,取消下载等功能。大概流程为:查看本地保存的目的路径是否存在对应的文件,有则记录文件的大小。然后使用getContentLength()方法来得到需要下载文件的大小。假如记录大小和实际大小相等,则证明不需要下载,如不相等则进行断点下载。RandomAccessFile的使用是因为它可以指定位置读,指定位置写的一个类,故可以实现断点下载。通常开发过程中,多用于多线程下载一个大文件.

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
public class DownloadTask extends AsyncTask<String, Integer, Integer> {

private DownloadListener mDownListener;
private boolean isCanceled = false;
private boolean isPaused = false;
private int lastProgress;

public DownloadTask(DownloadListener downloadListener) {
mDownListener = downloadListener;
}

@Override
protected Integer doInBackground(String... strings) {
InputStream is = null;
//可读可写,在实现断点下载时优先考虑
RandomAccessFile saveFile = null;
File file = null;
try {
long downloadedLength = 0; //记录已下载的文件长度
String downloadUrl = strings[0];
String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
file = new File(directory + fileName);
if (file.exists()) {
downloadedLength = file.length();
}
long contentLength = getContentLength(downloadUrl); //实际文件长度
if (contentLength == 0) {
return Constants.TYPE_FAILED;
} else if (contentLength == downloadedLength) {
return Constants.TYPE_SUCCESS;
}


OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
//断点下载,指定从哪个字节开始下载
.addHeader("RANGE", "bytes=" + downloadedLength + "-")
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();

if (response != null) {
is = response.body().byteStream();
saveFile = new RandomAccessFile(file, "rw");
saveFile.seek(downloadedLength); //跳过已下载的字节
byte[] b = new byte[1024];
int total = 0;
int len;
while ((len = is.read(b)) != -1) {
if (isCanceled) {
return Constants.TYPE_CANCELED;
} else if (isPaused) {
return Constants.TYPE_PAUSED;
} else {
total += len;
saveFile.write(b, 0, len);
int progress = (int) ((total + downloadedLength) * 100 / contentLength);
publishProgress(progress);
}
}
response.body().close();
return Constants.TYPE_SUCCESS;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (saveFile != null) {
saveFile.close();
}
if (isCanceled && file != null) {
file.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return Constants.TYPE_FAILED;
}

@Override
public void onProgressUpdate(Integer... values) {
int progress = values[0];
if (progress > lastProgress) {
mDownListener.onProgress(progress);
lastProgress = progress;
}
}

@Override
protected void onPostExecute(Integer status) {
switch (status) {
case Constants.TYPE_SUCCESS:
mDownListener.onSuccess();
break;
case Constants.TYPE_FAILED:
mDownListener.onFailed();
break;
case Constants.TYPE_PAUSED:
mDownListener.onPaused();
break;
case Constants.TYPE_CANCELED:
mDownListener.onCanceled();
break;
default:
break;
}
}

public void pauseDownload(){
isPaused= true;
}
public void cancelDownload(){
isCanceled = true;
}

private long getContentLength(String downloadUrl) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();
if (response != null && response.isSuccessful()) {
long contentLength = response.body().contentLength();
response.body().close();
return contentLength;
}
return 0;
}
}

相关源码位置

-------------本文结束感谢您的阅读-------------