19

I am using an custom view and in that i am using an canvas in which a user can draw anything and after that i want to save that image in sd card bt was not able to do that. Don't know what is going on.

else if(view.getId()==R.id.save_btn){
            //save drawing
            AlertDialog.Builder saveDialog = new AlertDialog.Builder(this);
            saveDialog.setTitle("Save drawing");
            saveDialog.setMessage("Save drawing to device Gallery?");
            saveDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
                private FileOutputStream fOut;

                public void onClick(DialogInterface dialog, int which){
                    //save drawing
                    drawView.setDrawingCacheEnabled(true);

                    //attempt to save
                    String imgSaved = MediaStore.Images.Media.insertImage(
                            getContentResolver(), drawView.getDrawingCache(),
                            UUID.randomUUID().toString()+".png", "drawing");
                    //feedback
                    if(imgSaved!=null){
                        Toast savedToast = Toast.makeText(getApplicationContext(), 
                                "Drawing saved to Gallery!", Toast.LENGTH_SHORT);
                        savedToast.show();
                    }
                    else{
                        Toast unsavedToast = Toast.makeText(getApplicationContext(), 
                                "Oops! Image could not be saved.", Toast.LENGTH_SHORT);
                        unsavedToast.show();
                    }
                    drawView.destroyDrawingCache();
                }
            });
            saveDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
                public void onClick(DialogInterface dialog, int which){
                    dialog.cancel();
                }
            });
            saveDialog.show();
        }

HERE IS THE ERROR DETAILS

04-14 11:24:28.700: E/MediaStore(6866): Failed to insert image
04-14 11:24:28.700: E/MediaStore(6866): java.io.FileNotFoundException: No such file or directory
04-14 11:24:28.700: E/MediaStore(6866):     at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146)
04-14 11:24:28.700: E/MediaStore(6866):     at android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:577)
04-14 11:24:28.700: E/MediaStore(6866):     at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:673)
04-14 11:24:28.700: E/MediaStore(6866):     at android.content.ContentResolver.openOutputStream(ContentResolver.java:537)
04-14 11:24:28.700: E/MediaStore(6866):     at android.content.ContentResolver.openOutputStream(ContentResolver.java:513)
04-14 11:24:28.700: E/MediaStore(6866):     at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:891)
04-14 11:24:28.700: E/MediaStore(6866):     at com.example.clent.MainActivity$9.onClick(MainActivity.java:238)
04-14 11:24:28.700: E/MediaStore(6866):     at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
04-14 11:24:28.700: E/MediaStore(6866):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-14 11:24:28.700: E/MediaStore(6866):     at android.os.Looper.loop(Looper.java:137)
04-14 11:24:28.700: E/MediaStore(6866):     at android.app.ActivityThread.main(ActivityThread.java:5103)
04-14 11:24:28.700: E/MediaStore(6866):     at java.lang.reflect.Method.invokeNative(Native Method)
04-14 11:24:28.700: E/MediaStore(6866):     at java.lang.reflect.Method.invoke(Method.java:525)
04-14 11:24:28.700: E/MediaStore(6866):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
04-14 11:24:28.700: E/MediaStore(6866):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-14 11:24:28.700: E/MediaStore(6866):     at dalvik.system.NativeStart.main(Native Method)

I am always getting this message while trying to save image...."Oops! Image could not be saved.".....

Pravesh
  • 822
  • 1
  • 8
  • 20
  • having the same issue on Android 4.4.2 SM-P601. Insert image method always fails. with the same exception. – Taras Leskiv Aug 07 '15 at 11:59
  • Are you able to save as PNG? Because it seems that `insertImage` with a Bitmap parameter always saves as `image/jpeg` [source](http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/provider/MediaStore.java#976) – TechAurelian Aug 29 '20 at 09:42

2 Answers2

27

I had this issue in the Emulator (Android 4.4) and turns out it's due to an Android bug, where it happens when the user hasn't taken a photo on the device before (i.e. gallery is empty and hasn't been initialized.). The workaround is to initialize the photo directory manually:

void fixMediaDir() {
    File sdcard = Environment.getExternalStorageDirectory();
    if (sdcard != null) {
        File mediaDir = new File(sdcard, "DCIM/Camera");
        if (!mediaDir.exists()) {
            mediaDir.mkdirs();
        }
    }
}

Not sure if this is fixed in later versions of Android.

Dia Kharrat
  • 5,948
  • 3
  • 32
  • 43
8

A bit late answer, but still...

Not sure which is line 238, but probably the reason is here:

String imgSaved = MediaStore.Images.Media.insertImage( getContentResolver(), drawView.getDrawingCache(), UUID.randomUUID().toString()+".png", "drawing");

Since the method is within a click listener getContentResolver may be returning a Resolver different from the one for the application. Either save a private reference to the content resolver, or you could try replacing getContentResolver with MainActivity.this.getContentResolver() :

String imgSaved = MediaStore.Images.Media.insertImage( MainActivity.this.getContentResolver(), drawView.getDrawingCache(), UUID.randomUUID().toString() + ".png", "drawing");

Alternatively, it might be a permissioning problem. Make sure in the manifest you have:

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

One final note, the result of insertImage is an URI, imgSaved is not the best name for that variable :)

ılǝ
  • 3,440
  • 2
  • 33
  • 47
  • Thanks, your comment helped me. I made a private ContentResolver contentResolver as a field in my adapter, on initialisation i've attached getContext().getContentResolver(); to it and when doing insertImage i used the contentResolver. – lxknvlk Mar 29 '15 at 09:43