Android WebView应用下载PDF后如何实现自动打开功能?
实现方案
现有代码无需大改,仅需补充下载完成监听和调用系统打开PDF的逻辑即可实现需求,完全复用现有从站点获取原始文件名的规则,不需要你自定义文件名。
修改步骤
1. 补充成员变量
在WebViewActivity类中增加以下成员变量:
// 存储当前PDF下载任务的ID,用于匹配下载完成广播 private long curPdfDownloadId; // 存储本次下载的PDF原始文件名 private String curPdfFileName; // 监听下载完成的广播接收器 private BroadcastReceiver downloadCompleteReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) { long completeId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); if (completeId == curPdfDownloadId) { openDownloadedPdf(); } } } };
2. 修改下载监听逻辑
调整原有setDownloadListener内的代码,保存下载任务ID和文件名:
webView.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) { DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setMimeType(mimeType); String cookies = CookieManager.getInstance().getCookie(url); request.addRequestHeader("cookie",cookies); request.addRequestHeader("User-Agent",userAgent); String fileName = URLUtil.guessFileName(url,contentDisposition,mimeType); request.setDescription("Downloading File"); request.setTitle(fileName); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); // 仅PDF文件增加自动打开逻辑,其他文件走原有下载逻辑 if ("application/pdf".equals(mimeType)) { curPdfFileName = fileName; curPdfDownloadId = downloadManager.enqueue(request); Toast.makeText(getApplicationContext(), "PDF下载中,完成后将自动打开", Toast.LENGTH_SHORT).show(); } else { downloadManager.enqueue(request); Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_SHORT).show(); } } });
3. 新增PDF打开方法
在WebViewActivity中新增打开PDF的工具方法,适配不同Android版本权限要求:
private void openDownloadedPdf() { File pdfFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), curPdfFileName); Uri pdfUri; // 适配Android 7.0及以上的文件访问权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { pdfUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", pdfFile); } else { pdfUri = Uri.fromFile(pdfFile); } Intent openIntent = new Intent(Intent.ACTION_VIEW); openIntent.setDataAndType(pdfUri, "application/pdf"); openIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); openIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); try { startActivity(openIntent); } catch (ActivityNotFoundException e) { Toast.makeText(this, "未找到可用的PDF阅读器,请先安装", Toast.LENGTH_SHORT).show(); } }
4. 注册/注销下载完成广播
调整原有onStart和onStop方法,注册和注销下载监听广播:
@Override protected void onStart() { IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(networkChangeListener, filter); // 新增注册下载完成广播 IntentFilter downloadFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); registerReceiver(downloadCompleteReceiver, downloadFilter); super.onStart(); } @Override protected void onStop() { unregisterReceiver(networkChangeListener); // 新增注销下载完成广播 unregisterReceiver(downloadCompleteReceiver); super.onStop(); }
5. 配置FileProvider(Android 7.0+必需)
- 在
res/xml目录下新建file_paths.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="downloads" path="Download/" /> </paths>
- 在
AndroidManifest.xml的application标签内添加Provider配置:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
注意说明
- 不需要你集成内置PDF阅读器,直接调用系统已安装的第三方PDF应用打开即可
- 如果你需要所有下载文件都自动打开,去掉下载逻辑里的mimeType判断即可
- 无PDF阅读器时会弹出提示,不会导致应用崩溃
内容的提问来源于stack exchange,提问作者Gedanggoreng
相关产品推荐
相关产品推荐

