小结
分批下载:向服务器请求数据回来时,分3次下载,(也可以多次),首先来一次请求 获取总长以及设置步长
之后用RandomAccessFile随机流的seek的方法来保存长度,以便下一次读取继续下载;
断点续传及进度:调用RequestBody.create 的原方法,在原方法的上做修改,使用source去使用buffer读取并下载,在connectLength方法中记录上一次的上传的长度(需要从服务器获取)
具体代码
package com.example.test;
import android.Manifest;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.Util;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "---";
private Button textDownLoad;
private Button textUpload;
private SeekBar seekBar;
private String download_url = "http://uvideo.spriteapp.cn/video/2019/0512/56488d0a-7465-11e9-b91b-1866daeb0df1_wpd.mp4";
private String upload_url = "http://192.168.43.79/hfs/";
private Handler handler = new Handler();
private Button textUploads;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
initView();
}
private void initView() {
textDownLoad = findViewById(R.id.text_downLoad);
textUpload = findViewById(R.id.text_upload);
seekBar = findViewById(R.id.seek_bar);
textUploads = findViewById(R.id.text_uploads);
textDownLoad.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
downLoad();
}
});
textUpload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
upLoad();
}
});
textUploads.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
upLoads();
}
});
}
private File file_ups;
private void upLoads() {
file_ups = new File("/sdcard/ada.mp4");
OkHttpClient client = new OkHttpClient.Builder().build();
// RequestBody.create()
RequestBody requestBody = new RequestBody() {
@Override
public @Nullable
MediaType contentType() {
return MediaType.parse("media/mp4");
}
//15000 这个长度是从服务器端获取的 但是目前hfs无法做到
@Override
public long contentLength() {
return file_ups.length() - 15000;
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(file_ups);
Buffer buffer = new Buffer();
long len = 0;
while ((len = source.read(buffer, 1024)) != -1) {
sink.write(buffer, len);
}
} finally {
Util.closeQuietly(source);
}
}
};
MultipartBody.Builder formDataPart = new MultipartBody.Builder()
.addFormDataPart("file", "test2.mp4", requestBody);
Request request = new Request.Builder()
.url(upload_url)
.post(formDataPart.build())
.header("Connection","keep-alive")
.header("Connect","*/*")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
private File file_up;
private void upLoad() {
file_up = new File("/sdcard/ada.mp4");
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
Interceptor interceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request token = chain.request().newBuilder().header("token", "123321").build();
String path = chain.request().url().encodedPath();
String host = chain.request().url().host();
String method = chain.request().method();
Log.i(TAG, "地址: " + path);
Log.i(TAG, "主机地址: " + host);
Log.i(TAG, "请求方法: " + method);
return chain.proceed(token);
}
};
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(httpLoggingInterceptor)
.build();
// RequestBody requestBody = RequestBody.create(MediaType.parse("media/mp4"), "/sdcard/ada.mp4");
RequestBody requestBody = new RequestBody() {
@Override
public @Nullable
MediaType contentType() {
return MediaType.parse("media/mp4");
}
@Override
public long contentLength() {
return file_up.length();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(file_up);
Buffer buffer = new Buffer();
long length = file_up.length();
long len = 0;
long count = 0;
while ((len = source.read(buffer, 1024)) != -1) {
sink.write(buffer, len);
count += len;
final int values = (int) (count * 100 / length);
Log.i(TAG, "writeTo: " + values);
seekBar.setProgress(values);
}
} finally {
Util.closeQuietly(source);
}
}
};
MultipartBody.Builder formDataPart = new MultipartBody.Builder().addFormDataPart("file", "tests.mp4", requestBody);
formDataPart.setType(MultipartBody.FORM);
Request request = new Request.Builder()
.url(upload_url)
.post(formDataPart.build())
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
private long number;
private long max;
private long count;
private void downLoad() {
OkHttpClient client = new OkHttpClient.Builder().build();
Request request = new Request.Builder()
.get()
.url(download_url)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
max = response.body().contentLength();
number = max / 3;
Log.i(TAG, "onResponse: " + max);
startLoad();
}
});
}
private File file;
private void startLoad() {
OkHttpClient client = new OkHttpClient.Builder().build();
file = new File("/sdcard/ada.mp4");
Request request = new Request.Builder()
.header("Range", "bytes=0-" + number)
.url(download_url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
ResponseBody body = response.body();
InputStream is = body.byteStream();
byte[] b = new byte[1024];
int len = 0;
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
randomAccessFile.seek(0);
while ((len = is.read(b)) != -1) {
count += len;
final int values = (int) (count * 100 / max);
randomAccessFile.write(b, 0, len);
Log.i(TAG, "Thread1: " + values);
handler.post(new Runnable() {
@Override
public void run() {
seekBar.setProgress(values);
}
});
}
}
});
Request request1 = new Request.Builder()
.header("Range", "bytes=" + number + "-" + number * 2)
.url(download_url)
.build();
client.newCall(request1).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
ResponseBody body = response.body();
InputStream is = body.byteStream();
byte[] b = new byte[1024];
int len = 0;
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
randomAccessFile.seek(number);
while ((len = is.read(b)) != -1) {
count += len;
final int values = (int) (count * 100 / max);
randomAccessFile.write(b, 0, len);
Log.i(TAG, "Thread2: " + values);
handler.post(new Runnable() {
@Override
public void run() {
seekBar.setProgress(values);
}
});
}
}
});
Request request2 = new Request.Builder()
.header("Range", "bytes=" + number * 2 + "-" + max)
.url(download_url)
.build();
client.newCall(request2).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
ResponseBody body = response.body();
InputStream is = body.byteStream();
byte[] b = new byte[1024];
int len = 0;
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
randomAccessFile.seek(number * 2);
while ((len = is.read(b)) != -1) {
count += len;
final int values = (int) (count * 100 / max);
randomAccessFile.write(b, 0, len);
Log.i(TAG, "Thread3: " + values);
handler.post(new Runnable() {
@Override
public void run() {
seekBar.setProgress(values);
}
});
}
}
});
}
}