2012-10-28 56 views
1

我需要從URL下載文件,除非我不知道文件的類型,我使用的URL在其末尾沒有/random.file所以我無法解析文件名的url。 目前我使用Android下載管理器,它的工作原理和手段我沒有處理下載,但我無法看到從文件下載文件名。如果我在Firefox中加載相同的URL,例如它會詢問'下載文件:Nameoffile.extension'。來自不包含文件名後綴的URL的文件名

有沒有一種方法可以讓我在下載文件之前複製此行爲並獲取文件名?

回答

2

我結束了使用ASyncTask手動檢索文件名並將它傳遞給下載管理器,如果它幫助任何人這是我做到了這一點(我的網址在實際文件下載之前經過了一些重定向):

class GetFileInfo extends AsyncTask<String, Integer, String> 
{ 
    protected String doInBackground(String... urls) 
    { 
       URL url; 
       String filename = null; 
       try { 
        url = new URL(urls[0]); 
       HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
       conn.connect(); 
       conn.setInstanceFollowRedirects(false); 

       try { 
        for(int i = 0; i < 10; i++) 
        { 
         url = new URL(conn.getHeaderField("Location")); 
         conn = (HttpURLConnection) url.openConnection(); 
         conn.connect(); 
         conn.setInstanceFollowRedirects(false); 
        } 
       } catch (Exception e) { 
       } 

       String depo = conn.getHeaderField("Content-Disposition"); 
       String depoSplit[] = depo.split(";"); 
       int size = depoSplit.length; 
       for(int i = 0; i < size; i++) 
       { 
        if(depoSplit[i].startsWith("filename=")) 
        { 
         filename = depoSplit[i].replace("filename=", "").replace("\"", "").trim(); 
         Global.error(filename); 
         i = size; 
        } 
       } 
       } catch (MalformedURLException e1) { 
        e1.printStackTrace(); 
       } catch (IOException e) { 
       } 
      return filename; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected void onProgressUpdate(Integer... progress) { 
     super.onProgressUpdate(progress); 
    } 
} 
+0

Content-Disposition的解析是非常原始的,對於邊緣情況和非ASCII字符都會失敗。 –

2

您最好閱讀響應中的HTTP Content-Type標題並確定它是什麼類型的文件。文件擴展名不能保證文件的類型。 Content-Disposition: attachment; filename="fname.ext"是另一種方法來做到這一點,如果你是特定的文件名。查看list of HTTP headers瞭解更多信息。

+0

謝謝,實際上我到底做了什麼:-) – crazyfool

0

的AsyncTask手工獲取文件名:

private static class getFileNameAsync extends AsyncTask<String, Void, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     URL url; 
     String filename = null; 
     HttpURLConnection conn = null; 
     try { 
      url = new URL(params[0]); 
      conn = (HttpURLConnection) url.openConnection(); 
      conn.connect(); 
      conn.setInstanceFollowRedirects(false); 

      try { 
       for(int i = 0; i < 100; i++) 
       { 
        String stringURL = conn.getHeaderField("Location"); 
        if (stringURL != null) { 
         url = new URL(stringURL); 
         conn = (HttpURLConnection) url.openConnection(); 
         conn.connect(); 
         conn.setInstanceFollowRedirects(false); 
        } else { 
         i = 100; 
        } 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

      String depo = conn.getHeaderField("Content-Disposition"); 
      if (depo != null) { 
       String depoSplit[] = depo.split(";"); 
       int size = depoSplit.length; 
       for(int i = 0; i < size; i++) 
       { 
        if(depoSplit[i].startsWith("filename=")) 
        { 
         filename = depoSplit[i].replaceFirst("(?i)^.*filename=\"?([^\"]+)\"?.*$", "$1").trim(); 
         i = size; 
        } 
       } 
      } 
     } catch (MalformedURLException e){ 
      e.printStackTrace(); 
     } catch (ProtocolException e){ 
      e.printStackTrace(); 
     } catch (FileNotFoundException e){ 
      e.printStackTrace(); 
     } catch (IOException e){ 
      e.printStackTrace(); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } finally { 
      if (conn != null) 
       conn.disconnect(); 
     } 
     return filename; 
    } 
    @Override 
    protected void onPostExecute(String filename) { 
     super.onPostExecute(filename); 
    } 
} 

DownloadListener:

mWebView.setDownloadListener(new DownloadListener() { 
     @Override 
     public void onDownloadStart(String url, 
            String userAgent, 
            String contentDisposition, 
            String mimetype, 
            long contentLength) { 
      if(Build.VERSION.SDK_INT >=23){ 
       Context nContext = MainActivity.this.getApplicationContext(); 
       if(nContext.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ 
        MainActivity.this.requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); 
        return; 
       } 
      } 

      String fileName = ""; 
      url = url.replace(" ", "%20"); 

      AsyncTask<String, Void, String> asyncTask = new getFileNameAsync(); 
      asyncTask.execute(url); 

      try { 
       fileName = asyncTask.get(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } catch (ExecutionException e) { 
       e.printStackTrace(); 
      } catch (CancellationException e) { 
       e.printStackTrace(); 
      } 
      if ((fileName == null) || (fileName.hashCode() == "".hashCode())) { 
       fileName = URLUtil.guessFileName(url, contentDisposition, mimetype); 
      } 

      DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); 

      request.setMimeType(mimetype); 
      String cookies = CookieManager.getInstance().getCookie(url); 
      request.addRequestHeader("Cookie", cookies); 
      request.addRequestHeader("User-Agent", userAgent); 
      request.setDescription("Downloading File"); 
      request.setTitle(fileName); 
      request.allowScanningByMediaScanner(); 
      request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); 
      request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); 
      DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); 
      if (downloadManager != null) { 
       downloadManager.enqueue(request); 
      } 
      Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show(); 
     } 
    });