使用方法和源代码看注释
package com.geaosu.alearn;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/*
=========================== 该工具类的用法 ===========================
=========================== 该工具类的用法 ===========================
=========================== 该工具类的用法 ===========================
// 锤子便签
String url = "https://01911f43fa7455a7a99a61cc172fc905.dd.cdntips.com/imtt.dd.qq.com/16891/apk/15A873B930E4EDF0A772A67566516D38.apk?mkey=5f4778860e864886&f=0f1d&fsname=com.smartisan.notes_3.7.2_47.apk&csr=1bbd&cip=14.134.110.115&proto=https";
// 调用方法一
DownloadUtils.getInstance()
.setUrl(url)
.setDirPath("/sdcard/Download/")
.setFileName("锤子便签")
.setOnDownloadListener(new DownloadUtils.OnDownloadListener() {
@Override
public void onStart() {
}
@Override
public void onProgress(int fileTotalSize, int progress) {
}
@Override
public void onFinish(File file) {
}
@Override
public void onError(String errMsg) {
}
});
// 调用方法二
DownloadUtils instance = DownloadUtils.getInstance();
instance.downLoadFile(url, "/sdcard/Download/", "锤子便签", new DownloadUtils.OnDownloadListener() {
@Override
public void onStart() {
}
@Override
public void onProgress(int fileTotalSize, int progress) {
}
@Override
public void onFinish(File file) {
}
@Override
public void onError(String errMsg) {
}
});
=========================== 该工具类的用法 ===========================
=========================== 该工具类的用法 ===========================
=========================== 该工具类的用法 ===========================
*/
/**
* 下载工具
*/
public class DownloadUtils {
private static final String TAG = "DownloadUtils";
private static Context mContext;
private static DownloadUtils mDownloadUtils;
private static ThreadUtils mThreadUtils;
private String mDownloadUrl;
private String mDriPath;
private String mFileName;
private DownloadUtils() {
}
// 获取对象
public static DownloadUtils getInstance() {
if (mThreadUtils == null) {
mThreadUtils = new ThreadUtils();
}
if (mDownloadUtils == null) {
mDownloadUtils = new DownloadUtils();
}
return mDownloadUtils;
}
// 设置下载地址
public DownloadUtils setUrl(String downloadUrl) {
if (downloadUrl == null) {
throw new NullPointerException("url is a null");
}
this.mDownloadUrl = downloadUrl;
return mDownloadUtils;
}
// 设置下载文件夹
public DownloadUtils setDirPath(String dirPath) {
if (dirPath == null) {
throw new NullPointerException("dirPath is a null");
}
this.mDriPath = dirPath;
return mDownloadUtils;
}
// 设置下载文件名称
public DownloadUtils setFileName(String fileName) {
if (fileName == null) {
throw new NullPointerException("fileName is a null");
}
this.mFileName = fileName;
return mDownloadUtils;
}
// 设置下载进度回调监听
public void setOnDownloadListener(OnDownloadListener listener) {
if (listener == null) {
throw new NullPointerException("OnDownloadListener is a null");
}
downLoadFile(mDownloadUrl, mDriPath, mFileName, listener);
}
/**
* 下载文件
*
* @param downloadUrl
* @param driPath
* @param fileName
* @param listener
* @return file对象
*/
public void downLoadFile(String downloadUrl, String driPath, String fileName, OnDownloadListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
// 先判空, 保证参数无误
if (TextUtils.isEmpty(downloadUrl) || TextUtils.isEmpty(driPath) || TextUtils.isEmpty(fileName)) {
throw new NullPointerException("downloadUrl is a null");
}
if (TextUtils.isEmpty(driPath) || TextUtils.isEmpty(fileName)) {
throw new NullPointerException("driPath is a null");
}
if (TextUtils.isEmpty(fileName)) {
throw new NullPointerException("fileName is a null");
}
if (listener == null) {
throw new NullPointerException("OnDownloadListener is a null object");
}
// 输出一下下载信息
Log.d("gLog", TAG + " - 文件下载 ------>> 文件下载地址: " + downloadUrl);
Log.d("gLog", TAG + " - 文件下载 ------>> 文件保存路径: " + driPath);
Log.d("gLog", TAG + " - 文件下载 ------>> 文件保存名称: " + fileName);
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onStart();
}
});
// 下载准备
int downloadedSize = 0; // 已经下载的文件大小
int fileTotalSize = 0; // 文件总大小
// 文件夹准备
File file = new File(driPath);
if (!file.exists()) { // 判断文件夹是否存在
if (!file.mkdirs()) { // 文件夹不存在, 创建
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onError("无法创建文件夹");
}
});
return;
}
}
// 文件全路径 = 文件夹+文件名+后缀
file = new File(driPath + File.separator + fileName);
if (file == null) {
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onError("无法创建文件");
}
});
}
// 流和链接
InputStream inputStream = null;
FileOutputStream outputStream = null;
HttpURLConnection connection = null;
// 开始链接
try {
URL url = new URL(downloadUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10 * 1000);
connection.setReadTimeout(10 * 1000);
connection.connect();
// 获取要下载的文件信息
fileTotalSize = connection.getContentLength(); // 文件总大小
inputStream = connection.getInputStream();
outputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024 * 4];
int len;
while ((len = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
downloadedSize += len;
// 计算文件下载进度
final int progress = (int) (downloadedSize * 1.0f / fileTotalSize * 100);
int finalFileTotalSize = fileTotalSize;
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onProgress(finalFileTotalSize, progress);
}
});
}
// 下载成功
File finalFile = file;
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onFinish(finalFile);
}
});
} catch (Exception e) {
if (file.exists()) {
if (file.delete()) {
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onError("下载失败, 失败信息: " + e.getMessage());
}
});
} else {
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onError("下载失败, 失败信息: " + e.getMessage());
}
});
}
} else {
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onError("下载失败, 失败信息: " + e.getMessage());
}
});
}
} finally {
try {
if (inputStream != null)
inputStream.close();
if (outputStream != null)
outputStream.close();
if (connection != null)
connection.disconnect();
} catch (Exception e) {
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onError("IO流关闭失败, 失败信息: " + e.getMessage());
}
});
}
}
}
}).start();
}
/**
* 回调监听器
*
* 所有回调函数都运行在主线程
*/
public interface OnDownloadListener {
// 开始下载
void onStart();
// 正在下载
void onProgress(int fileTotalSize, int progress);
// 下载完成
void onFinish(File file);
// 下载失败
void onError(String errMsg);
}
/**
* 线程切换工具
*/
private static class ThreadUtils {
private Handler mHandler = new Handler(Looper.getMainLooper());
// 在主线程中运行
public void runOnUiThread(Runnable r) {
if (Looper.myLooper() == Looper.getMainLooper()) {
//主线程
r.run();
} else {
//子线程
mHandler.post(r);
}
}
// 在子线程中运行
public void runOnSubThread(Runnable r) {
new Thread(r).start();
}
// 是否是主线程
public boolean isMainThread() {
return Looper.getMainLooper() == Looper.myLooper();
}
}
}