使用SiliCompressor压缩图片时抛出NumberFormatException求助
解决SiliCompressor图片压缩时的NumberFormatException异常
问题场景
在Android项目中使用SiliCompressor进行图片压缩时触发NumberFormatException,多次尝试无法解决,求修复方案。
相关代码
activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { if (result.getResultCode() == RESULT_OK && null != result.getData()) { if (result.getData().getClipData() != null) { int countofImages = result.getData().getClipData().getItemCount(); // 多选图片逻辑 for (int i = 0; i < countofImages; i++) { if (imageList.size() < 8) { imageuri = result.getData().getClipData().getItemAt(i).getUri(); File file = new File(SiliCompressor.with(getContext()).compress(FileUtils.getPath(getContext(), imageuri), new File(getContext().getCacheDir(), "temp" + i))); compresseduri = Uri.fromFile(file); imageList.add(new CustomModel(getfilename(imageuri), compresseduri)); } else { Toast.makeText(getContext(), "Can't select more than 8 images", Toast.LENGTH_SHORT).show(); } } adapter.notifyDataSetChanged(); rentSell3Binding.totalphotos.setText("Photos (" + imageList.size() + ")"); } // 单选图片逻辑 else { if (imageList.size() < 8) { imageuri = result.getData().getData(); File file = new File(SiliCompressor.with(getContext()).compress(FileUtils.getPath(getContext(), imageuri), new File(getContext().getCacheDir(), "temp"))); compresseduri = Uri.fromFile(file); imageList.add(new CustomModel(getfilename(imageuri), compresseduri)); } else { Toast.makeText(getContext(), "Can't select more than 8 images", Toast.LENGTH_SHORT).show(); } adapter.notifyDataSetChanged(); rentSell3Binding.totalphotos.setText("Photos (" + imageList.size() + ")"); } } } });
报错信息
报错行
File file = new File(SiliCompressor.with(getContext()).compress(FileUtils.getPath(getContext(), imageuri), new File(getContext().getCacheDir(), "temp" + i)));
堆栈信息
java.lang.NumberFormatException: For input string: "msf:126968" at java.lang.Long.parseLong(Long.java:594) at java.lang.Long.valueOf(Long.java:808) at com.iceteck.silicompressorr.FileUtils.getPath(FileUtils.java:288) at com.shrihari.backsoon.Listing_Fragment_3$5.onActivityResult(Listing_Fragment_3.java:263)
修复方案
根本原因
SiliCompressor自带的FileUtils.getPath方法无法兼容msf:开头的特殊Uri,该方法内部尝试将此类Uri的部分内容转换为Long类型,导致转换失败抛出异常。
具体解决方法
1. 替换Uri转文件路径逻辑,改用ContentResolver复制文件到本地缓存
放弃使用SiliCompressor的FileUtils.getPath,通过ContentResolver将Uri指向的文件内容复制到本地缓存,再将缓存文件传给压缩工具:
// 新增方法:将Uri内容复制到本地缓存文件 private File copyUriToCache(Context context, Uri uri, String fileName) throws IOException { File cacheFile = new File(context.getCacheDir(), fileName); try (InputStream inputStream = context.getContentResolver().openInputStream(uri); OutputStream outputStream = new FileOutputStream(cacheFile)) { byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, length); } } return cacheFile; }
修改压缩逻辑:
// 替换原来的压缩代码段 if (imageList.size() < 8) { imageuri = result.getData().getClipData().getItemAt(i).getUri(); try { // 将Uri对应的文件复制到缓存 File sourceFile = copyUriToCache(getContext(), imageuri, "source_" + i); File compressedFile = new File(getContext().getCacheDir(), "temp" + i); // 传入缓存文件路径进行压缩 String compressedPath = SiliCompressor.with(getContext()).compress(sourceFile.getAbsolutePath(), compressedFile); compresseduri = Uri.fromFile(new File(compressedPath)); imageList.add(new CustomModel(getfilename(imageuri), compresseduri)); } catch (IOException e) { e.printStackTrace(); Toast.makeText(getContext(), "图片压缩失败", Toast.LENGTH_SHORT).show(); } }
2. 升级SiliCompressor版本
检查当前使用的SiliCompressor版本,若为旧版本,尝试升级到最新版,查看官方是否修复了FileUtils对特殊Uri的兼容问题。
3. 直接传入File对象进行压缩
如果可行,直接将通过ContentResolver获取到的File对象传给SiliCompressor的compress方法,绕开路径解析步骤。
额外注意事项
- Android 10及以上版本中,使用
Uri.fromFile可能触发FileUriExposedException,建议改用FileProvider生成内容Uri。 - 所有IO操作需添加try-catch块处理异常,避免程序崩溃。
内容的提问来源于stack exchange,提问作者Puru Chaudhary
相关产品推荐
相关产品推荐

