Android DownloadManager的使用

DownloadManger是android提供的一个系统服务,用于处理App安装包下载任务,通常在应用商店下载应用时,就会用到此服务。我们自己开发的应用,通常都需要实现App在线更新功能,在此我们就可以使用这个系统服务,而不用再自己处理大文件下载等复杂情况。
通过DownloadManager可以获取到当前的下载进度、下载状态(成功、失败、暂停)等。

  • DownloadManager实例可通过如下方式获得:

    DownlaodMnager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);

  • 建立一个下载任务,下载文件默认保存在系统内部存储中,为避免某些情况下下载失败,在此可选择保存到外部存储中(需要系统外部存储权限),设置存储位置时,若选用 setDestinationInExternalPublicDir 方法,生成的是文件夹,若直接生成APK文件,可用如下方式:

    public long startDownLoad(String url, String apkName) {
    DownlaodMnager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
    request.allowScanningByMediaScanner();//设置文件可由MediaScanner扫描
    request.setAllowedOverMetered(true);//是否允许流量下载
    request.setDescription(“App更新”);//下载描述
    request.setMimeType(“application/vnd.android.package-archive”);
    File file = new File(Environment.getExternalStorageDirectory() + File.separator +
    Environment.DIRECTORY_DOWNLOADS + File.separator + apkName);//文件保存位置
    request.setDestinationUri(Uri.fromFile(file));//下载文件外部存储URI
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);//通知栏可见性
    long id = manager.enqueue(request);
    return id;
    }
    注意:每建立一个下载任务后,都会返回一个不同的Id,即使前面已经建立了下载任务,所以在此要注意不要重复下载;

  • 获取下载进度,要使用建立下载任务时返回的Id,若要在进度条中动态显示进度,可使用 TimeTask或 Handler每1s/次 或更短时间查询进度:

    public int queryProcess(long id) {
    int percent = 0;
    DownlaodMnager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    DownloadManager.Query query = new DownloadManager.Query();
    Cursor cursor = manager.query(query.setFilterById(id));//只查看指定Id的下载任务
    if (cursor != null && cursor.moveToFirst()) {
    int total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));//App总大小
    int progress = cursor.getInt(
    cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));//已下载大小
    if (total > 0)
    percent = (progress * 100) / total;//计算百分比
    }
    if (cursor != null)
    cursor.close();
    return percent;
    }

  • 获取下载状态,在获取下载进度的同时可以获取状态,并在界面显示-失败、暂停等:

    public String queryStatus(long id) {
    DownlaodMnager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    DownloadManager.Query query = new DownloadManager.Query();
    Cursor cursor = manager.query(query.setFilterById(id));
    if (cursor != null && cursor.moveToFirst()) {
    int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));//状态:成功、暂停、失败
    switch (status) {
    case DownloadManager.STATUS_FAILED:
    stat = “下载失败”;
    break;
    …//其他状态可在源码中查看
    }
    }
    if (cursor != null)
    cursor.close();
    return stat;
    }

    • 取消下载任务:

      public void cancelDownLoad(long id) {
      if (manager != null && id != 0)
      manager.remove(id);
      }

    • 当下载成功后,需要跳转到系统的App安装界面,通过注册系统广播 android.intent.action.DOWNLOAD_COMPLETE,当监听到该广播时就可以直接去安装应用。
      若将APK文件存储在系统的外部存储中,则安装文件时必须要取得系统读取外部存储权限,否则显示安装包读取失败。

      DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
      Uri uri = manager.getUriForDownloadedFile(id);
      //
      public static void installApp(Context context, Uri uri) {
      Intent intent = new Intent();
      intent.setAction(Intent.ACTION_VIEW);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      //适配 7.0
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      intent.setDataAndType(uri, “application/vnd.android.package-archive”);
      intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
      //适配 8.0 相关
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      if (!context.getPackageManager().canRequestPackageInstalls()) {
      }
      }
      } else {
      intent.setDataAndType(uri, “application/vnd.android.package-archive”);
      }
      context.startActivity(intent);
      }


版权声明:本文为sinat_22910799原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。