Как получить имя файла при нажатии на URL в webview

Как получить имя файла, которое мы загрузили на сервер, когда мы предоставляем связанный для этого файла на странице?

что я делаю, я предоставляю данные с ссылкой на файл в webview, поэтому всякий раз, когда пользователь нажимает на ссылку, нужно загрузить с сервера, поскольку я загрузил этот файл с сервера, но проблема не может получить его точный тип и имя с помощью DownloadManager. Я хочу вот так!--2-->

enter image description here

см. выше я дал ссылку для моего файла в test_androt и когда я нажимаю, он даст dailog с опцией, имеющей имя файла, я не знаю, как достичь этого имени файла, когда пользователь нажимает на ссылку URL WebView.

изменить Извините, что забыл упомянуть, что мой URL выглядит так

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

4 ответов


я получил ответ благодаря 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
    }
}

вы можете просто разобрать 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, просто передав "null" для каждого параметра, кроме url (передайте url-адрес).

EDIT: это работает, только если у вас есть url с именем файла, встроенным в него. См. ответ Пратика выше, если вы ищете более надежный способ.


некоторые уточнения для решения Пратика.

изменения:

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=\"?([^\"]+)\"?.*$", "");
            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);
    }
}

это получит имя файла с сервера, который требует аутентификации (через cookies). Для этого вам нужно получить имя файла из заголовка content-disposition сервера, мы делаем это асинхронно (вы не можете сделать 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);
            }
        });