2017-04-06 56 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和文件提供的內部路徑。而且,它更奇怪,因爲我的代碼在第一次執行時起作用。它可以寫入和讀取圖像。當我關閉我的應用程序並重新運行它時發生錯誤..我不知道什麼是布萊恩。 :( –