不少應用程序均可能會使用到調用攝像頭拍照的功能,好比說程序裏須要上傳一張圖片 做爲用戶的頭像,這時打開攝像頭拍張照是最簡單快捷的。下面就讓咱們經過一個例子來學 習一下,如何才能在應用程序裏調用手機的攝像頭進行拍照。android
新建一個 ChoosePicTest 項目,而後修改 activity_main.xml 中的代碼,以下所示:ide
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"佈局
android:orientation="vertical" >code
<Button android:id="@+id/take_photo" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Take Photo" />xml
<ImageView android:id="@+id/picture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" />對象
</LinearLayout>blog
能夠看到,佈局文件中只有兩個控件,一個 Button 和一個 ImageView。Button 是用於打 開攝像頭進行拍照的,而 ImageView 則是用於將拍到的圖片顯示出來。事件
而後開始編寫調用攝像頭的具體邏輯,修改 MainActivity 中的代碼,以下所示:圖片
public class MainActivity extends Activity { public static final int TAKE_PHOTO = 1; public static final int CROP_PHOTO = 2; private Button takePhoto;get
private ImageView picture;
private Uri imageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
takePhoto = (Button) findViewById(R.id.take_photo);
picture = (ImageView) findViewById(R.id.picture);takePhoto.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 建立File對象,用於存儲拍照後的圖片
File outputImage = new File(Environment. getExternalStorageDirectory(), "tempImage.jpg");
try {
if (outputImage.exists()) {
outputImage.delete();
}
outputImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
imageUri = Uri.fromFile(outputImage);
Intent intent = new Intent("android.media.action. IMAGE_CAPTURE"); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent, TAKE_PHOTO); // 啓動相機程序
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case TAKE_PHOTO:
if (resultCode == RESULT_OK) {
Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(imageUri, "image/*"); intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, CROP_PHOTO); // 啓動裁剪程序
}
break;
case CROP_PHOTO:
if (resultCode == RESULT_OK) {
try {
Bitmap bitmap = BitmapFactory.decodeStream
(getContentResolver()
.openInputStream(imageUri));
picture.setImageBitmap(bitmap); // 將裁剪後的照片顯示出來
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
default:
break;
}
}
}
上述代碼稍微有點複雜,咱們來仔細地分析一下。在 MainActivity 中要作的第一件事自 然是分別獲取到 Button 和 ImageView 的實例,並給 Button 註冊上點擊事件,而後在 Button 的點擊事件裏開始處理調用攝像頭的邏輯,咱們重點看下這部分代碼。
首先這裏建立了一個 File 對象,用於存儲攝像頭拍下的圖片,這裏咱們把圖片命名爲 output_image.jpg , 並 將 它 存 放 在 手 機 SD 卡 的 根 目 錄 下 , 調 用 Environment 的 getExternalStorageDirectory() 方法獲取到的就是手機 SD 卡的根目錄。而後再調用 Uri 的 fromFile()方法將 File 對象轉換成 Uri 對象,這個 Uri 對象標識着 output_image.jpg 這張圖片 的惟一地址。接着構建出一個 Intent 對象,並將這個 Intent 的 action 指定爲 android.media.action. IMAGE_CAPTURE,再調用 Intent 的 putExtra()方法指定圖片的輸出地址,這裏填入剛剛得 到的 Uri 對象,最後調用 startActivityForResult()來啓動活動。因爲咱們使用的是一個隱式 Intent,系統會找出可以響應這個 Intent 的活動去啓動,這樣照相機程序就會被打開,拍下的 照片將會輸出到 output_image.jpg 中。
注意剛纔咱們是使用 startActivityForResult()來啓動活動的,所以拍完照後會有結果返回 到 onActivityResult()方法中。若是發現拍照成功,則會再次構建出一個 Intent 對象,並把它 的 action 指定爲 com.android.camera.action.CROP。這個 Intent 是用於對拍出的照片進行裁剪的,由於攝像頭拍出的照片都比較大,而咱們可能只但願截取其中的一小部分。而後給這個
Intent 設置上一些必要的屬性,並再次調用 startActivityForResult()來啓動裁剪程序。裁剪後 的照片一樣會輸出到 output_image.jpg 中。
裁剪操做完成以後,程序又會回調到 onActivityResult()方法中,這個時候咱們就能夠調 用 BitmapFactory 的 decodeStream()方法將 output_image.jpg 這張照片解析成 Bitmap 對象,然 後把它設置到 ImageView 中顯示出來。
因爲這個項目涉及到了向 SD 卡中寫數據的操做,所以咱們還須要在 AndroidManifest.xml中聲明權限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.choosepictest"
android:versionCode="1" android:versionName="1.0" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
……
</manifest>
這樣代碼就都編寫完了,如今將程序運行到手機上,而後點擊 Take Photo 按鈕就能夠進 行拍照了,如圖 8.13 所示。
圖 8.13
拍照完成後點擊肯定則能夠對照片進行裁剪,如圖 8.14 所示。
圖 8.14
點擊完成,就會回到咱們程序的界面。同時,裁剪後的照片固然也會顯示出來了,如圖
8.15 所示。
圖 8.15