You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio下载文件保留原文件名问题求助(.lrc存为.txt)

解决WebView下载.lrc文件被保存为.txt的问题

问题核心在于URLUtil.guessFileName的自动识别逻辑存在缺陷,加上系统对.lrc文件的MIME类型映射不明确,导致扩展名被错误替换成.txt。以下是修改后的代码和关键处理步骤:

修改后的代码

webview.setDownloadListener(new DownloadListener() {
    @Override
    public void onDownloadStart(String url, String userAgent, String contentDisposition, String fileExtension, long contentLength) {
        // 从URL提取真实扩展名
        String extFromUrl = MimeTypeMap.getFileExtensionFromUrl(url);
        // 优先使用URL中的扩展名,无则用传入的fileExtension
        String targetExt = TextUtils.isEmpty(extFromUrl) ? fileExtension : extFromUrl;
        // 强制保留lrc扩展名
        if ("lrc".equalsIgnoreCase(targetExt)) {
            targetExt = "lrc";
        }

        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
        String cookies = CookieManager.getInstance().getCookie(url);
        request.addRequestHeader("cookie", cookies);
        request.addRequestHeader("User-Agent", userAgent);
        request.setDescription("Downloading file....");
        
        // 自定义文件名生成,避免扩展名被替换
        String fileName = URLUtil.guessFileName(url, contentDisposition, null);
        // 如果文件名是txt但目标扩展名是lrc,替换后缀
        if (fileName.endsWith(".txt") && "lrc".equalsIgnoreCase(targetExt)) {
            fileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".lrc";
        } else if (!fileName.contains(".")) {
            // 无扩展名时手动添加
            fileName += "." + targetExt;
        }
        
        request.setTitle(fileName);
        request.allowScanningByMediaScanner();
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
        
        // 设置正确的MIME类型,避免系统误判
        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(targetExt);
        if (!TextUtils.isEmpty(mimeType)) {
            request.setMimeType(mimeType);
        } else if ("lrc".equalsIgnoreCase(targetExt)) {
            // 找不到MIME类型时,用二进制流类型兜底
            request.setMimeType("application/octet-stream");
        }

        DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        dm.enqueue(request);
        Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_SHORT).show();
    }
});

关键处理点

  • 手动控制扩展名:优先从URL提取扩展名,强制保留.lrc后缀,避免依赖服务器返回的可能错误的fileExtension参数。
  • 重写文件名逻辑:替换URLUtil.guessFileName生成的错误.txt后缀,确保文件名正确。
  • 指定MIME类型:给DownloadManager明确文件类型,防止系统因MIME映射缺失而将.lrc识别为.txt。

额外注意

  • 检查下载链接是否确实包含.lrc后缀,比如http://example.com/xxx.lrc。
  • 如果服务器返回的contentDisposition头部里的文件名是.txt,上述代码也会自动替换成.lrc。
  • 测试时可以打印fileName和targetExt的值,快速定位问题点。

内容的提问来源于stack exchange,提问作者Dibya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 16:15:51