MediaStore.Images.Media.insertImage возвращает значение null при попытке сохранить изображение

Я использую пользовательское представление и тем, что я использую холст, в котором пользователь может рисовать что-либо, и после этого я хочу сохранить это изображение на SD-карте, bt не смог этого сделать. Не знаю, что происходит.

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();
        }

ЗДЕСЬ ИНФОРМАЦИЯ ОШИБОК

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)

Я всегда получаю это сообщение, пытаясь сохранить изображение.... "Упс! Изображение не может быть сохранено"......

Ответы

Ответ 1

У меня была эта проблема в эмуляторе (Android 4.4) и получается из-за ошибки Android, где это происходит, когда пользователь не сделал снимок на устройстве до (т.е. галерея пуста и не была инициализирована). Обходным путем является инициализация каталога фотографий вручную:

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

Не уверен, что это исправлено в более поздних версиях Android.

Ответ 2

Немного поздний ответ, но все же...

Не уверен, что это строка 238, но, вероятно, причина здесь:

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

Так как метод находится внутри прослушивателя кликов, getContentResolver может возвращать Resolver, отличный от того, который используется для приложения. Либо сохраните личную ссылку на преобразователь содержимого, либо вы можете попробовать заменить getContentResolver на MainActivity.this.getContentResolver():

String imgSaved = MediaStore.Images.Media.insertImage(                             MainActivity.this.getContentResolver(),                             drawView.getDrawingCache(),                             UUID.randomUUID(). ToString() + ".png",                              "Рисунок" );

В качестве альтернативы, это может быть проблема разрешения. Убедитесь, что в манифесте есть:

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

Наконец, результат insertImage - это URI, imgSaved не лучшее имя для этой переменной:)