Android下载管理器DownloadManager

目录

一、构建下载请求-Request

二、进行下载操作-DownloadManager

三、查询下载进度-Query

四、事件广播监听

1.下载完成事件

2.下载进行时的通知栏点击事件

3.下载完成后的通知栏点击事件

五、暂停、继续下载

六、基础使用案例代码


Android 从 2.3 (API9) 开始提供了专门的下载工具DownloadManager(下载管理器)统一管理下载操作。
下载管理器DownloadManager的对象从系统服务DOWNLOAD_SERVICE中获取,具体使用过程分为3步:构建下载请求(Request)、进行下载操作(DownloadManager)和查询下载进度(Query)。

一、构建下载请求-Request

要想使用下载功能,首先得构建一个下载请求(DownloadManager.Request),说明从哪里下载、下载参数是什么、下载的文件保存到哪里等。这个下载请求就是DownloadManager的内部类Request。以下是该类的常用方法:

  • DownloadManager构造函数:指定从哪个网络地址下载文件。
  • setAllowedNetworkTypes:指定允许下载的网络类型。若同时允许多种网络类型,则可使用竖线“|”把多种网络类型拼接起来。取值为:
  1. DownloadManager.Request.NETWORK_WIFI WiFi 网络
  2. DownloadManager.Request.NETWORK_MOBILE 移动网络(手机的数据连接)
  • setDestinationInExternalFilesDir:设置下载文件的保存路径(存于程序私有文件夹)。
  • setDestinationInExternalPublicDir:设置下载文件的保存路径(存于公共文件夹)。第一个参数为目录类型(主文件夹);第二个参数为主文件夹下的部分文件路径,为仅文件名时不加后缀名,为路径时需加后缀名;另外,如果指定目录已存在同名文件,系统就会将新下载的文件重命名,即在文件名末尾添加“-1” “-2”之类的序号。目录类型(主文件夹)取值如下:
  1. Environment.DIRECTORY_PICTURES
  2. Environment.DIRECTORY_DCIM
  3. Environment.DIRECTORY_MUSIC
  4. Environment.DIRECTORY_DOWNLOADS
  5. Environment.DIRECTORY_SCREENSHORT
  • addRequestHeader:给 HTTP 请求添加头部参数。如断点续传的Range字头,根据已有字节数续接。
  • setMimeType:设置下载文件的媒体类型。一般无须设置,默认是服务器返回的媒体类型。参数为String型,如"text/html",HTML格式;"text/pain",纯文本格式;"image/jpeg",jpg图片格式。
  • setTitle:设置通知栏上的消息标题。如果不设置,默认标题就是下载的文件名。
  • setDescription:设置通知栏上的消息描述。如果不设置,默认显示系统估算的下载剩余时间。
  • setVisibleInDownloadsUi:设置是否显示在系统的下载页面上。
  • setNotificationVisibility: 设置通知栏的下载任务可见类型。取值如下:
  1. DownloadManager.Request.VISIBILITY_HIDDEN   隐藏
  2. DownloadManager.Request.VISIBILITY_VISIBLE   下载时可见(下载完成后消失)
  3. DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED   下载进行时与完成后都可见
  4. DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION   只有下载完成后可见

二、进行下载操作-DownloadManager

构建完下载请求才能进行下载的相关操作。以下是DownloadManager的常用方法:

  • enqueue:将下载请求加入任务队列中,排队等待下载。该方法返回本次下载任务的编号
  • remove:取消指定编号的下载任务。
  • openDownloadedFile:打开下载完成的文件。
  • getMimeTypeForDownloadedFile:获取下载完成文件的媒体类型。
  • query:根据查询请求获取符合条件的结果集游标Curosr。

三、查询下载进度-Query

虽然下载进度可在通知栏上查看,但是如果App自身也想了解当前的下载进度,就要调用下载管理器的query方法。该方法的输入参数是一个Query对象,返回结果集的Cursor对象,这里的Cursor用法与SQLite中的Cursor 一样。
以下是Query类的常用方法说明:

  • setFilterByld:根据编号过滤下载任务。
  • setFilterByStatus:根据状态过滤下载任务。

设置完查询请求,即可调用 DownloadManager 对象的query方法,获得结果集的游标对象Cusor。该游标中包含下载任务的完整字段信息,主要下载字段的取值如下:

  1. DownloadManager.COLUMN_LOCAL_FILENAME   下载文件的本地保存路径
  2. DownloadManager.COLUMN_MEDIA_TYPE   下载文件的媒体类型
  3. DownloadManager.COLUMN_TOTAL_SIZE_BYTES   下载文件的总大小
  4. DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR   已下载的文件大小
  5. DownloadManager.COLUMN_STATUS   下载状态

下载状态的取值说明:

  1. STATUS_PENDING   挂起,即正在等待
  2. STATUS_RUNNING   运行中
  3. STATUS_PAUSED   暂停
  4. STATUS_SUCCESSFUL   成功
  5. STATUS_FAILED   失败
//方法总结

//创建下载请求
DownloadManager.Request request=new DownloadManager.Request(Uri.parse(urlString));
//设置允许下载的网络类型
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE);
//设置保存文件地址
//公共文件夹-第一个参数为文件夹类型-第二个参数为主文件夹下的部分文件路径,为仅文件名时不加后缀名,为路径时需加后缀名
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"MyDownloadManagerTest/myTestDownload.png");
//app私有文件夹
//request.setDestinationInExternalFilesDir(MainActivity.this, Environment.DIRECTORY_DOWNLOADS,"myTestDownload");
//添加HTTP请求头参数,如断点续接Range字段(使用已有字节数续接)
//request.addRequestHeader("Range", "bytes=" + downloadedBytes + "-");
//设置下载文件的媒体类型,一般无需设置,默认服务器返回的媒体类型
//request.setMimeType("image/jpeg");
//设置通知栏标题,无设置默认下载的文件名
request.setTitle("DownloadManager下载测试");
//设置通知栏内容,无设置默认估算剩余时间
//request.setDescription("通知栏内容");
//设置是否显示在系统的下载页面上
request.setVisibleInDownloadsUi(true);
//设置通知栏显示类型
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

//获取下载管理器
DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

//下载
//将下载请求添加到任务队列
long downloadId=downloadManager.enqueue(request);
//取消下载
downloadManager.remove(downloadId);
//获取下载完成文件的媒体类型
String fileString=downloadManager.getMimeTypeForDownloadedFile(downloadId);

//查询下载情况
//获取Query
DownloadManager.Query query=new DownloadManager.Query();
//根据下载ID过滤
query.setFilterById(downloadId);
//根据下载状态过滤
query.setFilterByStatus(DownloadManager.STATUS_RUNNING);
//查询-Cursor的使用方法与SEQLite一致
Cursor cursor=downloadManager.query(query);

四、事件广播监听

系统的下载服务还提供3种下载事件,开发者可通过注册广播接收者监听对应的广播消息进行相应的处理。3种下载事件说明如下:

1.下载完成事件

在下载完成时,系统会发出名为 DownloadManager.ACTION_DOWNLOAD_COMPLETE(值为字符串 android.intent.action.DOWNLOAD_COMPLETE)的广播,因此可注册一个该广播的接收器,用来判断当前任务是否已下载完毕,并进行后续的业务处理。

2.下载进行时的通知栏点击事件

在下载过程中,只要用户点击通知栏上的下载任务,系统就会发出行为名称是DownloadManager.ACTION_NOTIFICATION_CLICKED(值为字符串 androidintent.action.DOWNLOAD_NOTIFICATION_CLICKED)的广播,可注册该广播的接收器进行相关处理,比如跳转到该任务的下载进度页面等。

3.下载完成后的通知栏点击事件

下载完成后点击触发的是系统的 Intent.ACION_VIEW(浏览行为)。对于浏览行为,系统会根据媒体类型自动寻找对应App打开。因此,如果开发者要控制此时的点击行为,可以调用Request对象的setMimeType方法设置媒体类型,这样 Android 就会按照这个类型打开相应的 APP

public class MyReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        //获取活动
        String action=intent.getAction();
        //下载完成触发广播
        if(action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)){
            //获取下载编号
            //getLongExtra第二个参数为默认值
            long downloadId=intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);
        }
        //点击通知(未下载完)触发通知
        else if(action.equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)){
            //获取全部下载编号
            long[] downloadIds=intent.getLongArrayExtra(DownloadManager.EXTRA_DOWNLOAD_ID);
            //检查是否是本应用下载的
            for(long downloadId:downloadIds){
                //... ...
            }
        }
        //点击通知(下载完)触发通知
        else if (action.equals(Intent.ACTION_VIEW)) {
            //获取下载编号
            long downloadId=intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);
        }
    }
}

五、暂停、继续下载

DownloadManager类不提供直接的暂停下载的方式。它只提供了启动下载和取消下载的方法

如果想要实现下载的暂停功能,可以使用DownloadManager提供的remove()方法取消下载任务。然后,可以记录已下载的字节数和文件URL等信息,以便稍后重新启动下载时可以通过设置HTTP字头的Range字段恢复下载进度。

需要注意的是,为了支持断点续传,服务器必须能够处理并正确响应Range字段,返回恰当范围的数据。同时,如果服务器不支持断点续传或不满足范围请求,它可能会忽略Range字段并返回完整的文件。因此,断点续传的成功与否也取决于服务器的支持

private long downloadId; // 用于记录下载任务的ID
private boolean isPaused = false; // 标记下载是否被暂停

/**
 * 第一次下载时参数使用0
 */
private void startDownload(int downloadedBytes) {
    // 创建下载请求
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(urlString));
    // 根据已下载的字节数设置请求头Range字段,以实现断点续传功能
    request.addRequestHeader("Range", "bytes=" + downloadedBytes + "-");
    // 其他设置...

    // 获取下载管理器
    DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
    // 下载执行
    downloadId = downloadManager.enqueue(request);
}

private void pauseDownload() {
    // 取消下载任务
    DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
    downloadManager.remove(downloadId);
    // 记录已下载的字节数()
    long downloadedBytes = getDownloadedBytes(downloadId);
    // 保存已下载的字节数及其他信息至本地,以便稍后恢复下载

    isPaused = true;
}

private void resumeDownload() {
    // 恢复下载,重新发起下载请求
    isPaused = false;

    // 从本地获取已下载的字节数及其他信息
    // long downloadedBytes = getSavedDownloadedBytes();

    startDownload(dowbloadedBytes);
}

private int getDownloadedBytes(downloadId){
    int retI=0;
    //获取Query
    DownloadManager.Query query=new DownloadManager.Query();
    //根据下载ID过滤
    query.setFilterById(downloadId);
    
    // 获取下载管理器
    DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
    
    //查询-Cursor的使用方法与SEQLite一致
    Cursor cursor=downloadManager.query(query);
    if(cursor.getCount()>0){
        cursor.moveToNext();
        retI=cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
    }
    return retI;
}

六、基础使用案例代码

public class MainActivity extends AppCompatActivity {
    private String urlString="https://bkimg.cdn.bcebos.com/pic/00e93901213fb80ee7dc88b530d12f2eb9389447?x-bce-process=image/resize,m_lfit,w_536,limit_1/quality,Q_70";
    private URL url=null;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取控件
        Button button=findViewById(R.id.button);
        //获取URL
        try {
            url=new URL(urlString);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
        //添加监听器
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                if(!getNetworkState(MainActivity.this)){
                    Toast.makeText(MainActivity.this,"无网络",Toast.LENGTH_SHORT).show();
                    return;
                }
                Toast.makeText(MainActivity.this,"开始下载",Toast.LENGTH_SHORT).show();
                startDownload();
            }
        });

    }


    /**
     * 获取网络状态
     * @param context
     * @return true连接 false未连接
     */
    private boolean getNetworkState(Context context){
        ConnectivityManager cm= (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo=cm.getActiveNetworkInfo();
        if(networkInfo==null){
            return false;
        }
        return true;
    }

    /**
     * 开始下载-DownloadManager
     */
    private void startDownload(){
        //创建下载请求
        DownloadManager.Request request=new DownloadManager.Request(Uri.parse(urlString));                        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE);
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"myTestDownload");
        request.setTitle("DownloadManager下载测试");
        request.setVisibleInDownloadsUi(false);
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

        //获取下载管理器
        DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

        //将下载请求添加到任务对列
        long downloadId=downloadManager.enqueue(request);
    }

}

tag:保存文件;网络下载;存储;保存;下载;内存;路径

  • 36
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android开发中,我们可以利用DownloadManager类实现下载功能。DownloadManagerAndroid系统提供的一个用于管理下载任务的类,它负责处理下载请求,管理和控制下载任务的状态。 实现下载功能的步骤如下: 1. 创建DownloadManager对象: ``` DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); ``` 2. 构建下载请求: ``` DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadUrl)); request.setTitle("文件名"); // 设置下载文件的标题 request.setDescription("下载中"); // 设置下载的描述信息 request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); // 设置下载通知的可见性 request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "文件名"); // 设置下载文件的保存路径和文件名 ``` 3. 添加下载请求到DownloadManager队列中: ``` long downloadId = downloadManager.enqueue(request); ``` 4. 监听下载状态: ``` BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); if (id == downloadId) { DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(downloadId); Cursor cursor = downloadManager.query(query); if (cursor.moveToFirst()) { int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); if (status == DownloadManager.STATUS_SUCCESSFUL) { // 下载成功 } else if (status == DownloadManager.STATUS_FAILED) { // 下载失败 } else if (status == DownloadManager.STATUS_RUNNING) { // 下载中 } } cursor.close(); } } }; registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); ``` 通过以上步骤,我们可以利用DownloadManager实现下载功能。用户可以通过监听下载状态,获取下载任务的状态并进行相应的处理,例如在下载完成时显示通知,或者在下载失败时提示用户重新下载

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在下嗷呜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值