這節課會介紹如何利用現有的camera程式來拍一張照片。
假設你想通過你的用戶端程式實作一個聚合全球天氣的地圖,上面會有各地的目前天氣圖檔。那麼集合圖檔隻是你程式的一部分。你想要最簡單的動作來擷取圖檔,而不是重新發明(reinvent)一個camera。幸運的是,大多數Android裝置都已經至少安裝了一款相機程式。在這節課中,你會學習,如何拍照。[暈,說了這麼多的話做引子,下次遇到這樣的“廢話”真的不想翻譯了]
Request Camera Permission [請求相機權限]
在寫程式之前,需要在你的程式的manifest檔案中添加下面的權限:
<manifest ... >
<uses-feature android:name="android.hardware.camera" />
...
</manifest ... >
如果你的程式并不需要一定有Camera,可以添加
android:required="false"
的tag屬性。這樣的話,Google Play 也會允許沒有camera的裝置下載下傳這個程式。當然你有必要在使用Camera之前通過
hasSystemFeature(PackageManager.FEATURE_CAMERA)
方法來檢查裝置上是否有Camera。如果沒有,你應該關閉你的Camera相關的功能! [這個幾乎沒有人去做檢查,因為目前所有的智能手機都會有相機]
Take a Photo with the Camera App [使用相機程式拍照]
Android中的方法是:啟動一個Intent來完成你想要的動作。這個步驟包含三部分:
Intent
本身,啟動的外部
Activity
, 與一些處理傳回照片的代碼。如:
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, actionCode);
}
當然在發出Intent之前,你需要檢查是否有app會來handle這個intent,否則會引起啟動失敗:
public static boolean isIntentAvailable(Context context, String action) {
final PackageManager packageManager = context.getPackageManager();
final Intent intent = new Intent(action);
List<ResolveInfo> list =
packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
View the Photo [檢視照片]
Android的Camera程式會把拍好的照片編碼為bitmap,使用extra value的方式添加到傳回的
Intent
當中, 對應的key為data。
private void handleSmallCameraPhoto(Intent intent) {
Bundle extras = intent.getExtras();
mImageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(mImageBitmap);
}
Note: 這僅僅是處理一張很少的縮略圖而已,如果是大的全圖,需要做更多的事情來避免ANR。
Save the Photo [儲存照片]
如果你提供一個file對象給Android的Camera程式,它會儲存這張全圖到給定的路徑下。你必須提供存儲的卷名,檔案夾名與檔案名。對于2.2以上的系統,如下操作即可:
storageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
),
getAlbumName()
);
- Set the file name [設定檔案名]
正如上面描述的那樣,檔案的路徑會有裝置的系統環境決定。你自己需要做的隻是定義個不會引起檔案名沖突的命名scheme。下面會示範一種解決方案:
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp =
new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
File image = File.createTempFile(
imageFileName,
JPEG_FILE_SUFFIX,
getAlbumDir()
);
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
- Append the file name onto the Intent [把檔案名添加到網絡上]
Once you have a place to save your image, pass that location to the camera application via the
Intent
.
File f = createImageFile();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
Add the Photo to a Gallery [添加照片到相冊]
對于大多數人來說,最簡單檢視你的照片的方式是通過系統的Media Provider。下面會示範如何觸發系統的Media Scanner來添加你的照片到Media Provider的DB中,這樣使得相冊程式與其他程式能夠讀取到那些圖檔。
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
Decode a Scaled Image [解碼縮放圖檔]
在有限的記憶體下,管理全尺寸的圖檔會很麻煩。下面會介紹如何縮放圖檔來适應程式的顯示:
private void setPic() {
// Get the dimensions of the View
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
mImageView.setImageBitmap(bitmap);
}
學習自:http://developer.android.com/training/camera/photobasics.html,歡迎一起交流!
轉載請注明出自:http://blog.csdn.net/kesenhoo,謝謝!