前言
最近接到一个需求,做一个.xls
文件下载功能 方便用户统计数据
没什么难度 直接撸起袖子开干
已封装工具类 基于Android Rxjava+Okhttp+Retrofit
实现效果
需要用的工具类如下 以封装完毕 使用简单
FileDownLoadObserver
public abstract class FileDownLoadObserver<T> extends DefaultObserver<T> {
public abstract void onDownLoadStart();
//下载成功的回调
public abstract void onDownLoadSuccess(T t);
//下载失败回调
public abstract void onDownLoadFail(Throwable throwable);
//下载进度监听
public abstract void onDownLoadProgress(int progress, long total);
@Override
protected void onStart() {
super.onStart();
onDownLoadStart();
}
@Override
public void onNext(T t) {
onDownLoadSuccess(t);
}
@Override
public void onError(Throwable e) {
onDownLoadFail(e);
}
@Override
public void onComplete() {
}
public File saveFile(ResponseBody responseBody, String destFileDir, String destFileName)
throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
try {
is = responseBody.byteStream();
final long total = responseBody.contentLength();
long sum = 0;
File dir = new File(destFileDir);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, destFileName);
fos = new FileOutputStream(file);
while ((len = is.read(buf)) != -1) {
sum += len;
fos.write(buf, 0, len);
final long finalSum = sum;
//这里就是对进度的监听回调
onDownLoadProgress((int) (finalSum * 100 / total), total);
}
fos.flush();
return file;
} finally {
try {
if (is != null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fos != null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
DownLoadUtil 工具
public static String default_path = Environment.getExternalStorageDirectory().
getAbsolutePath() + "/download";
public static void downLoad(String url, String path, String fileName) {
downLoad(url, path, fileName, new FileDownLoadObserver<File>() {
@Override
public void onDownLoadStart() {
//开始
}
@Override
public void onDownLoadSuccess(File file) {
//成功
}
@Override
public void onDownLoadFail(Throwable throwable) {
//失败
}
@Override
public void onDownLoadProgress(int progress, long total) {
//下载进度
}
});
}
public static void downLoad(String url, final String path, final String fileName,
final FileDownLoadObserver<File> fileDownLoadObserver) {
Retrofit retrofit = new Retrofit.Builder()
.client(new OkHttpClient())
.baseUrl(URL_DEFAULT)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofit.create(ApiService.class)
.downLoadFile(url)
.subscribeOn(Schedulers.io())//subscribeOn和ObserOn必须在io线程,否则出错
.observeOn(Schedulers.io())
.observeOn(Schedulers.computation())//需要
.map(new Function<ResponseBody, File>() {
@Override
public File apply(@NonNull ResponseBody responseBody) throws Exception {
return fileDownLoadObserver.saveFile(responseBody,
default_path + path, fileName);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(fileDownLoadObserver);
}
使用方法
long currentTime = System.currentTimeMillis();
Date date = new Date(currentTime);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日");
String url = "http://vfx.mtime.cn/Video/2019/03/18/mp4/190318214226685784.mp4";
//点击了文件下载
DownLoadUtil.downLoad(url, "", formatter.format(date) + "订单报表.mp4",
new FileDownLoadObserver<File>() {
@Override
public void onDownLoadStart() {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onDownLoadSuccess(File file) {
progressBar.setVisibility(View.GONE);
ToastHelper.showToast(OrderManagerActivity.this, "下载完成");
mBtnGoLookFile.setVisibility(View.VISIBLE);
mBtnGoLookFile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri contentUri = FileProvider.getUriForFile
(OrderManagerActivity.this, "com.jk.house", file);
intent.setDataAndType(contentUri, "*/*");
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivity(intent);
mBtnGoLookFile.setVisibility(View.GONE);
}
});
}
@Override
public void onDownLoadFail(Throwable throwable) {
progressBar.setVisibility(View.GONE);
ToastHelper.showToast(OrderManagerActivity.this, "文件下载失败,请重试");
Log.e(TAG, " down load error == >> " + throwable.getMessage());
}
@Override
public void onDownLoadProgress(int progress, long total) {
runOnUiThread(new Runnable() {
@Override
public void run() {
progressBar.setMax(100);
progressBar.setProgress(progress);
}
});
}
});
NumberProgressBar
Github地址
NumberProgressBarGithub地址
在使用过程中 可能会遇到线程的问题 建议参考
Only the original thread that created a view hierarchy can touch its views
共勉
2021 继续努力!~