2017-04-06 49 views
0

我想保存图像文件到我的应用程序的内部存储机器人的内部存储。使用的图像

为此,我编写了以下方法,它采用id和bitmap并创建一个图像的文件,其中directory是类型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()mehtod是将位图写入内部存储的一个。

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,...)和位图(无论是原件或缩略图),使文件和压缩到它的OutputStream。

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

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

但是,在关闭我的应用程序并再次运行它之后,它会抛出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的数据是否剩余。

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

我唯一的猜测是当我再次编译这个项目时,它会以某种方式改变我的应用程序的上下文中独特的东西,这会导致内部存储器的更改,我认为这完全是无稽之谈。

我在哪里错了?

回答

0

你必须给runtime许可棉花糖及以上:

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

感谢您的回复,但我使用的是不需要许可的内部存储。 –

0

有几件事情,你可能是做错了什么。每当你想读/写内部/外部存储,你必须确保你做了以下的事情;

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

感谢您的回复,但我正在使用内部存储并且不需要权限。我不硬编码的路径,但从ContextWrapper得到它。我检查文件夹是否存在于saveBitmapWithThumbnail()方法中的if语句中。 11.png和11_tn.png只是一个例子,我使用的是根据sqllite的id从1开始的文件名。这就是为什么我的应用程序试图访问1.png和1_tn.png。他们是第一个放在数据库里面,id设置为1. –

+0

你的'错误'清楚地表明它没有找到该文件,所以存储器肯定有问题。看看[这里](http://stackoverflow.com/questions/26579869/how-can-i-let-users-access-the-internal-storage-directory-of-my-app) –

+0

是啊...这就是为什么我很困惑..当我搜索这个问题时,我看到了这个问题,但他混淆了内部和外部存储路径,而我只使用ContextWrapper和文件提供的内部路径。而且,它更奇怪,因为我的代码在第一次执行时起作用。它可以写入和读取图像。当我关闭我的应用程序并重新运行它时发生错误..我不知道什么是布莱恩。 :( –