Android 呼叫系統相機拍照的返回結果
1.開啟相機的Intent Action: MediaStore.ACTION_IMAGE_CAPTURE,下面為它的註釋:
/** * Standard Intent action that can be sent to have the camera application * capture an image and return it. * <p> * The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. * If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap * object in the extra field. This is useful for applications that only need a small image. * If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri * value of EXTRA_OUTPUT. * As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this uri can also be supplied through * {@link android.content.Intent#setClipData(ClipData)}. If using this approach, you still must * supply the uri through the EXTRA_OUTPUT field for compatibility with old applications. * If you don't set a ClipData, it will be copied there for you when calling * {@link Context#startActivity(Intent)}. * * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} and above * and declares as using the {@link android.Manifest.permission#CAMERA} permission which * is not granted, then atempting to use this action will result in a {@link * java.lang.SecurityException}. * * @see #EXTRA_OUTPUT */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public final static String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
從註釋可以知道,該Action會開啟照相機拍照然後返回結果,如果在沒有設定額外的控制圖片儲存路徑的引數MediaStore.EXTRA_OUTPUT情況下,返回的結果將是一個小的Bitmap,這僅僅只適合於應用程式需要一張小的圖片的時候;如果設定了MediaStore.EXTRA_OUTPUT,那麼將儲存整個大小的到指定的Uri中。
沒有設定MediaStore.EXTRA_OUTPUT的情況下:
從(Bitmap) extras.get("data")直接就可以獲取到返回的圖片,但這種圖片小且質量很差,下面為測試的返回結果:public void onTakePhotoClick(View view) { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bundle extras = data.getExtras(); mImageBitmap = (Bitmap) extras.get("data"); mThumbView.setImageBitmap(mImageBitmap); } }
設定MediaStore.EXTRA_OUTPUT的情況下,需要新增
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/mnt/sdcard/DCIM/Album/1.jpg")));
附加:/mnt/sdcard/DCIM/Album/1.jpg為圖片的儲存地址。
2.將圖片新增到相簿中
這樣拍的照片並不會出現在系統的相簿中,但經過一些測試,有些手機關機重啟之後,相簿中會出現這些照片,原因是重啟之後系統掃描了資料夾,將圖片新增到了多媒體資料庫中。下面為將圖片新增到多媒體資料中的方法:
2.1通過傳送廣播給系統將檔案新增到多媒體資料庫中:
/*
* Request the media scanner to scan a file and add it to the media database.
*/
private void scanFile() {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(new File("/mnt/sdcard/DCIM/Album/1.jpg")));
sendBroadcast(intent);
}
這段程式碼會啟動一個叫MediaScannerBroadcast廣播,但該廣播並不會去掃描檔案,是交給一個叫MediaScannerService服務去完成的,另外上面的Uri也可以換成資料夾的路徑。2.2手動將圖片插入到媒體資料中:
Bitmap bm = BitmapFactory.decodeFile("/mnt/sdcard/DCIM/Album/1.jpg");
String stringUrl = MediaStore.Images.Media.insertImage(getContentResolver(), bm, "", "");
下面為insertImage(ContentResolver cr, String imagePath,String name, String description)的原始碼:
<span style="font-size:18px;"> /**
* 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;
}</span>
從原始碼可以知道,其實是通過多媒體的內容提供者將圖片插入到了資料庫中,另外將圖片插入到多媒體資料庫中之後,我們需要獲取圖片,通過返回結果stringUrl 可以知道,它就是圖片儲存在媒體資料庫中的路徑,因此:String path = getPath(Uri.parse(stringUrl), "date_added desc limit 1");
/**
* 獲得媒體資料庫中圖片的路徑
*/
private String getPath(Uri uri, String sortOrder) {
String path = null;
Cursor cursor = getContentResolver().query(uri, null, null, null, sortOrder);
if (cursor != null) {
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA));
}
}
cursor.close();
}
return path;
}
OK,從上面解決了系統圖庫不顯示應用程式拍照的圖片得問題。
附加:系統相簿的儲存路徑為資料夾"/mnt/sdcard/DCIM/Camera"下,如果拍照之後,系統圖庫不顯示拍的照片,可以將圖片儲存的路徑改為資料夾"/mnt/sdcard/DCIM/Camera"下,經過測試,一定會顯示到系統圖庫中。