转自:http://blog.csdn.net/wxzking/archive/2011/05/02/6384576.aspx
我曾经写过一篇文章“Android2.2平台上支持多camera”,网址为:
http://blog.csdn.net/wxzking/archive/2011/03/05/6225143.aspx。
这篇文章主要描述了Android2.2下camera系统的Framework层如何支持双camera。在camera的应用程序中,只是简单地加了一些测试code。由于测试需要,要在camera的应用程序的菜单中加入菜单项,动态地切换前后camera,以方便测试。
下面我将在camera应用程序的preference菜单(也就是我们看到的第一个菜单,可以设置图像大小,场景等)中,添加select_camera项,其有两个成员,分别为:back_camera和front_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_back和pref_camera_id_entry_front,即Back_camera和Front_camera。菜单项成员对应的键值为pref_camera_id_entryvalues,其定义为:back_camera和front_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.java中。cameraId相当于从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);
}
通过它们可以获取或者设置camera的ID。
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);
设置mCameraId为0,即表示默认打开后置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)设置当前需要打开的camera的ID。
在函数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();
}
}
6. CameraHeadUpDisplay.java文件
其位于Packages/apps/camera/ src/com/android/camera/ui/ CameraHeadUpDisplay.java。
在函数getListPreferences中添加CameraSettings.KEY_CAMERA_ID,即如下所示:
ListPreference prefs[] = getListPreferences(group,
CameraSettings.KEY_FOCUS_MODE,
CameraSettings.KEY_EXPOSURE,
CameraSettings.KEY_SCENE_MODE,
CameraSettings.KEY_PICTURE_SIZE,
CameraSettings.KEY_CAMERA_ID,
CameraSettings.KEY_JPEG_QUALITY,
CameraSettings.KEY_COLOR_EFFECT);
函数getListPreferences()定义在文件HeadUpDisplay.java中,其定义为:
protected static ListPreference[] getListPreferences(
PreferenceGroup group, String ... prefKeys) {
ArrayList<ListPreference> list = new ArrayList<ListPreference>();
for (String key : prefKeys) {
ListPreference pref = group.findPreference(key);
if (pref != null && pref.getEntries().length > 0) {
list.add(pref);
}
}
return list.toArray(new ListPreference[list.size()]);
}
这里的处理,就决定了哪些菜单项会被考虑去做显示。所以必须添加CameraSettings.KEY_CAMERA_ID进去,否则菜单项是不会被显示的。
7. Camera.java文件
其位于Framework/base/core/java/android/hardware/camera.java。
在这个文件中,主要是提供几个获取和设置cameraId的接口。首先定义:
private static final String KEY_CAMERA_ID = "cameraid";
public void setCamId(int cameraId)
{
if(0 == cameraId){
set(KEY_CAMERA_ID, "back_camera");
}
else{
set(KEY_CAMERA_ID, "front_camera");
}
}
public int getCamId()
{
if("back_camera" == get(KEY_CAMERA_ID)){
return 0;
}
else{
return 1;
}
}
public void setCameraIdString(String value)
{
set(KEY_CAMERA_ID, value);
}
public String getCameraIdString()
{
return get(KEY_CAMERA_ID);
}
public List<String> getSupportedCameraId() {
String str = get(KEY_CAMERA_ID + SUPPORTED_VALUES_SUFFIX);
return split(str);
}
这里需要说明的是,在camera HAL必须把硬件camera所支持的cameraID信息表示清楚,否则应用程序不能正确显示camera切换菜单。
8. CameraParameters.cpp文件
其位于Framework/base/libs/camera/CameraParameters.cpp。
在该文件中添加如下定义:
const char CameraParameters::KEY_CAMERA_ID[] = "cameraid";
const char CameraParameters::KEY_SUPPORTED_CAMERA_ID[] = "cameraid-values";
同时,CameraParameters.h中添加:
static const char KEY_CAMERA_ID[];
static const char KEY_SUPPORTED_CAMERA_ID[];
上述文字,就Android2.2下camera应用程序中如何添加菜单支持camera切换问题,做了一些描述。希望对刚接触Android平台下camera的朋友能有所帮助。如果有其他问题,可以联系我。
Revision History 修订历史记录 | |||
Version 版本 | Date 日期 | Author 作者 | Brief Description 变更简要 |
0.0.1 | 2011-05-02 | Wangxiaozhe QQ:1226062415 | Init draft. |
|
|
|
|
|
|
|
|
|
|
|
|