如何从DownloadManager下载文件名

时间:2017-07-13 16:21:31

标签: android android-fragments download-manager

我在标签视图布局中有两个片段。我正在使用WebView()和DownloadManager()来下载文件。我的文件下载完美但下载的文件没有原始文件名。这是我的问题。如何获取原始文件名?我在这里找到了一些代码来解决这个问题,但是没有一个能帮助我......

以下是我使用下载管理器的片段:

public class Download extends Fragment {
    View v;
    WebView webView2;
    SwipeRefreshLayout mySwipeRefreshLayout;
    DownloadManager downloadManager;

    public String currentUrl = "";
    String myLink = "";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        v = inflater.inflate(R.layout.download, container, false);
        mySwipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swiperefresh);
        webView2 = (WebView) v.findViewById(R.id.webView_download);

        int permissionCheck = ContextCompat.checkSelfPermission(getContext(),
            Manifest.permission.WRITE_EXTERNAL_STORAGE);

        webView2.setInitialScale(1);
        webView2.getSettings().setJavaScriptEnabled(true);
        webView2.getSettings().setLoadWithOverviewMode(true);
        webView2.getSettings().setUseWideViewPort(true);
        webView2.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        webView2.setScrollbarFadingEnabled(false);
        webView2.setVerticalScrollBarEnabled(false);
        webView2.loadUrl(currentUrl);
        webView2.setWebViewClient(new WebViewClient());
        webView2.getSettings().setBuiltInZoomControls(true);
        webView2.getSettings().setUseWideViewPort(true);
        webView2.getSettings().setLoadWithOverviewMode(true);
        webView2.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        webView2.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                return (event.getAction() == MotionEvent.ACTION_MOVE);
            }
        });

        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
            Bundle bundle = getArguments();

            if (bundle != null) {
                String value = getArguments().getString("link");
                myLink = value;
                webView2.loadUrl(myLink);
            }

            webView2.setDownloadListener(new DownloadListener() {
                public void onDownloadStart(String url, String userAgent,
                                            String contentDisposition, String mimetype,
                                            long contentLength) {
                    Intent i = new Intent(Intent.ACTION_VIEW);
                    i.setData(Uri.parse(url));

                    downloadManager = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
                    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
                    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "Youtube_Video" + ".mp4");
                    request.allowScanningByMediaScanner();
                    Long reference = downloadManager.enqueue(request);

                    Toast.makeText(getContext(), "Downloading...", Toast.LENGTH_LONG).show();
                }
            });
        } else {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }

        return v;
    }
}

2 个答案:

答案 0 :(得分:1)

您将忽略在contentDisposition方法中收到的onDownloadStart()参数-例如,通过表单提交或POST请求或有时通过具有重定向功能的GET方法下载文件时, Content-disposition标头通常会包含您要查找的文件名。

import android.webkit.URLUtil;

// ...

webView.setDownloadListener(new DownloadListener() {
    public void onDownloadStart(
        String url,
        String userAgent,
        String contentDisposition, // <<< HERE IS THE ANSWER <<<
        String mimetype,
        long contentLength) {

        String humanReadableFileName = URLUtil.guessFileName(url, contentDisposition, mimetype);
        //     ^^^^^^^^^^^^^^^^^^^^^ the name you expect
    // ....


    });

即使contentDisposition将包含您的原始文件名,您仍然需要使用BroadcastReceiver来获取实际的内容Uri:

    BroadcastReceiver onCompleteHandler = new BroadcastReceiver() {
        public void onReceive(Context ctx, Intent intent) {
            long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
            if (downloadId == downloadRef) {
                Log.d(TAG, "onReceive: " + intent);
                DownloadManager.Query query = new DownloadManager.Query();
                query.setFilterById(downloadId);
                Cursor cur = downloadManager.query(query);

                if (cur.moveToFirst()) {
                    int columnIndex = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
                    if (DownloadManager.STATUS_SUCCESSFUL == cur.getInt(columnIndex)) {
                        String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));

                        Uri uriDownloadedFile = Uri.parse(uriString);
                        // TODO: consume the uri
                }

            }
        }
    };
    registerReceiver(onCompleteHandler, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

答案 1 :(得分:0)

HTTP通常不包含单独的文件名。您可以在URL路径中使用文件名,例如,在最后一个正斜杠之后取出所有内容:

String filename = currentUrl.substring(currentUrl.lastIndexOf('/') + 1);

然后将其传递给:

request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);

如果标题中有文件名,那么单独的HEAD请求就可以了(请参阅this answer)。