【发布时间】:2018-04-20 15:05:07
【问题描述】:
我正在努力解决文件保存问题。
我有两个特点:
- 拍照保存图片
- 将图片添加到图库
对于第一部分(文件保存),我使用
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
byte[] byteArray = stream.toByteArray();
final File file = new File(getAlbumStorageDir(context, Settings.ALBUM),
Settings.FILENAME_PREFIX + id + + ".jpg");
return saveDataToFile(byteArray , file);//writes bytes to file
public static File getAlbumStorageDir(Context context, String albumName) {
// Get the directory for the app's private pictures directory.
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e("LOG_TAG", "Directory not created");
}
return file;
}
对于第二部分,我将文件从 1 复制到公共存储目录并使其在图库中可用
File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), Settings.CAMERA_IMAGES_DIR + "/");
if (!storageDir.exists())
storageDir.mkdir();
File copyFile = new File(storageDir, fileToCopy.getName());
try {
copyFile.createNewFile();
copy(fileToCopy, copyFile);// writes bytes from one file to another
Uri finalUri = Uri.fromFile(copyFile);
galleryAddPic(finalUri, context);
} catch (java.io.IOException e) {
Crashlytics.logException(e);
}
public static void galleryAddPic(Uri contentUri, Context context) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, contentUri);
context.sendBroadcast(mediaScanIntent);
}
在我的情况和大多数其他情况下,这工作正常。
但有些用户收到以下错误:
Caused by java.io.IOException: open failed: ENOENT (No such file or directory)
at java.io.File.createNewFile(File.java:942)
at com.testapp.utils.Utils.copyImageFile(Utils.java:311)
at com.testapp.utils.Utils.savePhoto(Utils.java:420)
at com.testapp.fragments.PictureListFragment$3$4.onAction(PictureListFragment.java:297)
at com.testapp.views.PictureOverlayView$5.onClick(PictureOverlayView.java:145)
at android.view.View.performClick(View.java:5721)
at android.view.View$PerformClick.run(View.java:22620)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7406)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
我查了,这些用户有写外部权限。
在这些情况下,StorageDir 看起来像 /storage/emulated/0/Pictures/album。 storageDir.mkdir() 返回 false 并且此目录不存在。
这一步出现问题:
copyFile.createNewFile();
我将不胜感激任何帮助和建议。
【问题讨论】:
-
为什么不先检查 copyFile.createNewFile() 在做任何事情之前是否返回 true。
-
除了在清单中请求权限之外,您是否添加了 Android 6+ 的代码让用户确认这些权限?
-
if (!file.mkdirs()) { Log.e("LOG_TAG", "Directory not created"); }。不要盲目地调用 mkdirs(),因为当目录已经存在时,你会得到那个日志。你没看到吗。仅当目录不存在时才调用 mkdirs()。如果你不能强制该目录,你应该返回 null。并在调用函数后检查该 null。 -
if (!storageDir.exists()) storageDir.mkdir();。错误的!检查 mkdirs 的返回值。并显示一个 toast,如果为 false,则返回 null。 -
问题是 copyFile.createNewFile() 抛出异常并检查它的真实性不会有帮助。但感谢代码改进提示。