андроид - сохранить изображение в галерею
у меня есть приложение с галереей изображений, и я хочу, чтобы пользователь мог сохранить его в своей собственной галерее.
Я создал меню опций с одним голосом "сохранить", чтобы разрешить это, но проблема в том...как я могу сохранить изображение в галерею?
Это мой код:
@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");
правильно ли сохранить в галерее?
к сожалению, код не работает :(
9 ответов:
MediaStore.Images.Media.insertImage(getContentResolver(), yourBitmap, yourTitle , yourDescription);прежний код добавит изображение в конце галереи. Если вы хотите изменить дату так, чтобы она отображалась в начале или в любых других метаданных, см. код ниже (Cortesy of S-K, 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
Я пробовал много вещей, чтобы позволить этой работе на зефир и леденец. Наконец, я закончил тем, что переместил сохраненное изображение в папку DCIM (новые изображения сканирования Google Photo app, только если они находятся внутри этой папки, по-видимому)
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 тоже.
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 )thios даст вам корневой путь для каталога галерея.
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); }
Я пришел сюда с тем же сомнением, но для Xamarin для Android, я использовал ответ 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); }и это решило мою проблему, спасибо Зигрист. Я поставил его здесь, потому что я не нашел answare об этом для Xamarin, и я надеюсь, что это может помочь другим людям.
в моем случае решения выше не работали я должен был сделать следующее:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f)));
вы можете создать каталог внутри папки камеры и сохранить. И сканирование после завершения. Он мгновенно покажет ваше изображение в галерее. Ура!!
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(); }этот код находится в методе onCreate.Этот код предназначен для создания каталога app_name. Теперь к этому каталогу можно получить доступ с помощью приложения file manager по умолчанию в android. Используйте эту строку filePath везде, где требуется, чтобы установить папку назначения. Я уверен, что этот метод работает и на Android 7, потому что я тестировал его.Следовательно,он может работать и на других версиях Android.
Comments