Android中点击悬浮按钮从WebView下载文件
Hey there! Let's get this sorted—you want to trigger file downloads using a floating action button (FAB) instead of relying on WebView clicks, and you already have the WebView download logic working. Here's how to adapt that code for your FAB:
Step 1: Refactor your download logic into a reusable method
First, take the code you wrote in DownloadListener and wrap it into a standalone method. This way you can call it from both the WebView (if you still need that functionality) and your FAB.
private void startFileDownload(String url, String userAgent, String contentDisposition, String mimetype) { // Initialize download request with your target URL DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setMimeType(mimetype); // Pass along cookies (match your original logic here) String cookies = CookieManager.getInstance().getCookie(url); if (cookies != null) { request.addRequestHeader("Cookie", cookies); } // Configure download notifications and storage request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype); request.setTitle(fileName); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); // Trigger the download DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); if (downloadManager != null) { downloadManager.enqueue(request); Toast.makeText(this, "Download started!", Toast.LENGTH_SHORT).show(); } }
Step 2: Keep WebView download functionality (optional)
If you still want WebView clicks to trigger downloads, just update your existing listener to call the new method:
wv.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { startFileDownload(url, userAgent, contentDisposition, mimetype); } });
Step 3: Hook up your FAB to trigger downloads
Now, set a click listener on your FAB. The key here is having the correct download URL—if it's a fixed URL, hardcode it; if it's dynamic (from the WebView), you'll need to capture it first (see tip below).
// Assuming your FAB is named fabDownload in your layout FloatingActionButton fabDownload = findViewById(R.id.fabDownload); fabDownload.setOnClickListener(v -> { // Replace this with your actual download URL String targetDownloadUrl = "https://example.com/your-file-to-download.pdf"; // Get the user agent from your WebView (matches what WebView uses) String userAgent = wv.getSettings().getUserAgentString(); // If you don't have contentDisposition or mimetype, you can pass empty strings // DownloadManager will often auto-detect these, but specifying them helps with file handling startFileDownload(targetDownloadUrl, userAgent, "", "application/pdf"); });
Pro Tip: Capture dynamic download URLs from WebView
If your download link is embedded in the WebView's page content, you can extract it using JavaScript injection when the page finishes loading:
wv.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // Inject JS to grab the download link (adjust the selector to match your page's HTML) view.evaluateJavascript("document.querySelector('a.download-button').href", downloadUrl -> { // Clean up the quoted string returned by evaluateJavascript String cleanUrl = downloadUrl.replace("\"", ""); // Store this URL to use when the FAB is clicked // e.g., save it to a class variable like mDynamicDownloadUrl }); } });
Don't forget permissions
Make sure your AndroidManifest.xml has the necessary permissions:
<uses-permission android:name="android.permission.INTERNET" /> <!-- Only needed for Android 9 (API 28) and below --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
For Android 10 (API 29) and above, you don't need the WRITE_EXTERNAL_STORAGE permission—DownloadManager handles storing to public directories automatically.
内容的提问来源于stack exchange,提问作者Naveen Kumar Yadav

