Android2.2的camera應用程序中支持雙camera切換(一)(轉)

Android2.2的camera應用程序中支持雙camera切換(一)(轉)  

2011-06-09 11:31:38|  分類: android|字號 訂閱

我曾經寫過一篇文章“Android2.2平臺上支持多camera”,網址爲:

http://blog.csdn.net/wxzking/archive/2011/03/05/6225143.aspx

這篇文章主要描述了Android2.2camera系統的Framework層如何支持雙camera。在camera的應用程序中,只是簡單地加了一些測試code。由於測試需要,要在camera的應用程序的菜單中加入菜單項,動態地切換前後camera,以方便測試。

下面我將在camera應用程序的preference菜單(也就是我們看到的第一個菜單,可以設置圖像大小,場景等)中,添加select_camera項,其有兩個成員,分別爲:back_camerafront_camera,默認選中back_camera

       接下來,我將按照文件依次介紹如何修改菜單並支持camera切換。 

1.     camera_preferences.xml文件

其位於Packages\apps\camera\res\xml\camera_preferences.xml

camera_preferences.xml文件中,包含了camera應用程序所支持的所有preference菜單。首先需要在這個文件中添加如下code

<ListPreference camera:key="pref_camera_id_key"

 camera:defaultValue="@string/pref_camera_id_default"

 camera:title="@string/pref_camera_id_title"

 camera:entries="@array/pref_camera_id_entries"

 camera:entryValues="@array/pref_camera_id_entryvalues" />

該菜單項的名稱爲:pref_camera_id_title,其定義爲:Select_camera;默認選中的是pref_camera_id_default,其定義爲:back_camera菜單項包含的成員爲:pref_camera_id_entries,其定義在文件arrays.xml中,爲:pref_camera_id_entry_backpref_camera_id_entry_front,即Back_cameraFront_camera。菜單項成員對應的鍵值爲pref_camera_id_entryvalues,其定義爲:back_camerafront_camera

 

2.     strings.xml文件

          其位於Packages\apps\camera\ res\values\strings.xml

strings.xml文件中添加如下字符串的定義:

<string name="pref_camera_id_title">Select_camera</string>

<string name="pref_camera_id_entry_back">Back_camera</string>

<string name="pref_camera_id_entry_front">Front_camera</string>

<string name="pref_camera_id_default" translatable="false">back_camera</string>

 

3.     arrays.xml文件

其位於Packages\apps\camera\ res\values\ arrays.xml

arrays.xml文件中添加如下定義,其定義了菜單項成員及其鍵值。

<string-array name="pref_camera_id_entries" translatable="false">

  <item>@string/pref_camera_id_entry_back</item>

  <item>@string/pref_camera_id_entry_front</item>

 </string-array>

<string-array name="pref_camera_id_entryvalues" translatable="false">

  <item>back_camera</item>

  <item>front_camera</item>

 </string-array>

 

4.       CameraSettings.java文件

其位於Packages\apps\camera\ src\com\android\camera\CameraSettings.java

首先定義:

public static final String KEY_CAMERA_ID = "pref_camera_id_key";

這個與文件camera_preferences.xml中的菜單項對應。

然後在函數:

private void initPreference(PreferenceGroup group)中添加如下的code

ListPreference cameraId = group.findPreference(KEY_CAMERA_ID); 

code的意思是在camera preference中去找鍵值爲KEY_CAMERA_ID的菜單項。如果不存在則返回null,否則返回該菜單項。

函數public ListPreference findPreference(String key)的定義在文件

PreferenceGroup.java中。

緊接着,又添加code

if (cameraId != null) {

  filterUnsupportedOptions(group, cameraId,

  mParameters.getSupportedCameraId());}

函數mParameters.getSupportedCameraId()將獲取camera 硬件支持的camera切換的項,其定義在文件Framework/base/core/java/android/hardware/camera.javacameraId相當於從camera_preferences.xml中獲取的camera切換的項,它倆之間需要做個匹配,如果camera硬件支持的項不存在或者只有一項,則需要從group中去掉camera切換的菜單。

同時,添加如下兩個函數:

    public static int getCameraId(Parameters parameters){      

        if(parameters.getCameraIdString().equals("front_camera"))

            return 1;

        else

            return 0;

    }

    public static void setCameraId(int cameraId, Parameters parameters){

        parameters.setCamId(cameraId);

}

通過它們可以獲取或者設置cameraID

 

5.     Camera.java文件

其位於Packages\apps\camera\ src\com\android\camera\ Camera.java

在函數public void onCreate(Bundle icicle)中添加:

    mCameraId = 0;

    CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];

    CameraHolder.instance().setCameraId(mCameraId);

設置mCameraId0,即表示默認打開後置camera

將函數private void ensureCameraDevice()改爲:

    private void ensureCameraDevice() throws CameraHardwareException {

        if (mCameraDevice == null) {

        CameraHolder.instance().setCameraId(mCameraId);

            mCameraDevice = CameraHolder.instance().open();

            mInitialParams = mCameraDevice.getParameters();

        }

    }

在打開cameraDevice前,調用CameraHolder.instance().setCameraId(mCameraId)設置當前需要打開的cameraID

在函數private void updateCameraParametersPreference()中添加:

String cameraId = mPreferences.getString(CameraSettings.KEY_CAMERA_ID,

                getString(R.string.pref_camera_id_default));       

if (isSupported(cameraId, mParameters.getSupportedCameraId())) {

    if (!mParameters.getCameraIdString().equals(cameraId)) {

         mParameters.setCameraIdString(cameraId);      

    }

}

該函數是用來更新菜單設置的,

mPreferences.getString(CameraSettings.KEY_CAMERA_ID,

getString(R.string.pref_camera_id_default))獲取了鍵值KEY_CAMERA_ID對應的菜單項當前所選擇的項。isSupported(cameraId, mParameters.getSupportedCameraId())用來判斷該項是否是camera硬件所支持的項。如果是,使用

mParameters.getCameraIdString().equals(cameraId)來判斷該項是否與保存的cameraID是否一致,如果不一致,則使用mParameters.setCameraIdString(cameraId)更新保存值。通過這個函數,當用戶選擇菜單時,它就會用菜單上的變化更新當前保存的值。

在函數private void onSharedPreferenceChanged()的末尾添加code

int cameraId = CameraSettings.getCameraId(mParameters);

if (mCameraId != cameraId) {

    switchCameraId(cameraId);

}

使用CameraSettings.getCameraId(mParameters)獲取目前保存的cameraID,讓它與mCameraId比較,如果不一致,則需要切換camera。函數switchCameraId()的定義如下:

private void switchCameraId(int cameraId) {

        if (mPausing || !isCameraIdle()) return;

    Log.v(TAG, "switch camera: new cameraID: " + cameraId + ", old cameraID: " + mCameraId);

        mCameraId = cameraId;

        CameraSettings.setCameraId(cameraId, mParameters);

  

        stopPreview();

        closeCamera();

 

        // Remove the messages in the event queue.

        mHandler.removeMessages(RESTART_PREVIEW);

 

        // Reset variables

        mJpegPictureCallbackTime = 0;

        mZoomValue = 0;

 

        // Reload the preferences.

        mPreferences = PreferenceManager.getDefaultSharedPreferences(this);

        CameraSettings.upgradePreferences(mPreferences);

       

        // Restart the preview.

        resetExposureCompensation();

        //if (!restartPreview()) return;

        restartPreview();

 

        initializeZoom();

 

        // Reload the UI.

        if (mFirstTimeInitialized) {

            initializeHeadUpDisplay();

        }

}

(待續)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章