DownloadManager--Android自带的下载工具

本文介绍了Android自带的DownloadManager,用于处理Http/Https连接,支持后台下载、失败重试、断点续传。详细讲解了权限配置、DownloadManager的Request和Query类用法,包括设置下载位置、网络类型、文件类型、网络连接头和通知栏样式。同时,文章还阐述了如何获取下载信息和进度,以及如何实现自定义进度条。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

DownloadManager是Android2.3(API 9)提供的下载操作,其“处理Http/Https连接并监控连接中的状态变化及系统重启来确保每一个下载任务顺利完成”[1]。DownLoadManager对于后台下载、下载回调、失败重试、断点续传、文件操作等方面都有很好的支持,同时使用简便,对于开发者,在大多数的使用环境中,它都是一个很好的选择。

使用

DownloadManager有两个子类,Request和Query。

  • Request类可以设置下载属性,诸如下载地址、文件类型等。
  • Query类可以用来查询下载的相关信息,包括下载进度、下载文件地址等。

1.权限配置

DownloadManager的使用需要配置权限为

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2.下载方法

DownloadManager mDownloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);//获取下载管理器服务的实例
DownloadManager.Request mRequest = new DownloadManager.Request(Uri.parse(url));//创建下载请求并传入下载地址
Long downID = mDownloadManager.enqueue(mRequest);//将下载请求加入下载队列, 返回一个下载ID

3.封装下载请求Request

 mRequest.setDestinationInExternalPublicDir("/zhang_download/", url.substring(url.lastIndexOf("/")))// 指定下载路径
                .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE) // 指定可以在移动网络下下载
                .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI) // 可以再wifi下下载
                .setMimeType(mimeType) // 设定下载类型为apk
//                .addRequestHeader("header", "value") //网络连接的http头
                .setTitle("downloadManager下载...") // notification标题
                .setDescription("<文件描述>") // notification标题描述
                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // notification可见方式
3.1 设置文件下载位置
        // 将文件保存在应用所在文件夹下的Download文件夹下,下载的文件会随着应用的卸载而删除
        mRequest.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, "file.apk");
        // 将文件保存在SD卡"zhang_download"文件夹下,这个文件夹如果不存在会自动创建
        mRequest.setDestinationInExternalPublicDir("/zhang_download/", "file.apk");
3.2 指定下载时候的网络类型

设置适当的网络类型,避免用户使用移动流量下载文件(这点很重要啊···)。

        // 指定可以在移动网络下下载
        mRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE);
        // 可以在wifi下下载
        mRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
3.3 设置文件类型(mineType)

下载管理Ui中点击某个已下载完成文件及下载完成点击通知栏提示都会根据mimeType去打开文件。mineType参考表

        // 设置下载的文件类型为.APK安装文件
        mRequest.setMimeType("application/vnd.android.package-archive");
3.4 设置网络连接头
        // 设置网络连接http头,如User-Agent等
        mRequest.addRequestHeader("header", "value");
3.5 设置通知栏样式
.setTitle("downloadManager下载...") // notification标题
                .setDescription("<文件描述>") // notification标题描述
                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // notification可见方式

对于通知栏的显示模式,可以分为以下几种。

显示方式描述
VISIBILITY_VISIBLENotification在下载时显示,下载完成后关闭(默认方式)
VISIBILITY_VISIBLE_NOTIFY_COMPLETEDNotification下载时显示,下载完成后不关闭
VISIBILITY_HIDDENNotification不显示,需要添加权限Android.permission.DOWNLOAD_WITHOUT_NOTIFICATION
VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETIONNotification只有在下载完成时才会显示

4.获取下载信息

获取文件下载进度需要使用到Query类。通过Cursor结果集来获取下载信息。

    /**
     * 获取下载信息
     */
    private int getQuery() {
        int Percentage; // 下载进度
        mQuery = new DownloadManager.Query();
        Cursor cursor = mDownloadManager.query(mQuery.setFilterById(downId));
        if (cursor != null && cursor.moveToFirst()) {
            String address = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
            int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
            int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
            String title = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE));
            String description = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_DESCRIPTION));
            String downId = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_ID));
            Percentage = (int) ((bytes_downloaded * 1f) / bytes_total * 100f);
            cursor.close();
            return Percentage;
        }
        return 0;
    }

通过这样,我们便可以获取文件的下载进度、下载地址等信息。但由于这种方式一次只能获取某一个时间段的下载状态,因此我们需要设定定时器循环查询。同时,我们也可以定义自己的进度条,来显示下载进度。

                mTimer = new Timer();
                mTimer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        int Percentage = getQuery();
                        if (Percentage >= 100) {
                            cancel();
                            install(filePath); // 安装APK
                        }
                        Message msg = new Message();
                        msg.what = 1001;
                        msg.obj = Percentage;
                        handler.sendMessage(msg);

                    }
                }, 0, 100);

附上完整代码

/**
 * 使用downloadManager下载
 */
public class DownManagerActivity extends AppCompatActivity {

    private Context context;

    private String mimeType = "application/vnd.android.package-archive";

    private Button downloadManagerBtn;

    private ProgressBar progressBar;

    private String url = "http://gdown.baidu.com/data/wisegame/c5ada0a2f33be088/baidushoujizhushouyuan91zhu_16792523.apk";

    private DownloadManager mDownloadManager;

    private DownloadManager.Request mRequest;

    private DownloadManager.Query mQuery;

    private Long downId;

    private Timer mTimer;

    private String filePath;

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1001) {
                progressBar.setProgress((Integer) msg.obj);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_down_manager);
        context = this;
        initView();
    }

    private void initView() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle("使用DownloadManager下载文件");
        toolbar.setTitleTextColor(Color.WHITE);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });

        downloadManagerBtn = (Button) findViewById(R.id.downloadManagerBtn);
        downloadManagerBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                download();
                mTimer = new Timer();
                mTimer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        int Percentage = getQuery();
                        if (Percentage >= 100) {
                            cancel();
                            install(filePath); // 安装APK
                        }
                        Message msg = new Message();
                        msg.what = 1001;
                        msg.obj = Percentage;
                        handler.sendMessage(msg);

                    }
                }, 0, 100);
            }
        });

        progressBar = (ProgressBar) findViewById(R.id.progressBar);

    }

    /**
     * 下载
     */
    private void download() {
        mDownloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        mRequest = new DownloadManager.Request(Uri.parse(url));
        mRequest.setDestinationInExternalPublicDir("/zhang_download/", url.substring(url.lastIndexOf("/")))// 指定下载路径
                .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE) // 指定可以在移动网络下下载
                .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI) // 可以再wifi下下载
                .setMimeType(mimeType) // 设定下载类型为apk
                // .addRequestHeader("header", "value") //网络连接的http头
                .setTitle("downloadManager下载...") // notification标题
                .setDescription("<文件描述>") // notification标题描述
                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // notification可见方式



        downId = mDownloadManager.enqueue(mRequest);
    }

    /**
     * 获取下载信息
     */
    private int getQuery() {
        int Percentage;
        mQuery = new DownloadManager.Query();
        Cursor cursor = mDownloadManager.query(mQuery.setFilterById(downId));
        if (cursor != null && cursor.moveToFirst()) {
            String address = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
            int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
            int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
            String title = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE));
            String description = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_DESCRIPTION));
            String downId = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_ID));
            Percentage = (int) ((bytes_downloaded * 1f) / bytes_total * 100f);
            cursor.close();
            return Percentage;
        }
        return 0;
    }

    /**
     * 安装app
     * 
     * @param path
     */
    private void install(String path) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse(path), mimeType);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值