Android Camera

Android框架包含瞭對各種Camera以及其上可用的Camera功能的支持,它允許你在應用程序中抓拍照片和視頻。本文討論快速而簡單的拍攝照片和視頻的方法,並概要的介紹一個讓用戶創建定制Camera體驗的高級方法。

註意事項

在開啟應用程序使用Android設備上的Camera功能之前,要考慮一些打算如何使用這些硬件功能的問題:

1.  Camera需求:要考慮應用程序是否必須要運行在有Camera的設備上,如果必須,就要在應用程序的清單中聲明Camera需求;

2.  快照或定制Camera:應用程序準備如何使用Camera?是隻對抓拍或視頻剪輯感興趣?還是要應用程序提供使用Camera的新方法?對於抓拍或剪輯,要考慮使用既存的Camera應用程序。對於開發定制化的Camera功能,請看下文的“構建Camera應用程序”

3.  存儲:圖片或視頻是隻打算讓本應用程序可見,還是要共享給其他應用程序使用,如相冊或其他媒體和社區應用程序?是否想要這些圖片和視頻在應用被卸載後還可用?請看下文的“保存媒體文件”是如何解決這些問題的。

基礎

Android框架通過Camera API或Camera Intent來支持拍照和錄像,以下是相關的類:

Camera

    這個類是控制設備Camera的主API。在構建一個Camera應用程序時,它被用於拍照或錄像。

SurfaceView

    這個類用於向用戶實時的展現Camera的預覽。

MediaRecorder

    這個類用於記錄來自Camera的視頻

Intent

    MediaStore.ACTION_IMAGE_CAPTURE或MediaStore.ACTION_VIDEO_CAPTURE類型的Intent動作被用於不直接使用Camera對象來拍照或錄像。

清單聲明

在開始使用Camera API開發應用程序之前,要確保清單文件已經有瞭適當的聲明,以允許使用Camera硬件和其他相關的功能。

1.  Camera權限:應用程序必須申請使用設備Camera的權限。

<uses-permissionandroid:name="android.permission.CAMERA"/>

註意:如果通過Intent來使用Camera,應用程序就不需要申請這個權限。

2.  Camera功能:應用程序還必須要聲明打算使用的Camera功能,例如:

<uses-featureandroid:name="android.hardware.camera"/>

把Camera功能添加到應用程序的清單中,會讓Google Play防止把程序安裝到不包含Camera或不支持你所需要的Camera功能的設備上。關於如何使用基於功能過濾的Google Play,請看Google Play和基於功能的過濾

如果應用程序能夠使用Camera或正確的操作Camera功能,但卻不需要它,那麼就應該在清單中指定android:required屬性,並把屬性值設置為false:

<uses-feature android:name="android.hardware.camera" android:required="false" />3.  存儲權限:如果應用程序要把圖片或視頻保存到設備的外部存儲器上(如SD卡),就必須在清單中指定這個權限:

<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>4.  音頻錄音權限:對於視頻采集的音頻錄音,應用程序必須要申請音頻采集權限:

<uses-permissionandroid:name="android.permission.RECORD_AUDIO"/>5.  位置定位權限:如果應用程序要給圖片標記GPS位置信息,就必須申請位置定位權限:

<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>

關於獲得用戶位置的更多信息,請看“定位策略”

使用既存的Camera應用

在應用程序中不需要太多的額外代碼就可以快速的開啟拍照或錄像的方法是:使用Intent來調用一個既存的Android Camera應用程序。一個Camera Intent能夠通過既存的Camera應用程序和它返回給應用程序的播放控制來申請采集一張照片或一段視頻。本節會向你展示如何使用這項技術來采集一張圖片或一段視頻。

調用Camera Intent的過程會遵循以下這些大概的步驟:

1.  編寫一個Camera Intent:創建一個申請圖片或視頻的Intent對象,使用以下Intent類型之一:

MediaStore.ACTION_IMAGE_CAPTURE:從一個既存的Camera應用中申請圖片功能的Intent動作類型;

MediaStore.ACTION_VIDEO_CAPTURE:從一個既存的Camera應用中申請視頻功能的Intent動作類型。

2.  啟動Camera的Intent:使用startActivityForResult()方法來執行Camera的Intent。Intent啟動後,該Camera應用程序的用戶界面會顯示在屏幕上,並且用戶能夠拍照或錄像;

3.  接收Intent的結果:在你的應用程序中建立一個onActivityResult()方法來接收來自Camera Intent的回調和數據。當用戶完成成拍照或錄像(或者是取消操作),系統會調用這個方法。

圖像采集Intent

使用Camera Intent來采集圖像是你的應用程序用最少的代碼來拍照的快捷方式。一個圖片采集Intent能夠包含以下額外的信息:

MediaStore.EXTRA_OUTPUT:這個設置需要一個指定瞭保存圖片路徑和文件名的Uri對象。這個設置是可選,但強烈推薦使用。如果不指定這個值,Camera應用程序會用默認的名稱把采集到的圖片保存到默認的位置,這些默認值在Intent.getData()方法的返回字段中指定。

以下示例演示瞭如何構建一個圖片采集Intent,並執行它。示例中GetOutputMediaFileUri()方法引用瞭下面“保存媒體文件”一節中的示例代碼:

private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;

private Uri fileUri;

 

@Override

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

 

    // create Intent to take a picture and return control to the calling application

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

 

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image

    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

 

    // start the image capture Intent

    startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

}

startActivityResult()方法執行完成後,用戶就會看到Camera應用程序的界面。用戶完成拍照(或取消操作)之後,用戶界面就會返回到你的應用程序中,並且你必須監聽onActivityResult()方法來接收Intent的結果,並繼續你的應用程序的執行。

視頻采集Intent

使用Camera Intent采集視頻是讓你的應用程序能夠用最少的代碼來錄像的一中快捷方式。視頻采集Intent能夠包含以下額外信息:

MediaStore.EXTRA_OUTPUT:這個設置要求用一個URI來指定保存視頻的路徑和文件名。雖然它是可選的,但強烈推薦使用這個設置。如果沒有指定這個設置,那麼Camera應用程序會把采集到的視頻用默認的名稱保存到默認的位置,默認的設置是在Intent的Intent.getData()方法域中返回的。

MediaStore.EXTRA_VIDEO_QUALITY:這個值的范圍是0~1,0的時候質量最差且文件最小,1的時候質量最高且文件最大。

MediaStore.EXTRA_DURATION_LIMIT:這個值以秒為單位,顯示視頻采集的時長。

MediaStore.EXTRA_SIZE_LIMIT:這個值以字節為單位,限制視頻采集的文件大小。

下面的示例演示瞭如何構造一個視頻采集的Intent,並執行它。這個例子中的getOutputMediaFileUri()方法引用瞭下文的“保存媒體文件”中的示例代碼:

private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;

private Uri fileUri;

 

@Override

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

 

    //create new Intent

    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

 

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);  // create a file to save the video

    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);  // set the image file name

 

    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high

 

    // start the Video Capture Intent

    startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);

}

當startActivityForResult()方法被執行時,用戶就會看到一個可編輯的Camera應用程序界面。在用戶完成錄像(或取消操作)之後,該用戶界面就會返回到你的應用程序中,並且你必須監聽onActivityResult()方法來接收Intent的結果,並繼續執行你的應用程序。

接收Camera Intent結果

一旦你構建並執行瞭一個圖片或視頻的Camera Intent,那麼就必須要配置你應用程序來接收Intent的結果。本節向你展示瞭如何監聽來自Camera Intent的回調,以便應用程序能夠對采集到的圖片或視頻做進一步的處理。

為瞭接收Intent的結果,必須在啟動Intent的那個Activity中重寫onActivityResult()方法。下面的示例演示瞭如何重寫onActivityResult()方法來采集圖片Camera Intent或視頻Camera Intent的返回結果:

private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;

private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;

 

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {

        if (resultCode == RESULT_OK) {

            // Image captured and saved to fileUri specified in the Intent

            Toast.makeText(this, "Image saved to:\n" +

                     data.getData(), Toast.LENGTH_LONG).show();

        } else if (resultCode == RESULT_CANCELED) {

            // User cancelled the image capture

        } else {

            // Image capture failed, advise user

        }

    }

 

    if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {

        if (resultCode == RESULT_OK) {

            // Video captured and saved to fileUri specified in the Intent

            Toast.makeText(this, "Video saved to:\n" +

                     data.getData(), Toast.LENGTH_LONG).show();

        } else if (resultCode == RESULT_CANCELED) {

            // User cancelled the video capture

        } else {

            // Video capture failed, advise user

        }

    }

}

一旦Activity接收到一個成功的結果,那麼你的應用程序就可以訪問指定位置中的被采集的圖片或視頻。
 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。