大连密封材料 发表于 2024-8-21 00:33:43

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:指定答应下载的网络范例。若同时答应多种网络范例,则可使用竖线“|”把多种网络范例拼接起来。取值为:

[*]DownloadManager.Request.NETWORK_WIFI WiFi 网络
[*]DownloadManager.Request.NETWORK_MOBILE 移动网络(手机的数据连接)


[*]setDestinationInExternalFilesDir:设置下载文件的生存路径(存于程序私有文件夹)。
[*]setDestinationInExternalPublicDir:设置下载文件的生存路径(存于公共文件夹)。第一个参数为目次范例(主文件夹);第二个参数为主文件夹下的部分文件路径,为仅文件名时不加后缀名,为路径时需加后缀名;另外,如果指定目次已存在同名文件,系统就会将新下载的文件重命名,即在文件名末尾添加“-1” “-2”之类的序号。目次范例(主文件夹)取值如下:

[*]Environment.DIRECTORY_PICTURES
[*]Environment.DIRECTORY_DCIM
[*]Environment.DIRECTORY_MUSIC
[*]Environment.DIRECTORY_DOWNLOADS
[*]Environment.DIRECTORY_SCREENSHORT


[*]addRequestHeader:给 HTTP 请求添加头部参数。如断点续传的Range字头,根据已有字节数续接。
[*]setMimeType:设置下载文件的媒体范例。一样平常无须设置,默认是服务器返回的媒体范例。参数为String型,如"text/html",HTML格式;"text/pain",纯文本格式;"image/jpeg",jpg图片格式。
[*]setTitle:设置通知栏上的消息标题。如果不设置,默认标题就是下载的文件名。
[*]setDescription:设置通知栏上的消息描述。如果不设置,默认显示系统估算的下载剩余时间。
[*]setVisibleInDownloadsUi:设置是否显示在系统的下载页面上。
[*]setNotificationVisibility: 设置通知栏的下载任务可见范例。取值如下:

[*]DownloadManager.Request.VISIBILITY_HIDDEN   埋伏
[*]DownloadManager.Request.VISIBILITY_VISIBLE   下载时可见(下载完成后消散)
[*]DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED   下载举行时与完成后都可见
[*]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。该游标中包罗下载任务的完整字段信息,主要下载字段的取值如下:

[*]DownloadManager.COLUMN_LOCAL_FILENAME   下载文件的本地生存路径
[*]DownloadManager.COLUMN_MEDIA_TYPE   下载文件的媒体范例
[*]DownloadManager.COLUMN_TOTAL_SIZE_BYTES   下载文件的总大小
[*]DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR   已下载的文件大小
[*]DownloadManager.COLUMN_STATUS   下载状态
下载状态的取值说明:

[*]STATUS_PENDING   挂起,即正在等待
[*]STATUS_RUNNING   运行中
[*]STATUS_PAUSED   停息
[*]STATUS_SUCCESSFUL   乐成
[*]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:生存文件;网络下载;存储;生存;下载;内存;路径

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Android下载管理器DownloadManager