Webview setDownloadListener下载文件名异常 如何保留原名并添加自定义后缀
WebView下载文件名异常修复方案
根因说明
你遇到的文件名被替换为随机字符串的问题,核心是URLUtil.guessFileName方法在响应头contentDisposition未正确携带文件名、URL无明文文件名的场景下,会自动生成哈希字符串作为文件名,才会出现原文件abc.pdf变为随机串的情况。
另外你原有代码中多次调用URLUtil.guessFileName,也可能出现多次调用返回结果不一致的问题。
修改步骤
- 优先从
contentDisposition中解析原始文件名,兜底使用URLUtil.guessFileName的返回结果,保证拿到的文件名尽可能贴近原始名称 - 拆分原始文件名的主名和后缀,拼接你需要的
_my_project_name标识(示例效果为abc.pdf→abc_my_project_name.pdf,如果需要调整拼接规则可自行修改逻辑) - 统一使用拼接后的最终文件名设置下载任务的标题、存储路径,避免重复调用猜文件名方法导致的结果不一致
修改后完整代码
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); // 优先获取原始文件名,兜底用系统猜文件名的结果 String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType); // 拆分文件名和后缀,拼接自定义标识 int lastDotIndex = fileName.lastIndexOf("."); String nameWithoutExt = fileName; String ext = ""; if (lastDotIndex > 0) { nameWithoutExt = fileName.substring(0, lastDotIndex); ext = fileName.substring(lastDotIndex); } // 生成最终文件名,可根据需求调整拼接规则 String finalFileName = nameWithoutExt + "_my_project_name" + ext; request.addRequestHeader("cookie",cookies); request.addRequestHeader("User-Agent",userAgent); request.setDescription("Downloading file..."); // 用最终文件名设置标题 request.setTitle(finalFileName); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // 用最终文件名设置存储路径 request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, finalFileName); DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); dm.enqueue(request); Toast.makeText(getApplicationContext(),"Downloading File...",Toast.LENGTH_LONG).show(); } });
注意事项
- Android 13(API 33)及以上版本需要申请
POST_NOTIFICATIONS权限,才能正常显示下载完成通知 - 如果需要优先提取
contentDisposition中的精确文件名,可添加以下解析逻辑替换URLUtil.guessFileName的结果:
// 可选:从contentDisposition中精确解析文件名 if (!TextUtils.isEmpty(contentDisposition)) { Pattern pattern = Pattern.compile("filename=\"?(.*?)\"?;", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(contentDisposition); if (matcher.find()) { try { fileName = URLDecoder.decode(matcher.group(1), "UTF-8"); } catch (UnsupportedEncodingException e) { // 解码失败就用原来的fileName结果 } } }
内容的提问来源于stack exchange,提问作者Shivani Patil
相关产品推荐
相关产品推荐

