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);
前面的代码会将图片添加到图库的末尾。如果您想修改日期以使其出现在开头或任何其他元数据中,请参阅下面的代码(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;
}
}
}
这可以保存图像,但可以保存到图库的尽头,但是当您使用相机拍摄照片时,它会保存在顶部。我如何将图像保存到图库顶部? – 2012-06-12 16:23:37
人们应该总是解释他们为什么downvote – sfratini 2012-07-29 18:02:52
请注意,您还必须将
据this course,要做到这一点,正确的做法是:
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
)
thios会给你的根路径为画廊目录
我试过这个新的代码,但它崩溃了 java.lang.NoSuchFieldError:android.os.Environment.DIRECTORY_PICTURES – 2011-12-19 13:11:39
@Christian:此代码只适用于android> = 2.2 – 2011-12-19 13:13:27
好的谢谢,所以没有办法将图像放在android 2012-01-03 17:49:09
其实,你可以保存你的照片在任何地方。如果你想在一个公共空间来保存,所以任何其他应用程序可以访问,使用此代码:
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
这是一个很好的简单解决方案因为我们不需要改变整个实现,我们可以为应用程序创建一个自定义文件夹。 – 2015-10-07 12:48:03
当您只能扫描文件时,发送广播可能会浪费资源:http://*.com/a/5814533/43051。 – 2016-02-03 07:19:04
这是最好的解决方案,谢谢先生! – 2017-02-13 16:44:11
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);
}
为我完美工作。 – KNU 2013-12-12 20:41:24
我已经尝试了很多东西,让在棉花糖和棒棒糖这项工作。 最后我结束了保存的图像移动到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 site too。
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给用户的权限在此文件夹可能不存在。
感谢有关Google相册的信息。 – 2016-02-03 07:06:41
这是唯一的解决方案。 没有人提到该文件必须在DCIM文件夹中。 谢谢!!! – 2016-06-28 21:19:18
'Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)'为我做了诡计。谢谢! – saltandpepper 2017-11-17 11:51:06
我来到这里同样毋庸置疑的,但对于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的这个answare,我希望它可以帮助其他人。
在我的情况下,上述的解决方案没有工作,我必须做到以下几点:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f)));
其真的很了解这个选项,但不幸的是不适用于一些使用android 6的设备,所以'ContentProvider'更好的解决方案 – user5599807 2017-04-19 21:03:28
String filePath="/storage/emulated/0/DCIM"+app_name;
File dir=new File(filePath);
if(!dir.exists()){
dir.mkdir();
}
此代码是的onCreate method.This代码是用于创建APP_NAME的目录。 现在,可以使用android中的默认文件管理器应用程序访问此目录。 使用此字符串filePath来设置您的目标文件夹。 我相信这种方法也适用于Android 7,因为我测试过它。因此,它也可以在其他版本的Android上工作。
您可以在相机文件夹内创建一个目录并保存。一旦你完成扫描。它会立即在画廊中展示你的形象。干杯!!
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);
你解决了这个问题吗?可以请你与我分享 – user3233280 2014-02-22 09:53:05
我也有同样的问题http://*.com/questions/21951558/failed-to-save-image-from-app-assets-folder-to-gallery-folder-in-android/21951643?noredirect = 1#21951643 – user3233280 2014-02-22 09:54:25
对于那些仍然有问题保存文件,这可能是因为你的url包含非法字符,如“?”,“:”和“ - ”删除这些,它应该工作。这是外国设备和android模拟器中的常见错误。在这里看到更多关于它:http://*.com/questions/11394616/java-io-ioexception-open-failed-einval-invalid-argument-when-saving-a-image – ChallengeAccepted 2014-11-25 21:58:50