android: guarda la imagen en la galería

tengo una aplicación con una galería de imágenes y quiero que el usuario pueda guardarla en su propia galería. He creado un menú de opciones con una sola voz “guardar” para permitir eso, pero el problema es … ¿cómo puedo guardar la imagen en la galería?

este es mi código:

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

No estoy seguro de esta parte del código:

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

¿es correcto guardar en la galería? desafortunadamente el código no funciona 🙁

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

El código anterior agregará la imagen al final de la galería. Si desea modificar la fecha para que aparezca al principio o en cualquier otro metadato, consulte el siguiente código (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; } } } 

En realidad, puedes guardar tu foto en cualquier lugar. Si desea guardar en un espacio público, para que cualquier otra aplicación pueda acceder, use este código:

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

La imagen no va al álbum. Para hacer esto, debe llamar a un escaneo:

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

Puede encontrar más información en http://sofes.miximages.com/android/photobasics“, /* suffix */ storageDir /* directory */ ); return image; }

Y luego, el código estándar para escanear archivos que puedes encontrar en el sitio de Google Developers también .

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

Recuerde que esta carpeta no puede estar presente en todos los dispositivos del mundo y que, a partir de Marshmallow (API 23), debe solicitar permiso al WRITE_EXTERNAL_STORAGE para el usuario.

Según este curso , la forma correcta de hacerlo es:

 Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES ) 

thios le dará la ruta raíz para el directorio de la galería.

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

Vengo aquí con la misma duda, pero para Xamarin para Android, he utilizado la respuesta de Sigrist para hacer este método después de guardar mi archivo:

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

y resolvió mi problema, Thx Sigrist. Lo puse aquí porque no encontré un answare sobre esto para Xamarin y espero que pueda ayudar a otras personas.

En mi caso, las soluciones anteriores no funcionaron. Tuve que hacer lo siguiente:

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f))); 

Puede crear un directorio dentro de la carpeta de la cámara y guardar. Y escanea una vez que lo completes. Mostrará instantáneamente tu imagen en la galería. ¡¡Aclamaciones!!

  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); 
  String filePath="/storage/emulated/0/DCIM"+app_name; File dir=new File(filePath); if(!dir.exists()){ dir.mkdir(); } 

Este código está en el método Crear. Este código es para crear un directorio de nombre_aplicación. Ahora, se puede acceder a este directorio utilizando la aplicación de administrador de archivos predeterminada en Android. Use este string filePath donde sea necesario para establecer su carpeta de destino. Estoy seguro de que este método también funciona en Android 7 porque lo probé. Por lo tanto, también puede funcionar en otras versiones de Android.