Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get file name when clicking on URL in webview

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

enter image description here

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=
like image 607
Pratik Avatar asked Apr 08 '13 12:04

Pratik


3 Answers

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
    }
}
like image 71
Pratik Avatar answered Nov 08 '22 11:11

Pratik


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.

like image 34
anthonycr Avatar answered Nov 08 '22 13:11

anthonycr


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);
    }
}
like image 20
yuliskov Avatar answered Nov 08 '22 13:11

yuliskov