У меня есть приложение с галереей изображений, и я хочу, чтобы пользователь мог сохранить его в своей галерее. Я создал меню опций с одним голосом «сохранить», чтобы разрешить это, но проблема в том ... как я могу сохранить изображение в галерее?
это мой код:
@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");
правильно ли сохранять в галерею? к сожалению код не работает :(
android
imageview
gallery
save-image
Кристиан Джуппони
источник
источник
Ответы:
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; } } }
источник
.git
в конце)Собственно, вы можете сохранить свою картинку в любом месте. Если вы хотите сохранить в публичном месте, чтобы любое другое приложение могло получить доступ, используйте этот код:
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.
источник
Environment.getExternalStoragePublicDirectory
иIntent.ACTION_MEDIA_SCANNER_SCAN_FILE
устарели сейчас ...Я много чего пробовал, чтобы это работало на Marshmallow и Lollipop. Наконец, я переместил сохраненное изображение в папку DCIM (новое приложение Google Photo сканирует изображения, только если они явно находятся внутри этой папки)
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_DCIM)
сделал трюк для меня. Благодарность!getExternalStoragePublicDirectory()
теперь устарела для API 29. Необходимо использоватьСогласно этому курсу , правильный способ сделать это:
Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES )
Это даст вам корневой путь к каталогу галереи.
источник
Environment.getExternalStoragePublicDirectory
уже устарел ...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);
источник
Я прихожу сюда с такими же сомнениями, но для 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); }
и это решило мою проблему, Thx Sigrist. Я поместил это здесь, потому что я не нашел ответа об этом для Xamarin, и я надеюсь, что это может помочь другим людям.
источник
В моем случае приведенные выше решения не сработали, мне пришлось сделать следующее:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f)));
источник
ContentProvider
предпочтительнее решениеString filePath="/storage/emulated/0/DCIM"+app_name; File dir=new File(filePath); if(!dir.exists()){ dir.mkdir(); }
Этот код находится в методе onCreate. Этот код предназначен для создания каталога app_name. Теперь к этому каталогу можно получить доступ с помощью приложения файлового менеджера по умолчанию в android. Используйте эту строку filePath везде, где требуется, чтобы указать папку назначения. Я уверен, что этот метод работает и на Android 7, потому что я тестировал его, поэтому он может работать и на других версиях Android.
источник