admin管理员组

文章数量:1122952

目录

    • 1. 前言
    • 2. WebView 设置下载监听器
    • 3. WebView 下载文件
      • 3.1 跳转到浏览器下载
      • 3.2 使用系统的下载服务
        • 坑点
          • 1、下载文件格式错误
          • 2、下载文件名问题
      • 3.3 自定义下载任务
    • 4. 总结

1. 前言

最近在做 Android 混合项目的开发,涉及到 WebView 控件的文件下载功能,这里总结一下。

Android 中 Webview 控件默认是不支持文件下载的,需要设置其属性才支持。Webview 实现下载的方式主要有三种:

  1. 跳转到浏览器下载
  2. 使用系统的下载服务
  3. 自定义下载

本人能想到的只有三种,如有遗漏,还请赐教~~

记得添加 网络权限&文件读取权限,此处忽略不计,不懂请自行百度

2. WebView 设置下载监听器

Webview 默认是不支持文件下载的,需要给其设置下载监听器setDownloadListener

webView.setDownloadListener(new DownloadListener() {
   
      @Override
      public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
   
          //处理下载事件
      }
});
  • DownloadListener 里面只有一个方法 onDownloadStart,具体的参数含义可查看源码,里面注释的很详细。
  • 下载的URL 通过onDownloadStart方法参数传递,可以在这里处理下载事件。
  • 每当有文件需要下载时,该方法就会被回调。

3. WebView 下载文件

3.1 跳转到浏览器下载

这种方式最为简单粗暴,直接把下载任务抛给浏览器,剩下的就不用我们管了。

private void downloadByBrowser(String url) {
   
     Intent intent = new Intent(Intent.ACTION_VIEW);
     intent.addCategory(Intent.CATEGORY_BROWSABLE);
     intent.setData(Uri.parse(url));
     startActivity(intent);
}

缺点:
无法感知下载完成,所以就没有后续的处理,如 apk 下载完成后打开安装界面、文件下载完后打开文件 等。

3.2 使用系统的下载服务

DownloadManager 是系统提供的用于处理下载的服务,使用者只需提供 下载 URI 和 存储路径,并进行简单的设置。

DownloadManager 会在后台进行下载,并且在下载失败、网络切换以及系统重启后尝试重新下载。

添加下载任务:

/**
 * 使用系统的下载服务
 *
 * @param url                下载地址
 * @param contentDisposition attachment;filename=测试专用.wps;filename*=utf-8''测试专用.wps
 * @param mimeType           application/octet-stream
 */
private void downloadBySystem(String url, String contentDisposition, String mimeType) {
   
    LogUtil.d(TAG, "downloadBySystem:url=" + url + ",contentDisposition="
                + contentDisposition + ",mimeType=" + mimeType);
   // 指定下载地址
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
    // 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库
    request.allowScanningByMediaScanner();
    // 设置通知的显示类型,下载进行时和完成后显示通知
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    // 设置通知栏的标题,如果不设置,默认使用文件名
    // request.setTitle("This is title");
    // 设置通知栏的描述
    // request.setDescription("This is description");
    // 允许在计费流量下下载
    request.setAllowedOverMetered(false);
    // 允许该记录在下载管理界面可见
    request.setVisibleInDownloadsUi(false);
    // 允许漫游时下载
    request.setAllowedOverRoaming(true);
    // 允许下载的网路类型
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
    // 设置下载文件保存的路径和文件名
    String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType);
    LogUtil.d(TAG, "fileName:" + fileName);

    //storage/emulated/0/Android/data/项目名/files
	// request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
	// request.setDestinationInExternalPublicDir(ConstantPath.getCommonPath(mContext), fileName);

    //Android/data/项目名/files/storage/emulated/0/Android/data/项目名/files
	// request.setDestinationInExternalFilesDir(this, ConstantPath.getCommonPath(mContext), fileName);

    //另外可选一下方法,自定义下载路径
    Uri mDestinationUri = Uri.withAppendedPath(Uri.fromFile(
            new File(ConstantPath.getRootPath(ConstantPath.ANDROIDMOBILE))), fileName);
	// Uri mDestinationUri = Uri.withAppendedPath(Uri.fromFile(
	//                new File(ConstantPath.getCommonPath(mContext))), fileName);
    request.setDestinationUri(mDestinationUri);

    final DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
    // 添加一个下载任务
    long downloadId = downloadManager.enqueue(request);
    LogUtil.d(TAG, "downloadId:" + downloadId);
}

怎么知道文件下载成功呢?

系统在下载完成后会发送一条广播,里面有任务 ID,告诉调用者任务完成,通过 DownloadManager 获取到文件信息就可以进一步处理。

接收系统下载完成发出的广播:

private class DownloadCompleteReceiver extends BroadcastReceiver {
   
    @Override
     public void onReceive(Context context, Intent intent) {
   
         LogUtil.d(TAG + ",onReceive. intent:{}", intent != null ? intent.toUri(0) : null);
         if (intent != null) {
   
             if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.

本文标签: 几种方式文件AndroidWebView