使用方法和源代碼看注釋
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";
// 調(diào)用方法一
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) {
}
});
// 調(diào)用方法二
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;
}
// 設(shè)置下載地址
public DownloadUtils setUrl(String downloadUrl) {
if (downloadUrl == null) {
throw new NullPointerException("url is a null");
}
this.mDownloadUrl = downloadUrl;
return mDownloadUtils;
}
// 設(shè)置下載文件夾
public DownloadUtils setDirPath(String dirPath) {
if (dirPath == null) {
throw new NullPointerException("dirPath is a null");
}
this.mDriPath = dirPath;
return mDownloadUtils;
}
// 設(shè)置下載文件名稱
public DownloadUtils setFileName(String fileName) {
if (fileName == null) {
throw new NullPointerException("fileName is a null");
}
this.mFileName = fileName;
return mDownloadUtils;
}
// 設(shè)置下載進度回調(diào)監(jiān)聽
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() {
// 先判空, 保證參數(shù)無誤
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; // 已經(jīng)下載的文件大小
int fileTotalSize = 0; // 文件總大小
// 文件夾準備
File file = new File(driPath);
if (!file.exists()) { // 判斷文件夾是否存在
if (!file.mkdirs()) { // 文件夾不存在, 創(chuàng)建
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onError("無法創(chuàng)建文件夾");
}
});
return;
}
}
// 文件全路徑 = 文件夾+文件名+后綴
file = new File(driPath + File.separator + fileName);
if (file == null) {
mThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onError("無法創(chuàng)建文件");
}
});
}
// 流和鏈接
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流關(guān)閉失敗, 失敗信息: " + e.getMessage());
}
});
}
}
}
}).start();
}
/**
* 回調(diào)監(jiān)聽器
* <p>
* 所有回調(diào)函數(shù)都運行在主線程
*/
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();
}
}
}