1津肛、前言
我們都知道將圖片保存到本地的操作,但是如何將本地的圖片保存到相冊比肄。有幾種不同的方法快耿,下面分別講述這幾種方法。
2芳绩、調用系統方法
MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "title", "description");
MediaStore.Images.Media.insertImage(getContentResolver(), imgPath, "name", "description");
上面兩種方法是調用了系統的方法掀亥,將圖片的bitmap對象或者圖片的路徑作為參數傳遞,但是僅僅是這樣調用還是不能在相冊中看到圖片妥色。
我們還需要更新圖片庫搪花,使用下面的方法可以更新圖片庫:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(imgPath))););
上面的方法是掃描圖片路徑并將該圖片顯示到相冊中。
可以說上面的方法以及能夠滿足大部分手機的顯示圖片的需求嘹害,但是在另外一些手機撮竿,比如華為、OPPO笔呀,就存在兼容性問題幢踏。它會將圖片顯示在相冊的最前面。所以當手機相冊很多時许师,我們會產生這張圖片沒有被插入到相冊的錯覺房蝉。
那為什么會發(fā)生上面的情況呢?首先我們查看一下被插入的圖片的詳情:
可以看到圖片被插入到了最前面(圖片下標為1/304)微渠,再看圖片詳情搭幻,時間居然是1970/1/1 08:00:00,我們知道相冊中的圖片都是按照時間的順序升序的逞盆,所以怪不得圖片會被插入到最前面檀蹋。
3、原因及解決辦法
下面我們再來看為什么時間會是1970/1/1 08:00:00云芦。這個我們從源碼中入手找原因俯逾,直接進入MediaStore.Images.Media.insertImage()方法:
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);
...省略
} catch(Exception e) {
e.printstack();
}
...省略
}
通過上面的源碼可知贸桶,圖片是通過contentProvider插入的,調用的是ContentResolver的insert方法纱昧,其中第二個參數是ContentValues對象刨啸,它包含了圖片的信息。比如上面就僅僅包含了圖片的標題识脆、描述、圖片類型善已。我們看到上面僅僅put進去了三個鍵值對灼捂,而每一個key都是MediaColumns接口的常量,我們再來看一下還有哪些常量换团,對于圖片來說悉稠,可以看到還有DATE_TAKEN這個常量,再來看一下它的注釋:
/**
* The date & time that the image was taken in units
* of milliseconds since jan 1, 1970.
* <P>Type: INTEGER</P>
*/
public static final String DATE_TAKEN = "datetaken";
這個參數表示我們的圖片是什么時候拍攝的艘包,這個時間是以毫秒為單位的的猛,并且時間基點是1970年1月1日,這個時間看起來是不是很熟悉想虎,我們上面那張圖片詳情的時間也是1970年1月1日卦尊。
那么我們是不是可以認為調用MediaStore.Images.Media.insertImage()方法時,默認將時間設置為1970年1月1日舌厨,因此會將圖片顯示在相冊的最前面岂却。
知道了原因了之后,那么我們就仿照MediaStore.Images.Media.insertImage()自己寫一個方法進行圖片的插入裙椭,并且將圖片的拍攝時間寫進去,不就可以解決那個問題了嗎?具體的方法如下所示:
public static final String PIC_DIR_NAME = "myPhotos"; //在系統的圖片文件夾下創(chuàng)建了一個相冊文件夾未巫,名為“myPhotos"约急,所有的圖片都保存在該文件夾下。
private File mPicDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), PIC_DIR_NAME); //圖片統一保存在系統的圖片文件夾中
OutputStream out = null;
try {
mPicDir.mkdirs();
String mPicPath = new File(mPicDir, fileName).getAbsolutePath();
ContentValues values = new ContentValues();
ContentResolver resolver = mContext.getContentResolver();
values.put(MediaStore.Images.ImageColumns.DATA, mPicPath);
values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, fileName);
values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/jpg");
//將圖片的拍攝時間設置為當前的時間
values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, System.currentTimeMillis() + "");
Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (uri != null) {
out = resolver.openOutputStream(uri);
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
if (mContext instanceof Activity) {
Activity activity = (Activity) mContext;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
MuToast.showSuccessMsg(mContext, "保存成功");
Toast.makeText(mContext, "已保存在" + fileDir + "文件夾中", Toast.LENGTH_SHORT).show();
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用了上面的方法后炊汤,圖片可以成功地保存在系統相冊中正驻,并且能夠正確顯示在相冊的最后面。而且我們還創(chuàng)建了一個屬于我們自己的相冊文件夾”myPhotos"婿崭,我們可以將自己的應用的所有圖片都保存在自己相冊文件夾中拨拓。