安卓实现简易下载管理器(支持进度回显、开始停止控制)Android service+BroadcastReceiver+thread

直接上代码



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();
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值