Menggunakan penyimpanan internal android untuk gambar

Saya mencoba menyimpan file gambar ke penyimpanan internal aplikasi saya.

Untuk melakukan ini, saya menulis metode berikut yang mengambil id dan bitmap dan membuat file gambar, di mana direktori adalah bidang statis kelas bertipe 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;
}

Apa yang dilakukan metode ini adalah mendapatkan id dan bitmap dan menyimpan file aslinya dan membuat thumbnail ke dalam penyimpanan internal.

Nama-nama tersebut dihasilkan sebagai [id+".png"] untuk file asli dan [id+"_tn.png"] untuk file thumbnail.

saveBitmap() mehtod adalah yang menulis bitmap ke penyimpanan internal.

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) {}
}

Dibutuhkan nama file (11.png, 11_tn.png, ...) dan bitmap (apakah itu asli atau thumbnail) dan membuat file dan mengompresnya ke dalam aliran keluarannya.

Yang aneh adalah ketika saya menjalankan aplikasi saya untuk pertama kalinya menyimpan gambar, itu berfungsi dengan baik.

Itu dapat membaca dan menulis gambar yang disimpan di penyimpanan internal.

Namun, setelah saya menutup aplikasi saya dan menjalankannya lagi, FileNotFoundException muncul dengan log berikut.

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

Satu-satunya kesimpulan yang bisa saya ambil adalah penyimpanan internal berubah atau filenya terhapus setelah aplikasi saya ditutup, tapi saya tidak tahu kenapa.

Apa yang saya duga sekarang adalah saya memiliki masalah dengan pengujian saya.

Saya menguji ini sebagai berikut.

  1. Kompilasi dan jalankan proyek dengan penyisipan file dan periksa.

  2. Kompilasi dan jalankan proyek tanpa penyisipan file dan periksa apakah ada 1 data yang tersisa.

Saya melakukan ini karena saya tidak membuat ui apa pun untuk menulis atau membaca file di aplikasi saya.

Satu-satunya dugaan saya adalah ketika saya mengkompilasi proyek lagi, entah bagaimana itu mengubah sesuatu yang unik dalam konteks aplikasi saya yang menyebabkan perubahan penyimpanan internal yang menurut saya itu tidak masuk akal.

Dimana salahku??


person Hyun I Kim    schedule 06.04.2017    source sumber


Jawaban (2)


Ada beberapa hal yang mungkin Anda lakukan salah. Kapan pun Anda ingin membaca/menulis penyimpanan internal/eksternal, Anda harus memastikan Anda melakukan hal-hal berikut;

  1. Masukkan READ/WRITE Izin penyimpanan di Manifes Anda.
  2. Jika Android Version Anda Marshmallow atau lebih besar, mintalah izin run-time. Anda dapat memperoleh informasi tentang ini di sini
  3. Pastikan path benar. Seringkali jalur yang dikodekan dengan keras membuat perbedaan. Lihat di sini untuk detail selengkapnya.
  4. Pastikan Anda menelepon mkdirs() jika directory tidak ada.
  5. Pastikan filename benar. Anda tadi mengatakan bahwa itu 11.png dan 11_tn.png tetapi kemudian Anda mengakses 1.png. Mungkin ini menyebabkan masalah.
person Waqas Ahmed Ansari    schedule 06.04.2017
comment
Terima kasih atas balasannya, tetapi saya menggunakan penyimpanan internal dan tidak memerlukan izin. Saya tidak membuat kode keras untuk jalurnya tetapi mendapatkannya dari ContextWrapper. Saya memeriksa apakah folder tersebut ada di dalam pernyataan if dalam metode saveBitmapWithThumbnail(). 11.png dan 11_tn.png hanya contoh dan saya menggunakan nama file sesuai dengan id sqllite yang dimulai dari 1. Oleh karena itu aplikasi saya mencoba mengakses 1.png dan 1_tn.png. Mereka adalah orang pertama yang dimasukkan ke dalam database dan id disetel ke 1. - person Hyun I Kim; 06.04.2017
comment
error Anda dengan jelas mengatakan tidak menemukan file tersebut, jadi pasti ada yang salah dengan penyimpanannya. Lihat di sini - person Waqas Ahmed Ansari; 06.04.2017
comment
Ya... Itu sebabnya saya sangat bingung.. Saya melihat pertanyaan itu ketika saya mencari masalah ini tetapi dia membingungkan jalur penyimpanan internal dan eksternal sementara saya hanya menggunakan jalur internal yang disediakan oleh ContextWrapper dan File. Selain itu, ini jauh lebih aneh karena kode saya berfungsi saat pertama kali dieksekusi. Ia dapat menulis dan membaca gambar. Kesalahan terjadi ketika saya menutup aplikasi dan menjalankannya kembali.. Saya tidak tahu apa yang terjadi. :( - person Hyun I Kim; 06.04.2017

Anda harus memberikan izin runtime untuk marshmallow ke atas:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />`
person sanjeev kumar    schedule 06.04.2017
comment
Terima kasih atas balasannya, tapi saya menggunakan penyimpanan internal yang tidak memerlukan izin. - person Hyun I Kim; 06.04.2017