问题
How to get the file name which we uploaded on server when we provide linked for that file in page?
What I am doing is, I am providing data with file link in webview so whenever user click on link need to download from server as I have download this file from server but the problem is not able to get its exact type and name using DownloadManager. I want like this

See in above I have given link for my file in test_androt and when I click it will give the dailog with option having the file name, I don't know how to achieve this file name when user click on WebView URL link.
Edit Sorry to forgot mention that my URL look like this
misc/dnload.php?t1=MzQ0MDA=&t2=MTY5NTUz&t3=MTY5NTUzMTMwMjEyMDNfcGhhcm1hY3kga2V5IGluZm8ucG5n&t4=MTMwMjEyMDM=
回答1:
I got the answer thanks to Raghunandan for suggestion.
Here I need to extra call to get the header info of the downloading file. In the header section I got the name of the file.
Also I found this Filename from URL not containing filename suffix post through which I got more detail regarding header detail which we can getting at requesting time.
As we can use this URLUtil.guessFileName(url, null, null)
but this will given the file name of calling means for my case I have url like this
misc/dnload.php?t1=MzQ0MDA=&t2=MTY5NTUz&t3=MTY5NTUzMTMwMjEyMDNfcGhhcm1hY3kga2V5IGluZm8ucG5n&t4=MTMwMjEyMDM=
so from the above link this will extract the dnload.php as file name it not original file name which we download it just created download link for that file.
here is the code using this we can get the file name it just an extra call to get the information but actually we download, for download I have used android inbuilt api to DownloadManager to download file.
Content-Disposition this is the attribute in header section through which we can get the file name as in attachment form.
It'll will return info like this way Content-Disposition: attachment; filename="fname.ext"
so now just need to extract file name
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);
String depo = conn.getHeaderField("Content-Disposition");
String depoSplit[] = depo.split("filename=");
filename = depoSplit[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) {
super.onPostExecute();
// use result as file name
}
}
回答2:
You could simply parse the url and get the text after the last "/" and make that the file name, or you could use the following
URLUtil.guessFileName(url, contentDisposition, mimetype);
shown below as I have used it in my DownloadListener:
//this stuff goes inside your DownloadListener
@Override
public void onDownloadStart(final String url, String userAgent,final String contentDisposition, final String mimetype, long contentLength)
{
String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype); //returns a string of the name of the file THE IMPORTANT PART
//proceed with download
}
If you don't want to use it inside your DownloadListener, you can use it without the contentDisposition or mimetype by just passing 'null' in for each parameter except the url (pass the url in) also.
EDIT: This only works if you have a url with a filename embedded in it. See Pratik's answer above if you are looking for a more foolproof way.
回答3:
Some refinements for Pratik's solution.
Changes:
1) fixed broken filename extraction from Content-Disposition
2) added callback interface
Usage:
new GetFileInfo(new GetFileInfoListener() {
@Override
public void onTaskCompleted(String fileName) {
Log.v(TAG, "real filename is " + fileName);
}
}).execute(url);
Code:
class GetFileInfo extends AsyncTask<String, Integer, String>
{
public interface GetFileInfoListener {
void onTaskCompleted(String result);
}
private final GetFileInfoListener mListener;
public GetFileInfo(GetFileInfoListener listener) {
mListener = listener;
}
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);
String depo = conn.getHeaderField("Content-Disposition");
if (depo != null)
filename = depo.replaceFirst("(?i)^.*filename=\"?([^\"]+)\"?.*$", "$1");
else
filename = URLUtil.guessFileName(urls[0], null, null);
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e) {
}
return filename;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (mListener != null)
mListener.onTaskCompleted(result);
}
}
回答4:
This will get the filename from a server that requires authentication (via cookies). To do this you need to get the filename from the server content-disposition header, we do this async (you cannot do a http call in the main thread) and then pass a class to download the file after using the name of the file.
FileNameUtil.java
public class FileNameUtil extends AsyncTask<String, Void, String> {
private OnGetFileNameCompleted mListener;
public FileNameUtil(OnGetFileNameCompleted listener) {
super();
mListener = listener;
}
@Override
public String doInBackground(String... params) {
String filename = null;
try {
URL url = new URL(params[0]);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Cookie", "PHPSESSID=" + WebService.sessionId);
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 (Exception e) {
}
return filename;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(String filename) {
super.onPostExecute(filename);
mListener.processFinish(filename);
}
}
OnGetFileNameCompleted.java
public interface OnGetFileNameCompleted {
void processFinish(String filename);
}
Activivty.java
final Context c = this;
row.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final String url = "http://192.168.1.100/document.php?id=583";
FileNameUtil fileNameUtil = new FileNameUtil(new OnGetFileNameCompleted() {
@Override
public void processFinish(String filename) {
try {
DownloadManager dm = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.addRequestHeader("Cookie", "PHPSESSID=" + WebService.sessionId);
dm.enqueue(request);
if (filename != null) {
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
}
Intent i = new Intent();
i.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS);
context.startActivity(i);
} catch (Exception e) {
showMessage(R.string.error, R.string.error_occurred);
}
}
});
fileNameUtil.execute(url);
}
});
来源:https://stackoverflow.com/questions/15879119/how-to-get-file-name-when-clicking-on-url-in-webview