【问题标题】:Get file name from headers with DownloadManager in Android在 Android 中使用 DownloadManager 从标题中获取文件名
【发布时间】:2014-05-28 23:53:49
【问题描述】:

我正在使用 DownloadManager 从 url 下载视频文件。

问题是如果我使用默认文件夹下载文件,我在画廊中看不到视频。

另外,如果我尝试使用这种方法:

request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, 'filename');

我需要下载之前知道文件名,在这种情况下,我不需要

而且,我的 url 中没有文件名。

如何从标题中获取文件名并将名称传递给方法 setDestinationInExternalPublicDir ? 其他选择?

【问题讨论】:

  • “问题是如果我使用默认文件夹下载文件,我在画廊中看不到视频”——你做了什么让它显示在画廊中?你用过MediaScannerConnnectionscanFile() 吗?否则,直到下一轮定期文件索引才会显示,这可能需要一段时间。 “我需要在下载之前知道文件名,在这种情况下,我不需要”——然后发出 HTTP HEAD 请求或其他内容,以便您可以获取文件名。
  • 对我来说没有意义的是为什么 DonwloadManager 不提供仅设置目标文件夹并保留服务器文件名的方法。我在这里遗漏了什么?再次感谢您的光临。
  • 这是一个不错的功能,但DownloadManager 不提供。
  • 从下载响应头中获取文件名?我认为这将是“DownloadManager”的基本功能。有时使用 Android 令人沮丧。

标签: android android-download-manager


【解决方案1】:

方法URLUtil.guessFileName()(虽然还不知道Content-Disposition)以及同时被弃用的类AsyncTask现在都是有问题的方法。使用DownloadManager 正确地将下载排入队列:

  • 首先必须在任何 HTTP 客户端中禁用“跟随重定向”(这就是线索)。
  • 那么第一个响应将是HTTP 302(带有Location 标头),而不是HTTP 200
  • 获取该文件时,将获得带有Content-Disposition 标头(文件名)的HTTP 200
  • 只有这样才能使用DownloadManager 排队(虽然已经知道文件名)。

这是我的一个例子:RepositoryFragment(GitHub 客户端)。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。我使用了@rodeleon 答案,但响应标头中没有 Content-Disposition。然后我分析了 Chrome 开发工具中的 url 标头,并在响应标头中得到了“Location”,其中包含最后的文件名,就像“b/Ol/fire_mp3_24825.mp3”。所以不要使用

    String content = con.getHeaderField("Content-Disposition")
    

    我用过

    String content = con.getHeaderField("Location") 
    

    最后在 onPostExecute

        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            String fileName = result.substring(result.lastIndexOf("/") + 1);
            // use result as file name
            Log.d("MainActivity", "onPostExecute: " + fileName);
        }
    

    【讨论】:

      【解决方案3】:

      小提示,Android中有一个不错的辅助方法

      URLUtil.guessFileName(url, contentDisposition, contentType);
      

      所以在完成对服务器的调用后,从 Headers 中获取 contenttype 和 contentDisposition 这将尝试从信息中找到文件名。

      【讨论】:

      • 一个简单有效的解决方案。谢谢
      • 不幸的是,这个解决方案不支持来自 rfc tools.ietf.org/html/rfc5987的文件名*值
      【解决方案4】:
          request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MOVIES, uri.getLastPathSegment());
      

      【讨论】:

      • 不使用标题。
      【解决方案5】:

      如果有人想要执行 HEAD 请求以获取文件名:

      class GetFileName extends AsyncTask<String, Integer, String>
      {
          protected String doInBackground(String... urls)
          {
              URL url;
              String filename = null;
              try {
                  url = new URL(urls[0]);
                  String cookie = CookieManager.getInstance().getCookie(urls[0]);
                  HttpURLConnection con = (HttpURLConnection) url.openConnection();
                  con.setRequestProperty("Cookie", cookie);
                  con.setRequestMethod("HEAD");
                  con.setInstanceFollowRedirects(false);
                  con.connect();
      
                  String content = con.getHeaderField("Content-Disposition");
                  String contentSplit[] = content.split("filename=");
                  filename = contentSplit[1].replace("filename=", "").replace("\"", "").trim();
              } catch (MalformedURLException e1) {
                  e1.printStackTrace();
              } catch (IOException e) {
              }
              return filename;
          }
      
          @Override
          protected void onPreExecute() {
              super.onPreExecute();
          }
          @Override
          protected void onPostExecute(String result) {
      
          }
      }
      

      【讨论】:

      • 谢谢!那么有没有办法用 DownloadManager 做到这一点? :( 我正在从 Google Drive 下载文件,提取文件名的唯一方法是读取标题
      猜你喜欢
      • 2012-10-30
      • 2016-02-26
      • 1970-01-01
      • 1970-01-01
      • 2014-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多