场景模式scence mode流程

阅读: 评论:0

场景模式scence mode流程

场景模式scence mode流程

参考:

amera设置取景模式流程分析:

在Android平台上,设置菜单有两种方式:通过XML布局来实现和通过Menu.add方法实现。Camera系统中的菜单可以说是通过XML布局来实现的,但它的实现过程并非像一般文章里介绍的那样简单。所以,在此我就以设置取景模式的菜单为例,将Camera系统中菜单的设置流程作以简单介绍。

1、资源文件分析
在packages/apps/Camera/res/xml/有两个xml文件,分别为l(拍照的xml文件)和l(视频录制的xml文件)。这两个文件中列举了Camera和Video Camera两种模式下的不同菜单信息。以l为例,其中关于Scence mode的菜单项信息为:

<PreferenceGroup
。。。<IconListPreferencecamera:key="pref_camera_scenemode_key"camera:defaultValue="@string/pref_camera_scenemode_default"camera:title="@string/pref_camera_scenemode_title"camera:singleIcon="@drawable/ic_scn_holo_light"camera:entries="@array/pref_camera_scenemode_entries"camera:entryValues="@array/pref_camera_scenemode_entryvalues" />
。。。
</PreferenceGroup>

问题:什么是PreferenceGroup和IconListPreference

pref_camera_scenemode_title的定义在packages/apps/Camera/res/l中,其中有如下的定义:
    <!-- Settings screen, Select Scene mode --><string name="pref_camera_scenemode_title">Scene mode</string>
这个是相机设置上的标题,点击这个控件就会选择相应的取景模式

pref_camera_scenemode_entries定义在
packages/apps/Camera/res/l中,其中有如下的定义:
    <!-- Camera Preferences Scene Mode dialog box entries --><string-array name="pref_camera_scenemode_entries" translatable="false"><item>@string/pref_camera_scenemode_entry_auto</item><item>@string/pref_camera_scenemode_entry_landscape</item><item>@string/pref_camera_scenemode_entry_portrait</item><item>@string/pref_camera_scenemode_entry_night</item><item>@string/pref_camera_scenemode_entry_night_portrait</item><item>@string/pref_camera_scenemode_entry_action</item><item>@string/pref_camera_scenemode_entry_theatre</item><item>@string/pref_camera_scenemode_entry_beach</item><item>@string/pref_camera_scenemode_entry_snow</item><item>@string/pref_camera_scenemode_entry_sunset</item><item>@string/pref_camera_scenemode_entry_steadyphoto</item><item>@string/pref_camera_scenemode_entry_fireworks</item><item>@string/pref_camera_scenemode_entry_sports</item><item>@string/pref_camera_scenemode_entry_party</item><item>@string/pref_camera_scenemode_entry_candlelight</item></string-array>
由上面这些定义,我们可以看出,Android的Camera应用程序支持auto到candlelight的取景模式。但是硬件并非都支持这些模式的。所以最终的菜单中只会显示这几种模式当中中底层硬件所支持的,如果硬件支持的取景模式与其中任何一种都不匹配,则不会显示出“Scene mode”的菜单。

2、菜单的创建

在文件PackagesappslegacycamerasrccomandroidcameraCamera.java中,函数onCreateOptionsMenu()用来创建Camera系统的菜单。其具体定义如下:
    @Overridepublic boolean onCreateOptionsMenu(Menu menu) {CreateOptionsMenu(menu);if (mIsImageCaptureIntent) {// No options menu for urn false;} else {addBaseMenuItems(menu);}return true;}
在非Video Camera模式下,mIsImageCaptureIntent为true,此处将不做任何处理。当mIsImageCaptureIntent为false时,即Video Camera模式下,将调用函数addBaseMenuItems()来创建Video Camera的菜单。取景模式的菜单不会出现在Video Camera模式下,所以就不对addBaseMenuItems()函数分析了。

在Camera.java文件中定义了类MainHandler,它里面只有一个成员函数handleMessage(),它用来处理Camera应用程序中的message。
    private class MainHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case CLEAR_SCREEN_DELAY: {getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);break;}case FIRST_TIME_INIT: {initializeFirstTime();break;}case SET_CAMERA_PARAMETERS_WHEN_IDLE: {setCameraParametersWhenIdle(0);break;}case CHECK_DISPLAY_ROTATION: {// Set the display orientation if display rotation has changed.// Sometimes this happens when the device is held upside// down and camera app is opened. Rotation animation will// take some time and the rotation value we have got may be// wrong. Framework does not have a callback for this now.if (DisplayRotation(Camera.this) != mDisplayRotation) {setDisplayOrientation();}if (SystemClock.uptimeMillis() - mOnResumeTime < 5000) {mHandler.sendEmptyMessageDelayed(CHECK_DISPLAY_ROTATION, 100);}break;}case SHOW_TAP_TO_FOCUS_TOAST: {showTapToFocusToast();break;}case UPDATE_THUMBNAIL: {mImageSaver.updateThumbnail();break;}}}}
Message FIRST_TIME_INIT应该在类Camera初始化时就会被处理,我是这样猜的,只是还没有找到具体的code。
initializeFirstTime()的实现如下所示:
。。。
        mHeadUpDisplay = new CameraHeadUpDisplay(this);
        mHeadUpDisplay.setListener(new MyHeadUpDisplayListener());
        initializeHeadUpDisplay();
。。。

initializeHeadUpDisplay
    CameraSettings settings = new CameraSettings(this, mInitialParams,CameraHolder.instance().getCameraInfo());
    mHeadUpDisplay.initialize(l.camera_preferences),getZoomRatios(), mOrientationCompensation);

语句mHeadUpDisplay.initialize(l.camera_preferences),getZoomRatios(), mOrientationCompensation);中的R.xml.camera_preferences指的就是l资源文件。
接下来我们将对PreferenceGroup(),mHeadUpDisplay.initialize()和MyHeadUpDisplayListener做以介绍。

PreferenceGroup()
函数PreferenceGroup()定义在文件Packages/apps/camera/src/com/android/camera/CameraSetting.java中。其具体定义为:
    public PreferenceGroup getPreferenceGroup(int preferenceRes) {PreferenceInflater inflater = new PreferenceInflater(mContext);PreferenceGroup group =(PreferenceGroup) inflater.inflate(preferenceRes);if (mParameters != null) initPreference(group);return group;}
函数inflater.inflate(preferenceRes)将l文件中的菜单信息存储到PreferenceGroup中。接着函数initPreference()对这些信息做了处理,其定义为:
    private void initPreference(PreferenceGroup group) {
。。。ListPreference sceneMode = group.findPreference(KEY_SCENE_MODE);
。。。if (sceneMode != null) {filterUnsupportedOptions(group,sceneMode, SupportedSceneModes());}
。。。
}

其中,宏定义 KEY_SCENE_MODE定义在文件Packages/apps/camera/src/com/android/camera/CameraSetting.java中,具体定义为:
    public static final String KEY_SCENE_MODE = "pref_camera_scenemode_key";
该值与l中的KEY值匹配。

ListPreference sceneMode = group.findPreference(KEY_SCENE_MODE);将Scence mode信息存储在了结构体ListPreference sceneMode中。

语句
        if (sceneMode != null) {
            filterUnsupportedOptions(group,
                    sceneMode, SupportedSceneModes());
        }
SupportedSceneModes()获取了硬件Camera所支持的场景模式信息。
该信息在我目前所拿的机器在Camera HAL层中实现。在函数initDefaultParameters()中设置了硬件所支持的picture大小。路径:broadcomrhea_hawaiiv4l2_camerahalbrcmCameraHAL.cpp
CODE如下:
status_t CameraHAL::initDefaultParameters()
{
...//这个需要进一步分析源码。下次分析。str8 = pCamDev->querySceneModes(defScene);if (str8.length() > 0) {ALOGI("initDefaultParameters(): camera device supports %s scene modes", str8.string());mParameters.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, str8.string());mParameters.set(CameraParameters::KEY_SCENE_MODE, defScene.string());}elseALOGI("initDefaultParameters(): camera deevice does not support any scene mode");
...
}

函数 filterUnsupportedOptions() 会将Camera应用层和硬件支持的Scence mode中两者匹配的大小存储在group中。
这样PreferenceGroup()获取的group就是最终显示到Scence mode选项上的模式。

2.mHeadUpDisplay.initialize()
函数mHeadUpDisplay.initialize()定义在文件
broadcom_test_appsbrcmcamerasrccombroadcomcamerauiCameraHeadUpDisplay.java 中,其具体定义为:
    public void initialize(Context context, PreferenceGroup group,float[] initialZoomRatios, int initialOrientation) {mInitialZoomRatios = initialZoomRatios;mInitialOrientation = initialOrientation;super.initialize(context, group);//调用父类的initialize}public void initialize(Context context, PreferenceGroup preferenceGroup) {mPreferenceGroup = preferenceGroup;mSharedPrefs = (context);mPopupWindow = null;clearComponents();initializeIndicatorBar(context, preferenceGroup);//将group添加到菜单中。实现如下requestLayout();}protected void initializeIndicatorBar(Context context, PreferenceGroup group) {super.initializeIndicatorBar(context, group);ListPreference[] prefs = getListPreferences(group,CameraSettings.KEY_FOCUS_MODE,CameraSettings.KEY_EXPOSURE,CameraSettings.KEY_SCENE_MODE,CameraSettings.KEY_PICTURE_SIZE,CameraSettings.KEY_JPEG_QUALITY,CameraSettings.KEY_COLOR_EFFECT);mOtherSettings = new OtherSettingsIndicator(context, prefs);mOtherSettings.setOnRestorePreferencesClickedRunner(new Runnable() {public void run() {if (mListener != null) {RestorePreferencesClicked();}}});mIndicatorBar.addComponent(mOtherSettings);addIndicator(context, group, CameraSettings.KEY_WHITE_BALANCE);addIndicator(context, group, CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE);addIndicator(context, group, CameraSettings.KEY_VIDEO_QUALITY);addIndicator(context, group, CameraSettings.KEY_CAMERA_ID);mIndicatorBar.setOrientation(mInitialOrientation);}
}
函数addComponent()将group中的Scence mode添加到了菜单中。至此,菜单的创建就告一段落。下面我们介绍一下菜单的事件。


3、菜单的监听事件MyHeadUpDisplayListener
当菜单被点击时,菜单的监听事件就会监听到该事件,并作出相应的处理。监听事件定义在文件broadcom_test_appsbrcmcamerasrccombroadcomcameraCamera.java
    private class MyHeadUpDisplayListener implements HeadUpDisplay.Listener {public void onSharedPreferencesChanged() {SharedPreferenceChanged();}public void onRestorePreferencesClicked() {RestorePreferencesClicked();}public void onPopupWindowVisibilityChanged(int visibility) {}}
函数onSharedPreferenceChanged()定义为:
onSharedPreferenceChangedsetCameraParametersWhenIdle(UPDATE_PARAM_PREFERENCE);setCameraParametersupdateCameraParametersPreferenceprivate void updateCameraParametersPreference() {
....// Since change scene mode may change supported values,// Set scene mode first,mSceneMode = String(CameraSettings.KEY_SCENE_MODE,getString(R.string.pref_camera_scenemode_default));if (isSupported(mSceneMode, SupportedSceneModes())) {if (!SceneMode().equals(mSceneMode)) {mParameters.setSceneMode(mSceneMode);mCameraDevice.setParameters(mParameters);// Setting scene mode will change the settings of flash mode,// white balance, and focus mode. Here we read back the// parameters, so we can know those settings.mParameters = Parameters();}} else {mSceneMode = SceneMode();if (mSceneMode == null) {mSceneMode = Parameters.SCENE_MODE_AUTO;}}
...
}


本文发布于:2024-01-29 07:46:28,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170648559513777.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:场景   流程   模式   scence   mode
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23