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

Android使用SiliCompressor压缩相册图片触发NumberFormatException问题

Android相册选图压缩触发NumberFormatException问题解决

问题场景

从相册选择单张/多张图片,使用SiliCompressor库压缩时抛出java.lang.NumberFormatException,错误提示为For input string: "msf:126968",触发代码为压缩图片的核心行:

File file = new File(SiliCompressor.with(getContext()).compress(FileUtils.getPath(getContext(), imageuri), new File(getContext().getCacheDir(), "temp" + i)));

报错原因

FileUtils.getPath(getContext(), imageuri)返回的不是图片的真实本地文件路径,而是msf:126968格式的MediaStore URI字符串。SiliCompressor的compress方法期望接收合法的文件路径,内部处理时会尝试将传入的字符串解析为数字(大概率是解析MediaStore资源ID),但msf:126968无法转成数字,因此抛出异常。

注:msf:开头的URI是Android 10及以上版本中MediaStore Files Provider的标识,这类URI无法直接映射到本地文件路径,旧的路径转换工具类(如FileUtils.getPath)对其处理完全失效。

解决方案

方案1:将URI对应的文件复制到临时文件后再压缩

先通过ContentResolver读取URI对应的文件内容,写入本地缓存的临时文件,再将临时文件路径传给SiliCompressor压缩:

  1. 新增临时文件转换方法:
private File getTempFileFromUri(Context context, Uri uri) throws IOException {
    InputStream inputStream = context.getContentResolver().openInputStream(uri);
    // 创建临时文件,后缀用jpg适配大多数图片格式
    File tempFile = File.createTempFile("temp_album_img", ".jpg", context.getCacheDir());
    
    try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
    } finally {
        if (inputStream != null) {
            inputStream.close();
        }
    }
    return tempFile;
}
  1. 修改压缩代码(以多选场景为例):
// 替换原压缩代码块
if (imageList.size() < 8) {
    imageuri = result.getData().getClipData().getItemAt(i).getUri();
    try {
        File originalTempFile = getTempFileFromUri(getContext(), imageuri);
        // 压缩临时文件
        File compressedFile = SiliCompressor.with(getContext()).compress(
            originalTempFile.getAbsolutePath(), 
            new File(getContext().getCacheDir(), "temp" + i)
        );
        // 压缩完成后删除临时原文件,节省缓存空间
        originalTempFile.delete();
        
        compresseduri = Uri.fromFile(compressedFile);
        imageList.add(new CustomModel(getfilename(imageuri), compresseduri));
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(getContext(), "图片压缩失败", Toast.LENGTH_SHORT).show();
    }
} else {
    Toast.makeText(getContext(), "最多选择8张图片", Toast.LENGTH_SHORT).show();
}

方案2:使用SiliCompressor的URI压缩方法(推荐)

如果使用的SiliCompressor版本支持直接处理URI(需确认版本,部分新版本提供compressUri方法),可以直接传入URI进行压缩,省去路径转换步骤:

File compressedFile = SiliCompressor.with(getContext()).compressUri(
    imageuri, 
    new File(getContext().getCacheDir(), "temp" + i)
);
compresseduri = Uri.fromFile(compressedFile);

额外注意事项

  • Android 10及以上版本推荐使用MediaStore API处理媒体文件,避免直接操作文件路径,适配Scoped Storage。
  • 压缩完成后记得清理临时文件,防止占用过多缓存空间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:40:26