android – 将图像保存到图库中

我有一个图像库的应用程序,我希望用户可以将其保存到自己的画廊。 我已经创build了一个单一的声音“保存”的选项菜单,以允许,但问题是…如何将图像保存到画廊?

这是我的代码:

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

前面的代码将在图库的末尾添加图像。 如果您想修改date以便它出现在开头或任何其他元数据,请参阅下面的代码(SK, samkirton的Cortesy ):

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#TaskGalleryfind更多信息;

根据这个过程 ,正确的做法是:

 Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES ) 

thios会为您提供图库目录的根path。

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

我已经尝试了很多事情,让这个工作在棉花糖和棒棒糖。 最后,我结束了将保存的图片移动到DCIM文件夹(新的谷歌照片应用程序扫描图像,只有当他们在这个文件夹显然)

 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网站上find扫描文件的标准代码。

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

请记住,该文件夹不能出现在世界上的每个设备中,并且从棉花糖(API 23)开始,您需要向用户请求WRITE_EXTERNAL_STORAGE权限。

在我的情况下,上述解决scheme不起作用,我不得不做以下几点:

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

您可以在相机文件夹内创build一个目录并保存。 一旦你完成扫描。 它会立即在画廊中展示你的形象。 干杯!!

  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。 我把它放在这里,因为我没有findXamarin的这个answare,我希望它可以帮助其他人。

  String filePath="/storage/emulated/0/DCIM"+app_name; File dir=new File(filePath); if(!dir.exists()){ dir.mkdir(); } 

这段代码是在onCreate方法中。这段代码是用来创build一个app_name的目录。 现在,这个目录可以使用Android中的默认文件pipe理器应用程序访问。 根据需要使用此stringfilePath来设置目标文件夹。 我相信这个方法也适用于Android 7,因为我testing了它。因此,它也可以在其他版本的Android上工作。