Android应用使用OpenALPR触发NoSuchFileException的解决咨询
一、当前预加载图片的问题解决
你遇到的NoSuchFileException是因为Android的res/drawable目录下的资源并不是以文件系统中的普通文件存在的——它们会被打包进APK,编译后甚至会被重命名或压缩,所以直接用Paths.get()去读肯定找不到。这里有两种靠谱的解决方式:
方式1:保留在drawable,通过资源ID读取
利用Android的资源系统,通过getResources()获取输入流再转成字节数组,代码示例:
// 注意替换成你的Activity上下文,比如按钮点击里用this或者getContext() InputStream inputStream = getResources().openRawResource(R.drawable.license_plate); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; try { while ((len = inputStream.read(buffer)) != -1) { baos.write(buffer, 0, len); } byte[] data = baos.toByteArray(); // 这里就可以用data去调用OpenALPR的API了 } catch (IOException e) { e.printStackTrace(); } finally { try { inputStream.close(); baos.close(); } catch (IOException e) { e.printStackTrace(); } }
方式2:转移到assets目录读取
如果你更习惯用类似路径的方式访问,可以把图片放到app/src/main/assets目录下(没有的话手动新建这个目录),然后通过AssetManager读取:
AssetManager assetManager = getAssets(); try (InputStream inputStream = assetManager.open("license_plate.jpg"); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) != -1) { baos.write(buffer, 0, len); } byte[] data = baos.toByteArray(); // 用data调用API } catch (IOException e) { e.printStackTrace(); }
这里用了try-with-resources语法,能自动关闭流,更简洁安全。
二、非预加载多张图片的存储位置选择
如果是后续要处理用户拍摄、相册选择或者动态下载的图片,得根据你的需求来选存储位置:
应用私有内部存储:适合存储只有你的应用能访问的图片,比如缓存的识别结果。可以通过
getFilesDir()(永久存储,卸载才删)或getCacheDir()(缓存目录,空间不足时系统可能清理)获取路径,直接用Java文件API操作即可,比如:File imageFile = new File(getFilesDir(), "user_captured_plate.jpg");这种方式不需要申请任何权限。
外部存储的应用私有目录:如果图片比较大,想存在外部存储但又不想让其他应用访问,用
getExternalFilesDir(),比如:File imageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); File imageFile = new File(imageDir, "user_captured_plate.jpg");这里的文件在应用卸载时会被自动删除,Android 10及以上不需要权限。
外部公共目录:如果需要用户或其他应用能访问这些图片(比如用户要在相册里看到),可以用
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),但注意Android 10及以上需要申请MANAGE_EXTERNAL_STORAGE权限,或者用MediaStore API来写入,否则会有访问限制。
内容的提问来源于stack exchange,提问作者Bbb

