7

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

我正在做的是,我在 webview 中提供带有文件链接的数据,因此每当用户单击链接时,都需要从服务器下载,因为我已经从服务器下载了此文件,但问题无法使用 DownloadManager 获取其确切类型和名称。我想要这样

在此处输入图像描述

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

编辑抱歉忘记提到我的网址看起来像这样

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

4 回答 4

10

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

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 的情况下使用它,只需为除 url 之外的每个参数传递“null”(也传递 url)。

编辑:这仅在您有一个嵌入了文件名的 url 时才有效。如果您正在寻找一种更简单的方法,请参阅上面的 Pratik 的答案。

于 2013-04-08T17:16:21.650 回答
10

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

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

我还发现这个来自 URL 的文件名不包含文件名后缀帖子,通过该帖子我获得了有关标题详细信息的更多详细信息,我们可以在请求时获得这些详细信息。

因为我们可以使用它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
    }
}
于 2013-04-16T05:22:36.117 回答
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);
    }
}
于 2017-04-30T01:55:50.110 回答
0

这将从需要身份验证的服务器(通过 cookie)获取文件名。为此,您需要从服务器 content-disposition 标头中获取文件名,我们执行此异步操作(您不能在主线程中进行 http 调用),然后在使用文件名后传递一个类来下载文件。

文件名Util.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);
}

Activty.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);
            }
        });
于 2018-06-04T13:18:04.687 回答