【问题标题】:Using android internal storage for images使用 android 内部存储存储图像
【发布时间】:2017-04-06 04:03:57
【问题描述】:

我正在尝试将图像文件保存到我的应用程序的内部存储中。

为此,我编写了以下方法,该方法采用 id 和位图并创建图像文件,其中目录是 File 类型的类静态字段。

// Returns thumbnail
private static Bitmap saveBitmapWithThumbnail(long id, Bitmap bitmap) {
    Bitmap thumbnail;

    if(directory == null) {
        ContextWrapper cw = new ContextWrapper(Engine.getContext());
        directory = cw.getDir(DIRECTORY_NAME, Context.MODE_PRIVATE);
        if(!directory.exists()) directory.mkdir();
    }

    saveBitmap(getImageFileName(id), bitmap);
    saveBitmap(getThumbnailFileName(id), thumbnail=makeThumbnail(bitmap));
    return thumbnail;
}

此方法的作用是获取一个 id 和位图并将其保存为原始文件和创建的缩略图到内部存储中。

原始文件的名称为 [id+".png"],缩略图文件的名称为 [id+"_tn.png"]。

saveBitmap() 方法是将位图写入内部存储的方法。

private static void saveBitmap(String fileName, Bitmap bitmap) {
    File imageFile = new File(directory, fileName);

    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(imageFile);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.close();
    } catch(Exception e) {}
}

它获取文件名(11.png、11_tn.png、...)和位图(无论是原始文件还是缩略图),然后创建一个文件并压缩到它的输出流中。

奇怪的是,当我第一次运行我的应用程序保存图像时,效果很好。

它可以读取和写入存储在内部存储器中的图像。

但是,在我关闭我的应用程序并再次运行它后,它会抛出 FileNotFoundException 并带有以下日志。

W/System.err: java.io.FileNotFoundException: /1.png: open failed: ENOENT (No such file or directory)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:458)
W/System.err:     at java.io.FileInputStream.<init>(FileInputStream.java:78)
W/System.err:     at com.google.dotplace.dotplace.data.Image.parseCursor(Image.java:118)
W/System.err:     at com.google.dotplace.dotplace.data.Image.checkDebug(Image.java:74)
W/System.err:     at com.google.dotplace.dotplace.LoadActivity.debugDatabase(LoadActivity.java:77)
W/System.err:     at com.google.dotplace.dotplace.LoadActivity.onCreate(LoadActivity.java:25)
W/System.err:     at android.app.Activity.performCreate(Activity.java:5275)
W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2167)
W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2253)
W/System.err:     at android.app.ActivityThread.access$800(ActivityThread.java:142)
W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1203)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err:     at android.os.Looper.loop(Looper.java:136)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5120)
W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err:     at java.lang.reflect.Method.invoke(Method.java:515)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
W/System.err:     at dalvik.system.NativeStart.main(Native Method)
W/System.err: Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
W/System.err:     at libcore.io.Posix.open(Native Method)
W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:442)
W/System.err:   ... 19 more

我唯一能得出的结论是在我的应用程序关闭后内部存储发生变化或文件被删除,但我不知道为什么。

我现在的猜测是我的测试有问题。

我正在测试如下。

  1. 编译并运行带有文件插入和检查的项目。

  2. 在不插入文件的情况下编译并运行项目,并检查 1 的数据是否剩余。

我这样做是因为我没有在我的应用程序中创建任何用于写入或读取文件的用户界面。

我唯一的猜测是,当我再次编译项目时,它会以某种方式改变我的应用程序上下文中的某些独特内容,从而导致内部存储发生变化,我认为这很无稽之谈。

我哪里错了??

【问题讨论】:

    标签: android android-bitmap android-internal-storage


    【解决方案1】:

    您可能做错了几件事。每当您想读/写内部/外部存储时,您必须确保执行以下操作;

    1. READ/WRITE 存储权限放入您的清单中。
    2. 如果您的Android VersionMarshmallow 或更大,请询问运行时权限。您可以获取有关此here 的信息
    3. 确保path 正确。大多数情况下,硬编码路径会有所不同。详情请参阅here
    4. 如果directory 不存在,请务必致电mkdirs()
    5. 确保filename 正确。您之前说它是11.png11_tn.png,但后来您访问了1.png。可能是这导致了问题。

    【讨论】:

    • 感谢您的回复,但我使用的是内部存储,它不需要许可。我没有对路径进行硬编码,而是从 ContextWrapper 获取它。我检查该文件夹是否存在于 saveBitmapWithThumbnail() 方法的 if 语句中。 11.png 和 11_tn.png 只是示例,我根据从 1 开始的 sqllite 的 id 使用文件名。这就是我的应用程序尝试访问 1.png 和 1_tn.png 的原因。他们是第一个放入数据库的,并且 id 被设置为 1。
    • 您的error 明确表示找不到文件,所以存储肯定有问题。看看here
    • 是的......这就是为什么我很困惑..我在搜索这个问题时看到了这个问题,但他混淆了内部和外部存储路径,而我只使用 ContextWrapper 和 File 提供的内部路径.此外,这更奇怪,因为我的代码在第一次执行时就可以工作。它可以写入和读取图像。当我关闭我的应用程序并重新运行它时发生错误。我不知道发生了什么。 :(
    【解决方案2】:

    你必须给runtime棉花糖及以上权限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />`
    

    【讨论】:

    • 感谢您的回复,但我使用的是不需要权限的内部存储。
    猜你喜欢
    • 2012-07-18
    • 2011-08-11
    • 2013-01-16
    • 2013-10-28
    • 1970-01-01
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多