保存图片到相册

96
风清袖一
0.1 2017.03.03 21:23* 字数 441

本文主要介绍保存图片到相册的几种方式。其本质上并没有把图片保存到相册中,实际上是保存在SD卡下自定义的文件夹中,目的只是让QQ微信在选择照片的时候立刻显示,注:其实QQ微信也是这样做的。

方式1-扫描文件通知相册更新

// 通知相册更新
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
context.sendBroadcast(intent);

方式1-错误操作

MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), "name", "description");

// 通知相册更新
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
context.sendBroadcast(intent);

对比 方式1 和 错误方式 ,我们可以发现其实就是多了一行insertImage的代码,然后就不能被QQ微信立刻识别了,好伤心~~

这里我稍微研究了一下,然而没有发现本质原因,不过做了以下猜测,有兴趣的可以自行研究源码。

因为在使用ACTION_MEDIA_SCANNER_SCAN_FILE方式通知相册更新时,也需要执行类似insertImage方法内部的某些操作,可能和ContentProvider相关的数据库有关,所以如果你先执行了insertImage方法,那么它在接收到这个ACTION_MEDIA_SCANNER_SCAN_FILE广播的时候,做了如下判断:如果已经执行了insertImage方法,那么return;,所以不会执行再通知相册更新了。

方式2-完整操作

// 插入file数据到相册
ContentValues values = new ContentValues(9);
values.put(MediaStore.Images.Media.TITLE, "Camera");
values.put(MediaStore.Images.Media.DISPLAY_NAME, filename);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.ORIENTATION, 0);
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
values.put(MediaStore.Images.Media.SIZE, file.length());
Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
// 通知相册更新
context.sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", uri));

方式2-简单操作

// 插入file数据到相册
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
// 通知相册更新
context.sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", uri));

总结

对于Google百度出来的Android保存图片到相册表示无奈,90%以上都是一样的,这个时候如果我们还是依靠搜索,消耗的成本是很大的,如果你能够从源码入手,可能就会给你提供一些思路,例如:上述所说的方式2就是从insertImage方法中得出的,源码如下:

/**
 * Insert an image and create a thumbnail for it.
 *
 * @param cr The content resolver to use
 * @param source The stream to use for the image
 * @param title The name of the image
 * @param description The description of the image
 * @return The URL to the newly created image, or <code>null</code> if the image failed to be stored
 *              for any reason.
 */
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.DESCRIPTION, description);
    values.put(Images.Media.MIME_TYPE, "image/jpeg");

    Uri url = null;
    String stringUrl = null;    /* value to be returned */

    try {
        url = cr.insert(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.
            Bitmap microThumb = StoreThumbnail(cr, miniThumb, id, 50F, 50F,
                    Images.Thumbnails.MICRO_KIND);
        } else {
            Log.e(TAG, "Failed to create thumbnail, removing original");
            cr.delete(url, null, null);
            url = null;
        }
    } catch (Exception e) {
        Log.e(TAG, "Failed to insert image", e);
        if (url != null) {
            cr.delete(url, null, null);
            url = null;
        }
    }

    if (url != null) {
        stringUrl = url.toString();
    }

    return stringUrl;
}
Android