[android] android-갤러리에 이미지 저장

이미지 갤러리가있는 앱이 있고 사용자가 자신의 갤러리에 저장할 수 있기를 바랍니다. 이를 허용하기 위해 단일 음성 “저장”으로 옵션 메뉴를 만들었지 만 문제는 … 갤러리에 이미지를 어떻게 저장할 수 있습니까?

이것은 내 코드입니다.

@Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle item selection
            switch (item.getItemId()) {
            case R.id.menuFinale:

                imgView.setDrawingCacheEnabled(true);
                Bitmap bitmap = imgView.getDrawingCache();
                File root = Environment.getExternalStorageDirectory();
                File file = new File(root.getAbsolutePath()+"/DCIM/Camera/img.jpg");
                try
                {
                    file.createNewFile();
                    FileOutputStream ostream = new FileOutputStream(file);
                    bitmap.compress(CompressFormat.JPEG, 100, ostream);
                    ostream.close();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }



                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }

코드의이 부분을 잘 모르겠습니다.

File root = Environment.getExternalStorageDirectory();
                File file = new File(root.getAbsolutePath()+"/DCIM/Camera/img.jpg");

갤러리에 저장하는 것이 맞습니까? 불행히도 코드가 작동하지 않습니다.



답변

MediaStore.Images.Media.insertImage(getContentResolver(), yourBitmap, yourTitle , yourDescription);

이전 코드는 갤러리 끝에 이미지를 추가합니다. 시작 또는 다른 메타 데이터에 나타나도록 날짜를 수정하려면 아래 코드를 참조하십시오 (Cortesy of SK, samkirton ).

https://gist.github.com/samkirton/0242ba81d7ca00b475b9

/**
 * Android internals have been modified to store images in the media folder with
 * the correct date meta data
 * @author samuelkirton
 */
public class CapturePhotoUtils {

    /**
     * A copy of the Android internals  insertImage method, this method populates the
     * meta data with DATE_ADDED and DATE_TAKEN. This fixes a common problem where media
     * that is inserted manually gets saved at the end of the gallery (because date is not populated).
     * @see android.provider.MediaStore.Images.Media#insertImage(ContentResolver, Bitmap, String, String)
     */
    public static final String insertImage(ContentResolver cr,
            Bitmap source,
            String title,
            String description) {

        ContentValues values = new ContentValues();
        values.put(Images.Media.TITLE, title);
        values.put(Images.Media.DISPLAY_NAME, title);
        values.put(Images.Media.DESCRIPTION, description);
        values.put(Images.Media.MIME_TYPE, "image/jpeg");
        // Add the date meta data to ensure the image is added at the front of the gallery
        values.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
        values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis());

        Uri url = null;
        String stringUrl = null;    /* value to be returned */

        try {
            url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

            if (source != null) {
                OutputStream imageOut = cr.openOutputStream(url);
                try {
                    source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
                } finally {
                    imageOut.close();
                }

                long id = ContentUris.parseId(url);
                // Wait until MINI_KIND thumbnail is generated.
                Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id, Images.Thumbnails.MINI_KIND, null);
                // This is for backward compatibility.
                storeThumbnail(cr, miniThumb, id, 50F, 50F,Images.Thumbnails.MICRO_KIND);
            } else {
                cr.delete(url, null, null);
                url = null;
            }
        } catch (Exception e) {
            if (url != null) {
                cr.delete(url, null, null);
                url = null;
            }
        }

        if (url != null) {
            stringUrl = url.toString();
        }

        return stringUrl;
    }

    /**
     * A copy of the Android internals StoreThumbnail method, it used with the insertImage to
     * populate the android.provider.MediaStore.Images.Media#insertImage with all the correct
     * meta data. The StoreThumbnail method is private so it must be duplicated here.
     * @see android.provider.MediaStore.Images.Media (StoreThumbnail private method)
     */
    private static final Bitmap storeThumbnail(
            ContentResolver cr,
            Bitmap source,
            long id,
            float width,
            float height,
            int kind) {

        // create the matrix to scale it
        Matrix matrix = new Matrix();

        float scaleX = width / source.getWidth();
        float scaleY = height / source.getHeight();

        matrix.setScale(scaleX, scaleY);

        Bitmap thumb = Bitmap.createBitmap(source, 0, 0,
            source.getWidth(),
            source.getHeight(), matrix,
            true
        );

        ContentValues values = new ContentValues(4);
        values.put(Images.Thumbnails.KIND,kind);
        values.put(Images.Thumbnails.IMAGE_ID,(int)id);
        values.put(Images.Thumbnails.HEIGHT,thumb.getHeight());
        values.put(Images.Thumbnails.WIDTH,thumb.getWidth());

        Uri url = cr.insert(Images.Thumbnails.EXTERNAL_CONTENT_URI, values);

        try {
            OutputStream thumbOut = cr.openOutputStream(url);
            thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut);
            thumbOut.close();
            return thumb;
        } catch (FileNotFoundException ex) {
            return null;
        } catch (IOException ex) {
            return null;
        }
    }
}


답변

사실, 당신은 어디에서나 사진을 저장할 수 있습니다. 다른 애플리케이션이 액세스 할 수 있도록 공용 공간에 저장하려면 다음 코드를 사용하십시오.

storageDir = new File(
    Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES
    ),
    getAlbumName()
);

사진이 앨범으로 이동하지 않습니다. 이렇게하려면 스캔을 호출해야합니다.

private void galleryAddPic() {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    this.sendBroadcast(mediaScanIntent);
}

https://developer.android.com/training/camera/photobasics.html#TaskGallery 에서 자세한 정보를 찾을 수 있습니다.


답변

Marshmallow와 Lollipop에서이 작업을 수행하기 위해 많은 시도를했습니다. 마지막으로 저장된 사진을 DCIM 폴더로 옮겼습니다 (새 Google 포토 앱은이 폴더 안에 분명히있는 경우에만 이미지를 스캔합니다)

public static File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
         .format(System.currentTimeInMillis());
    File storageDir = new File(Environment
         .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera/");
    if (!storageDir.exists())
        storageDir.mkdirs();
    File image = File.createTempFile(
            timeStamp,                   /* prefix */
            ".jpeg",                     /* suffix */
            storageDir                   /* directory */
    );
    return image;
}

그런 다음 Google Developers 사이트에서도 찾을 수있는 파일 스캔을위한 표준 코드입니다 .

public static void addPicToGallery(Context context, String photoPath) {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(photoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    context.sendBroadcast(mediaScanIntent);
}

이 폴더는 전 세계의 모든 장치에있을 수는 없으며 Marshmallow (API 23)부터는 사용자에게 WRITE_EXTERNAL_STORAGE에 대한 권한을 요청해야합니다.


답변

이 과정 에 따르면 를 수행하는 올바른 방법은 다음과 같습니다.

Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES
    )

갤러리 디렉토리의 루트 경로를 제공합니다.


답변

private void galleryAddPic() {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    this.sendBroadcast(mediaScanIntent);
}


답변

카메라 폴더 안에 디렉토리를 생성하고 이미지를 저장할 수 있습니다. 그 후에 간단히 스캔을 수행 할 수 있습니다. 갤러리에 이미지가 즉시 표시됩니다.

String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString()+ "/Camera/Your_Directory_Name";
File myDir = new File(root);
myDir.mkdirs();
String fname = "Image-" + image_name + ".png";
File file = new File(myDir, fname);
System.out.println(file.getAbsolutePath());
if (file.exists()) file.delete();
    Log.i("LOAD", root + fname);
    try {
        FileOutputStream out = new FileOutputStream(file);
        finalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
        out.flush();
        out.close();
    } catch (Exception e) {
       e.printStackTrace();
    }

MediaScannerConnection.scanFile(context, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);


답변

나는 똑같은 의심으로 여기에 왔지만 Android 용 Xamarin의 경우 파일을 저장 한 후이 방법을 수행하기 위해 Sigrist 답변을 사용했습니다.

private void UpdateGallery()
{
    Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
    Java.IO.File file = new Java.IO.File(_path);
    Android.Net.Uri contentUri = Android.Net.Uri.FromFile(file);
    mediaScanIntent.SetData(contentUri);
    Application.Context.SendBroadcast(mediaScanIntent);
} 

그리고 그것은 내 문제를 해결했습니다, Thx Sigrist. Xamarin에 대한 answare를 찾지 못했기 때문에 여기에 넣었으며 다른 사람들을 도울 수 있기를 바랍니다.