Android Camera(二)

構建一個Camera應用程序

某些開發可能想要在他們的應用中定制Camera的用戶界面,或者要提供一些特殊的功能。創建定制化的Activity比使用Intent需要更多的代碼,但它能夠給你的戶提供更好的體驗。

以下是創建定制化的Camera界面的一般步驟:

1. 檢查和訪問Camera:創建代碼來檢查Camera和所申請訪問的存在性;

2. 創建一個預覽類:繼承SurfaceView來創建一個Camera的預覽類,並實現SurfaceHolder接口。這個類用來預覽來之Camera的實施圖像。

3. 構建一個預覽佈局:一旦有瞭Camera預覽類,就可以把這個預覽類和你想要的用戶界面控制結合在一起來創建一個視圖佈局。

4. 針對采集建立監聽:把監聽器與響應用戶動作(如按下按鈕)的界面控制連接到一起來啟動圖像或視頻的采集。

5. 采集和保存文件:針對真正采集的圖片或視頻,以及輸出的保存來編寫代碼。

6. 釋放Camera:使用Camera之後,你的應用程序必須釋放Camera,以便其他應用程序能夠使用。

Camera硬件是一個必須要認真管理的共享資源,因此你的應用程序在使用它時,不能跟其他應用程序發生沖突。下文將討論如何檢查Camera硬件、如何申請對Camera的訪問,如何采集圖片和視頻,以及在應用使用完成後如何釋放Camera。

警告:在應用程序使用完Camera時,要記住通過調用Camera.release()方法來釋放Camera對象。如果你的應用程序沒有正確的釋放Camera,所有的後續的視圖對Camera的訪問,包括你自己的應用程序,都會失敗,並可能到你的或其他的應用程序關閉。

檢查Camera硬件

如果你的應用程序沒有使用清單特別的聲明要使用Camera,那麼就應該在運行時檢查Camera是否有效。使用PackageManager.hasSystemFeature()方法,來執行這個檢查,如下例代碼所示:

/** Check if this device has a camera */

private boolean checkCameraHardware(Context context) {

    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){

        // this device has a camera

        return true;

    } else {

        // no camera on this device

        return false;

    }

}

Android設備能夠有多個Camera,例如用於攝影的背面Camera和用於視頻會話的前面Camera。Android2.3(API Level9)以後的版本允許你使用Camera.getNumberOfCameras()方法來檢查設備上可用的Camera的數量。

訪問Camera

如果你已經判斷在應用程序所運行的設備上有Camera,你必須獲取通過Camera實例才能申請訪問它(除非使用Intent來訪問Camera)。

使用Camera.open()方法來訪問主Camera,並確保要捕獲任何異常,如下例代碼所示:

/** A safe way to get an instance of the Camera object. */

public static Camera getCameraInstance(){

    Camera c = null;

    try {

        c = Camera.open(); // attempt to get a Camera instance

    }

    catch (Exception e){

        // Camera is not available (in use or does not exist)

    }

    return c; // returns null if camera is unavailable

}

警告:在使用Camera.open()時,要始終檢查異常。如果沒有檢查Camera是否被使用或是否存在,會導致你的應用程序被系統關閉。

在運行Android2.3(API Level9)以上的設備上,你能夠使用Camera.open(int)方法來訪問指定的Camera。上面的示例代碼訪問的是第一個Camera,也就是多個Camera的設備上背面的那個Camera。

檢查Camera功能

一旦獲得瞭訪問Camera的權限,就可以使用Camera.getParameters()方法來獲取更多的有關Camera能力的信息,這個方法返回一個Camera.Parameters對象。在使用API Level9以上的版本時,使用Camera.getCameraInfo()方法來判斷Camera是在設備的前面還是後面,以及圖像的方向。

創建一個預覽類

對用戶有效的拍照或錄像,必須是在設備的Camera上能夠看到。Camera預覽類是一個SurfaceView類,它能夠實時的顯示來自Camera的圖像數據,因此用戶能夠取景和采集圖片或視頻。

下例的示例代碼演示瞭如何創建能夠被包含到View佈局中的基本的Camera預覽類。為瞭捕獲創建和銷毀View的回調事件,這個類實現瞭SurfaceHolder.Callback接口,用於跟Camera的預覽輸入相匹配:

/** A basic Camera preview class */publicclassCameraPreviewextendsSurfaceViewimplementsSurfaceHolder.Callback{    privateSurfaceHolder mHolder;    privateCamera mCamera;     publicCameraPreview(Context context,Camera camera){        super(context);        mCamera = camera;         // Install a SurfaceHolder.Callback so we get notified when the        // underlying surface is created and destroyed.        mHolder = getHolder();        mHolder.addCallback(this);        // deprecated setting, but required on Android versions prior to 3.0        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    }     publicvoid surfaceCreated(SurfaceHolder holder){        // The Surface has been created, now tell the camera where to draw the preview.        try{            mCamera.setPreviewDisplay(holder);            mCamera.startPreview();        }catch(IOException e){            Log.d(TAG,"Error setting camera preview: "+ e.getMessage());        }    }     publicvoid surfaceDestroyed(SurfaceHolder holder){        // empty. Take care of releasing the Camera preview in your activity.    }     publicvoid surfaceChanged(SurfaceHolder holder,int format,int w,int h){        // If your preview can change or rotate, take care of those events here.        // Make sure to stop the preview before resizing or reformatting it.         if(mHolder.getSurface()==null){          // preview surface does not exist          return;        }         // stop preview before making changes        try{            mCamera.stopPreview();        }catch(Exception e){          // ignore: tried to stop a non-existent preview        }         // set preview size and make any resize, rotate or        // reformatting changes here         // start preview with new settings        try{            mCamera.setPreviewDisplay(mHolder);            mCamera.startPreview();         }catch(Exception e){            Log.d(TAG,"Error starting camera preview: "+ e.getMessage());        }    }}

如果你要給你Camera預覽窗口設置一個特定的尺寸,可以像上面註釋中標註的那樣,設置surfaceChanged()方法。在設置預覽尺寸的時候,必須使用來自getSupportedPreviewSizes()方法的值,在setPreviewSize()方法中不能使用隨意的值。

發佈留言

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