单击webview中的URL时如何获取文件名

时间:2013-04-08 12:33:39

标签: android android-webview android-download-manager

当我们在页面中为该文件提供链接时,如何获取我们在服务器上传的文件名?

我正在做的是,我在webview中提供带有文件链接的数据,所以每当用户点击链接需要从服务器下载时,因为我从服务器下载了这个文件,但问题是无法得到它的确切类型和名称使用DownloadManager。我想要这样

enter image description here

在上面看到我在test_androt中给出了我的文件的链接,当我点击它时会给dailog带有文件名的选项,当用户点击WebView URL链接时我不知道如何实现这个文件名。

修改 很抱歉忘记提及我的网址如下

misc/dnload.php?t1=MzQ0MDA=&t2=MTY5NTUz&t3=MTY5NTUzMTMwMjEyMDNfcGhhcm1hY3kga2V5IGluZm8ucG5n&t4=MTMwMjEyMDM=

4 个答案:

答案 0 :(得分:10)

您可以简单地解析网址并获取最后一个“/”后的文本并将其设为文件名,或者您可以使用以下内容

URLUtil.guessFileName(url, contentDisposition, mimetype);

如下所示,因为我在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
}

如果你不想在你的DownloadListener中使用它,你可以在没有contentDisposition或mimetype的情况下使用它,只需为每个参数传递'null',除了url(传递url)。

编辑:仅当您有一个嵌入了文件名的网址时才有效。如果您正在寻找一种更加万无一失的方式,请参阅上面的Pratik答案。

答案 1 :(得分:10)

感谢Raghunandan的建议,我得到了答案。

这里我需要额外的调用来获取下载文件的标题信息。在标题部分,我得到了文件的名称。

此外,我发现了这个Filename from URL not containing filename suffix帖子,通过该帖子我可以获得有关标题详细信息的更多详细信息,我们可以在请求时间。

因为我们可以使用这个URLUtil.guessFileName(url, null, null)但是这将给出我的案例的调用方式的文件名我有这样的URL

misc/dnload.php?t1=MzQ0MDA=&t2=MTY5NTUz&t3=MTY5NTUzMTMwMjEyMDNfcGhhcm1hY3kga2V5IGluZm8ucG5n&t4=MTMwMjEyMDM=

所以从上面的链接中这将提取 dnload.php 作为文件名,它不是我们下载的原始文件名,只是为该文件创建了下载链接。

这里是使用这个的代码我们可以得到文件名它只是一个额外的调用来获取信息但实际上我们下载,下载我已经使用android内置api到DownloadManager下载文件。

Content-Disposition this is the attribute in header section through which we can get the file name as in attachment form.

它将以这种方式Content-Disposition: attachment; filename="fname.ext"返回信息,所以现在只需要提取文件名

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 :(得分:1)

Pratik解决方案的一些改进。

的变化:

1)修复了Content-Disposition中提取的文件名提取

2)添加了回调接口

用法:

new GetFileInfo(new GetFileInfoListener() {
    @Override
    public void onTaskCompleted(String fileName) {
        Log.v(TAG, "real filename is " + fileName);
    }
}).execute(url);

代码:

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);
    }
}

答案 3 :(得分:0)

这将从需要身份验证的服务器(通过cookie)获取文件名。为此,您需要从服务器内容处置标头获取文件名,我们执行此异步(您不能在主线程中执行http调用),然后在使用文件名后传递类以下载文件。

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);
            }
        });