我需要從URL下載文件,除非我不知道文件的類型,我使用的URL在其末尾沒有/random.file所以我無法解析文件名的url。 目前我使用Android下載管理器,它的工作原理和手段我沒有處理下載,但我無法看到從文件下載文件名。如果我在Firefox中加載相同的URL,例如它會詢問'下載文件:Nameoffile.extension'。來自不包含文件名後綴的URL的文件名
有沒有一種方法可以讓我在下載文件之前複製此行爲並獲取文件名?
我需要從URL下載文件,除非我不知道文件的類型,我使用的URL在其末尾沒有/random.file所以我無法解析文件名的url。 目前我使用Android下載管理器,它的工作原理和手段我沒有處理下載,但我無法看到從文件下載文件名。如果我在Firefox中加載相同的URL,例如它會詢問'下載文件:Nameoffile.extension'。來自不包含文件名後綴的URL的文件名
有沒有一種方法可以讓我在下載文件之前複製此行爲並獲取文件名?
我結束了使用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);
}
}
您最好閱讀響應中的HTTP Content-Type
標題並確定它是什麼類型的文件。文件擴展名不能保證文件的類型。 Content-Disposition: attachment; filename="fname.ext"
是另一種方法來做到這一點,如果你是特定的文件名。查看list of HTTP headers瞭解更多信息。
謝謝,實際上我到底做了什麼:-) – crazyfool
的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();
}
});
Content-Disposition的解析是非常原始的,對於邊緣情況和非ASCII字符都會失敗。 –