打开Camera后,有九种拍照模式,分别是普通模式,智能模式,美肤模式,HDR模式,全景模式,特效模式,留声拍照模式,声控拍照模式,连拍优选模式。设置菜单中的模式项及图标是通过MenuIconListPreference类从Camera_preferences.xml文件中取出来的,当点击模式菜单,选择某一种拍照模式时,会触发MenuController类中的MenuItem 的Onclick事件,导入菜单项,调用onSettingChanged(pref)方法,判断当前引用资源是否是拍照模式菜单,如果是拍照模式,则继续调用overrideSettings(pref.getValue(),true)方法,将所有的菜单配置信息保存到Set<MenuIconListPreference> prefs集合中,接着调用onSettingsChanged(Set<MenuIconListPreference> prefs)方法,回调OnPreferenceChangedListener接口中的onSharedPreferencesChanged(List<? extends CameraPreference> cameraPreferences)方法,在PhotoModule类的onSharedPreferencesChanged(List<? extends CameraPreference> prefs)方法里,调用processPreferences(List<? extends CameraPreference> prefs)方法,循环处理每一个菜单列表,接下来继续调用setCameraParametersWhenIdle(int additionalUpdateSet)方法设置菜单相关的参数,判断当前相机是否为空闲状态,如果为idle则调用setCameraParameters(int updateSet)方法来设置相机参数,在setCameraParameters方法里会调用updateCameraParametersZoom()方法设置变焦参数,调用updateCameraParametersPreference()方法来设置拍摄模式的详细参数,当拍摄模式改变的时候会发消息给UI进行更新操作,如果当前拍摄模式不是全景模式时,会调用updateShootMode()方法更新拍摄模式,关键代码如下所示:
boolean isupdateParameters = mCameraDevice.updateShootMode(mShootingMode.getShotMode(), mParameters , useBackProcessIfNeeded());
首先是要调用CameraProxy类中的updateShootMode方法,进一步调用FeatureCamera类中的updateShootMode方法,关键代码如下:
public boolean updateShootMode(String mode, Parameters parameters , boolean useBackProcessIfNeeded) {
mShotModeFeature = FeatureShotModeFactory.getFeatureShotModeInstance(mode, FeatureCamera.this);
if(mShotModeFeature == null)return false;
return mShotModeFeature.prepareShotMode(parameters , useBackProcessIfNeeded);
}
通过一个模式工厂取得对应模式类的实例,预先在静态代码块中将九种拍摄模式对应的类放到了Map<String, Class<? extends IFeatureShotMode>>里,在getFeatureShotModeInstance方法中先获取模式对应的类,再通过AbstractShotMode.getInstance(clazz)方法获取到实现了IfeatureShotMode接口的类的实例。
例如当设置模式为留声拍照,先从工厂里取出该模式对应的类VoicePhotoModeFeature,然后再返回这个类的实例给FeatureCamera类,再通过它的getFeatureShotMode方法将具体模式实例传递给PhotoModule类,作为UI层与中间层通信的方法。在拍照前的过程中,一定会调用capture方法来完成拍照,其中有两处地方会调用getFeatureShotMode()方法,一个是在长按连拍模式的时候,会调用mCameraDevice.getFeatureShotMode().setMaxPictureNum(int)方法,设置最大照片数目;另一个是在绑定回调接口的时候,会调用mCameraDevice.getFeatureShotMode().genJpegPictureCallback(loc, Util.SCENE_MODE_HDR.equals(mSceneMode), PhotoModule.this)方法,将具体模式类对应的回调接口与之绑定,用于处理底层上报的一些图像数据,进而完成留声模式拍照的流程。