直接上代码
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class DownloadService extends Service {
private final String TAG = "DownloadService";
private static Map<String, DownloadThread> downLoadTaskMap = new HashMap<>();
// 添加下载
public static boolean taskAdd(Context ctx, String unique, String type, String url, Object data) {
if (TextUtils.isEmpty(url)) {
ToastUtil.show("下载地址不能为空");
return false;
} else if (downLoadTaskMap.get(unique) != null) {
ToastUtil.show("正在取消");
taskCancel(unique);
return false;
}
Intent intent = new Intent(ctx, DownloadService.class);
intent.putExtra("unique", unique);
intent.putExtra("type", type);
intent.putExtra("url", url);
intent.putExtra("data", (Serializable) data);
ctx.startService(intent);
return true;
}
// 任务停止
public static boolean taskCancel(String unique) {
DownloadThread downLoadTask = downLoadTaskMap.get(unique);
if (downLoadTask != null) {
downLoadTask.cancel();
}
return true;
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
Bundle bundle = intent.getExtras();
String unique = bundle.getString("unique");
String type = bundle.getString("type");
String urlStr = bundle.getString("url");
String fileName = bundle.getString("fileName");
if (TextUtils.isEmpty(urlStr)) {
ToastUtil.show("下载地址不能为空");
return super.onStartCommand(intent, flags, startId);
}
if (TextUtils.isEmpty(fileName)) {
File file = new File(urlStr);
intent.putExtra("fileName", file.getName());
}
System.out.println("unique ===> " + unique + ", type=" + type);
DownloadThread downLoadTask = new DownloadThread(intent);
new Thread(downLoadTask).start();
downLoadTaskMap.put(unique, downLoadTask);
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 下载类
* */
private class DownloadThread implements Runnable {
private int status = 0;
private Intent taskIntent = null;
private Intent sendIntent = null;
public DownloadThread(Intent intent) {
status = 1;
taskIntent = intent;
Bundle bundle = taskIntent.getExtras();
sendIntent = new Intent(DownloadReceiver.ACTION);
sendIntent.putExtra("unique", bundle.getString("unique"));
sendIntent.putExtra("type", bundle.getString("type"));
sendIntent.putExtra("url", bundle.getString("url"));
sendIntent.putExtra("data", (Serializable) bundle.get("data"));
}
public void cancel() {
status = 4;
}
private void onCancel() {
sendIntent.putExtra("status", DownloadReceiver.Status.cancel);
sendBroadcast(sendIntent);
downLoadTaskMap.remove(sendIntent.getStringExtra("unique"));
}
private void onFinish() {
sendIntent.putExtra("status", DownloadReceiver.Status.complate);
sendBroadcast(sendIntent);
downLoadTaskMap.remove(sendIntent.getStringExtra("unique"));
}
private void onFail() {
sendIntent.putExtra("status", DownloadReceiver.Status.fail);
sendBroadcast(sendIntent);
downLoadTaskMap.remove(sendIntent.getStringExtra("unique"));
}
@Override
public void run() {
// 数据
Bundle bundle = taskIntent.getExtras();
String fileName = bundle.getString("fileName");
String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + fileName;
String urlStr = bundle.getString("url");
// 准备回复 Intent
sendIntent.putExtra("fileName", fileName);
sendIntent.putExtra("filePath", filePath);
try {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
long fileSize = conn.getContentLength(); // 获取到最大值之后设置到进度条的MAX
// 开始下载通知
sendIntent.putExtra("status", DownloadReceiver.Status.start);
sendBroadcast(sendIntent);
// 开始下载
byte[] bytes = new byte[1024 * 512]; // 为方便测试故将其设置较小
int len = -1;
long downTotal = 0;
InputStream in = conn.getInputStream();
FileOutputStream out = new FileOutputStream(filePath);
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
downTotal += len;
// 取消
if (status == 4) {
onCancel();
out.close();
in.close();
return;
}
// 千分比
double progNumFloat = (double) downTotal / (double) fileSize;
long progNum = (long) (progNumFloat * 1000f);
// 模拟下载发送进度
sendIntent.putExtra("status", DownloadReceiver.Status.progress);
sendIntent.putExtra("fileSize", fileSize);
sendIntent.putExtra("downTotal", downTotal);
sendIntent.putExtra("progNum", progNum);
//System.out.println("fileSize ===> " + fileSize + ", downTotal ===> " + downTotal);
sendBroadcast(sendIntent);
}
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
onFail();
return;
}
onFinish();
}
}
}