保存图片到系统图库是个很常见的功能,今天第一次做的时候,遇到了一些问题,就是保存到了图库之后,在部分机型上无法立即显示,原因就是图库数据没有更新。百度了一下,发现这个问题还是很常见的,网上也有不少的解决办法。
在参考了:http://blog.csdn.net/xu_fu/article/details/39158747,这篇文章之后总算是实现了。而在文章最后,作者提到了系统截图功能的源码,里面同样有保存到图片的系统图库的功能,作者贴出了相关源码,于是尝试着以该源码的解决思路来实现保存图片的系统图库的功能,事实证明,该方法确实能很好的解决图库数据更新的问题,下面做一下记录,方便学习和交流。
首先贴出系统截图功能中保存图片到图库的部分源码:
Context context = params[0].context;
Bitmap image = params[0].image;
Resources r = context.getResources();
try {
// Create screenshot directory if it doesn't exist
mScreenshotDir.mkdirs();
// media provider uses seconds for DATE_MODIFIED and DATE_ADDED, but milliseconds
// for DATE_TAKEN
long dateSeconds = mImageTime / 1000;
// Save the screenshot to the MediaStore
ContentValues values = new ContentValues();
ContentResolver resolver = context.getContentResolver();
values.put(MediaStore.Images.ImageColumns.DATA, mImageFilePath);
values.put(MediaStore.Images.ImageColumns.TITLE, mImageFileName);
values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, mImageFileName);
values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, mImageTime);
values.put(MediaStore.Images.ImageColumns.DATE_ADDED, dateSeconds);
values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, dateSeconds);
values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");
values.put(MediaStore.Images.ImageColumns.WIDTH, mImageWidth);
values.put(MediaStore.Images.ImageColumns.HEIGHT, mImageHeight);
Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
OutputStream out = resolver.openOutputStream(uri);
image.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
// update file size in the database
values.clear();
values.put(MediaStore.Images.ImageColumns.SIZE, new File(mImageFilePath).length());
resolver.update(uri, values, null, null);
} catch (Exception e) {
}
布局文件什么的就不说了,这里就是一个ImageView,然后设置一张图片就行了。
从上面的部分源码中可以看到,在保存图片的时候,参数是Bitmap 对象,而我这里保存ImageView中显示的图片到系统图库,在XML中直接设置的时候是一个Drawable 对象,这里就需要进行一下转化,这里的代码是:
<pre name="code" class="java"> BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
<span style="white-space:pre"> </span>Bitamp bmp = drawable.getBitmap();
更多有关Drawable 和 Bitmap之间的转换,请参考这里:http://blog.csdn.net/june5253/article/details/7826597。
其他的不多说了,主要看看实现保存图片到系统图库的方法,请看下面的代码:
<pre name="code" class="java">private void saveImageToGallery(Context context, Bitmap bitmap) {
// Create screenshot directory if it doesn't exist
String dirName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + "MImages";
File fileDir = new File(dirName);
if (!fileDir.exists()) {
fileDir.mkdir();
}
long mImageTime = System.currentTimeMillis();//取当前系统时间
// media provider uses seconds for DATE_MODIFIED and DATE_ADDED, but milliseconds
// for DATE_TAKEN
long dateSeconds = mImageTime / 1000;
String mImageFileName = dateSeconds + ".png"; //以保存时间命名
String mImageFilePath = dirName + File.separator + mImageFileName; //注意这里的mImageFilePath是: 目录名称+文件名
int mImageWidth = bitmap.getWidth();
int mImageHeight = bitmap.getHeight();
// Save the screenshot to the MediaStore
ContentValues values = new ContentValues();
ContentResolver resolver = context.getContentResolver();
values.put(MediaStore.Images.ImageColumns.DATA, mImageFilePath);
values.put(MediaStore.Images.ImageColumns.TITLE, mImageFileName);
values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, mImageFileName);
values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, mImageTime);
values.put(MediaStore.Images.ImageColumns.DATE_ADDED, dateSeconds);
values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, dateSeconds);
values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");
values.put(MediaStore.Images.ImageColumns.WIDTH, mImageWidth);
values.put(MediaStore.Images.ImageColumns.HEIGHT, mImageHeight);
Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
try {
OutputStream out = resolver.openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// update file size in the database
values.clear();
values.put(MediaStore.Images.ImageColumns.SIZE, new File(mImageFilePath).length());
resolver.update(uri, values, null, null);
}
需要说明和注意的地方,已经用中文进行了注释,这样就OK了,在上面这段代码执行后,就可以在系统的DCIM目录下,生成一个MImages目录,保存的图片就在该目录下,同时可以在系统图库应用中看到名为MImages的相册,就跟系统截图的Screenshots相册一样。