本文主要介紹保存圖片到相冊(cè)的幾種方式儒陨。其本質(zhì)上并沒有把圖片保存到相冊(cè)中,實(shí)際上是保存在SD卡下自定義的文件夾中,目的只是讓QQ
和微信
在選擇照片的時(shí)候立刻顯示分冈,注:其實(shí)QQ
和微信
也是這樣做的胁镐。
方式1-掃描文件通知相冊(cè)更新
// 通知相冊(cè)更新
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
context.sendBroadcast(intent);
方式1-錯(cuò)誤操作
MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), "name", "description");
// 通知相冊(cè)更新
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
context.sendBroadcast(intent);
對(duì)比 方式1 和 錯(cuò)誤方式 偎血,我們可以發(fā)現(xiàn)其實(shí)就是多了一行insertImage
的代碼,然后就不能被QQ
和微信
立刻識(shí)別了盯漂,好傷心~~
這里我稍微研究了一下颇玷,然而沒有發(fā)現(xiàn)本質(zhì)原因,不過做了以下猜測(cè)就缆,有興趣的可以自行研究源碼帖渠。
因?yàn)樵谑褂?code>ACTION_MEDIA_SCANNER_SCAN_FILE方式通知相冊(cè)更新時(shí),也需要執(zhí)行類似insertImage
方法內(nèi)部的某些操作竭宰,可能和ContentProvider
相關(guān)的數(shù)據(jù)庫(kù)有關(guān)空郊,所以如果你先執(zhí)行了insertImage
方法,那么它在接收到這個(gè)ACTION_MEDIA_SCANNER_SCAN_FILE
廣播的時(shí)候切揭,做了如下判斷:如果已經(jīng)執(zhí)行了insertImage
方法狞甚,那么return;
,所以不會(huì)執(zhí)行再通知相冊(cè)更新
了伴箩。
方式2-完整操作
// 插入file數(shù)據(jù)到相冊(cè)
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);
// 通知相冊(cè)更新
context.sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", uri));
方式2-簡(jiǎn)單操作
// 插入file數(shù)據(jù)到相冊(cè)
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);
// 通知相冊(cè)更新
context.sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", uri));
總結(jié)
對(duì)于Google
和百度
出來的Android保存圖片到相冊(cè)
表示無奈入愧,90%以上都是一樣的,這個(gè)時(shí)候如果我們還是依靠搜索
嗤谚,消耗的成本是很大的棺蛛,如果你能夠從源碼
入手,可能就會(huì)給你提供一些思路巩步,例如:上述所說的方式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;
}