【问题标题】:File saving issue to public storage directory文件保存到公共存储目录的问题
【发布时间】:2018-04-20 15:05:07
【问题描述】:

我正在努力解决文件保存问题。

我有两个特点:

  1. 拍照保存图片
  2. 将图片添加到图库

对于第一部分(文件保存),我使用

     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() 抛出异常并检查它的真实性不会有帮助。但感谢代码改进提示。

标签: java android file save


【解决方案1】:

从您的代码中,您尝试将文件存储在外部存储中。似乎体验过的用户没有SD卡。

【讨论】:

  • 所有设备都有外部存储。这里使用哪个。与可移动 micro SD 卡无关。
猜你喜欢
  • 2016-01-09
  • 2016-06-05
  • 1970-01-01
  • 2011-08-11
  • 2015-03-18
  • 1970-01-01
  • 2018-08-24
  • 1970-01-01
  • 2021-09-08
相关资源
最近更新 更多