Android4.4 Camera app初始化分析
- 格式:doc
- 大小:68.04 KB
- 文档页数:20
AndroidCamera详解相关的类1. android.hardware.camera22. Camera3. SurfaceView---这个类⽤于向⽤户呈现实时相机预览。
4. MediaRecorder---这个类⽤于从摄像机录制视频。
5. Intent---MediaStore.ACTION_IMAGE_CAPTURE或MediaStore.ACTION_VIDEO_CAPTURE可⽤于捕获图像或视频,⽽⽆需直接使⽤Camera对象。
清单声明在使⽤Camera API开始开发应⽤程序之前,应确保您的清单具有适当的声明,以允许使⽤相机硬件和其他相关功能。
相机权限 - 您的应⽤程序必须请求使⽤设备相机的权限。
<uses-permission android:name="android.permission.CAMERA" />注意:如果您通过调⽤现有的摄像头应⽤程序来使⽤摄像头,则应⽤程序不需要请求此权限。
相机功能 - 您的应⽤程序还必须声明使⽤相机功能,例如:<uses-feature android:name="android.hardware.camera" />存储权限 - 如果应⽤程序将图像或视频保存到设备的外部存储设备(SD卡),则还必须在清单中指定此选项。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />⾳频录制权限 - 对于使⽤视频捕获录制⾳频,应⽤程序必须请求获取⾳频捕获权限。
<uses-permission android:name="android.permission.RECORD_AUDIO" />创建⾃定义摄像头为应⽤程序创建⾃定义摄像头界⾯的⼀般步骤如下:1. 检测和访问摄像机 - 创建代码以检查摄像机是否存在并请求访问。
AndroidCamera系统架构源码分析(1)系统:MTK Android4.4日期:2015年10月10日stamp&data setParameters Utils::Property::tryGet一. 前述之前对MTK的Camera的源码流程有过初步的了解,现在对以前了解的东西做一些梳理总结,但也仅是对源码流程一个贯穿,并不会对其进行深入分析,方便日后工作需求做一个铺垫。
此文分析的是Camera系统源码,即Frameworks层之后的,并不是APK的源码分析。
二. 分析思路1. 先从Camera的初始化开始,以cameraID为线索,简单地从Frameworks开始贯穿到底层。
主要任务Camera如何被打开的,完成源码的贯穿。
2. 然后再从startPreview开始去了解,Camera被打开之后,取出的数据流是什么,数据流经过了怎么的处理,然后又是怎么被送出到APK,显示出来的三. 上层入口针对于上面的两个分析点,从APK上层入口开始:private Camera mCamera;mCamera = Camera.open(cameraID);mCamera.startPreview();四. Camera 初始化化 Open(1) 文件列表:Camera.java: frameworks/base/core/java/android/hardwareandroid_hardware_Camera.cpp: frameworks/base/core/jniCamera.cpp: frameworks/av/cameraCameraBase.cpp: frameworks/av/cameraCameraService.cpp:frameworks/av/services/camera/libcameraservicemodule.h: frameworks/hardware/mtkcam/moduleCamDeviceManagerBase.cppmediatek/hardward/mtkcam/devicemgrCameraClient.cppframeworks/av/services/camera/libcameraservice/api1 CameraHardwareInterface.h:frameworks/av/services/camera/libcameraservice/device(2) Frameworks层第一个被调用的是Camera.java文件里的open函数。
相机分析文档一.相机的基本知识现在的手机几乎都实现照相机功能了,而且在硬件的支持下像素也越来越高,在现实生活中的用途也越来越广,而在Android中专门提供了Camera 来处理相机相关的事件,Camera 是一个专门用来连接和断开相机服务的类,Camera 下面包括如下几个事件:Camera.AutoFocusCallback:自动调焦功能;Camera.ErrorCallback:错误信息捕捉;Camera.Parameters :相机的属性参数Camera.PictureCallback:拍照、产生图片时触发;Camera.PreviewCallback:相机预览设置;Camera.ShutterCallback:快门设置;Camera.Size:图片尺寸;要在Android中使用相机服务很简单,Camera没有构造方法,我们要使用它直接通过open()方法来打开相机设备,然后通过Camera.Parameters 对相机的一些属性进行设置,比如输出图片的格式、大小等等。
下面是Camera类一些常用的方法介绍。
Camera类的方法方法说明autoFocus 设置自动对焦getParameters 得到相机的参数open 启动相机服务release 释放Camera服务setPreviewDisplay 设置预览setParameters 设置预览参数startPreview 开始预览stopPreview 停止预览takePicture 拍照这里重点说明一下拍照的方法和使用,takePicture 方法要实现3个回调函数,分别是:Camera.ShutterCallback (快门) 和两个Camera.PictureCallback(图像数据)。
这里我们在拍照之后要取得图像数据就需要实现Camera.PictureCallback 的onPictureTaken 方法。
onPictureTaken 中第一个参数就是图像数据,第二个参数则是相机。
Camera APP层分析之对camera framework层封装解析Android4.4版本的camera和4.0版本的设计差距还是很大的,4.0版本以前的camera在是camera 主activity中直接调用camera hal 层的的接口(如android.hardware.camera.open(), android.hardware.camera.setPreviewDisplay(),android.hardware.camera..startPreview()等)与camera device通信。
Android4.4版本camera app对camera device的访问又封装了一次,对camera device的访问必须经过camera manager接口,camera manager接口定义了camera基本操作,这样便于控制和管理camera device。
下图为相关类关系图。
1.CameraManager接口:提供的访问camera设备基本的操作,实现类必须调用CameraManager.cameraOpen获取CameraManager.CameraProxy接口对象来控制camera,实现CameraManager接口的类必须拥有一个独立于主线程的线程来实现对camera的操作,CameraManager接口也包装回调函数2.CameraProxy接口,封装在CameraManager接口之内,接收对camera操作请求,发送消息到camer handle。
所有对camera的操作都经由改接口,进行异步处理3.AndroidCameraManagerImpl类,该类实现了CameraManager 接口,与camera framework层接口直接通信,起到camera app 与camera framework对话中介的作用。
4.AndroidCameraProxyImpl类,AndroidCameraManagerImpl内部类,实现CameraManager.CameraProxy接口,CameraProxy已经介绍过了就是控制对camera的访问,AndroidCameraProxyImpl 类实现了具体的操作。
初始化摄像头的参数
初始化摄像头的参数是指在开始使用摄像头之前设置摄像头的
一些基本参数,以确保摄像头能够正常工作并满足特定的需求。
首先,我们需要考虑的是摄像头的分辨率,即图像的水平和垂直像素
数量。
这是决定图像质量和清晰度的重要参数。
另外,还需要设置
帧率,即每秒传输到计算机中的图像帧数,这会影响视频的流畅度。
此外,还需要考虑对比度、亮度、色彩饱和度等图像参数的设置,
以确保图像质量符合预期。
另外,还需要考虑摄像头的焦距、光圈
等硬件参数的设置,以满足特定的拍摄需求。
在初始化摄像头参数时,还需要考虑是否需要开启自动对焦、自动曝光等功能,以及是
否需要设置特定的白平衡模式来适应不同的拍摄环境。
最后,还需
要考虑是否需要进行图像的预处理,比如去噪、边缘增强等操作,
以满足特定的应用需求。
总之,初始化摄像头的参数涉及到多个方面,需要根据具体的应用场景和需求来进行综合设置。
Android4.0Camera架构分析之preview和takePicture上篇文章介绍了,Camera初始化的过程,完成初始化之后就可以使用Camera提供的以下功能了1.预览preview2.视频录制3.拍照和参数设置打开Camera第一键事情就是预览取景preview的动作,我们先从Camera app分析起。
所有拥有拍照功能的应用,它在预览时候都要实现SurfaceHolder.Callback接口,并实现其surfaceCreated、surfaceChanged、surfaceDestroyed三个函数,同时声明一个用于预览的窗口SurfaceView ,以下是系统自带ap的源代码SurfaceView preview = (SurfaceView) findViewById(R.id.camera_preview);SurfaceHolder holder = preview.getHolder();holder.addCallback(this);还要设置camera预览的surface缓存区,系统自带app实在surfaceChange()方法里面设置Camera的预览区,以供底层获取的preview数据不断投递到这个surface缓存区内。
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {mSurfaceHolder = holder;// The mCameraDevice will be null if it fails to connect to the camera// hardware. In this case we will show a dialog and then finish the// activity, so it's OK to ignore it.if (mCameraDevice == null) return;// Sometimes surfaceChanged is called after onPause or before onResume.// Ignore it.if (mPausing || isFinishing()) return;// Set preview display if the surface is being created. Preview was// already started. Also restart the preview if display rotation has// changed. Sometimes this happens when the device is held in portrait// and camera app is opened. Rotation animation takes some time and// display rotation in onCreate may not be what we want.if (mCameraState == PREVIEW_STOPPED) {startPreview();startFaceDetection();} else {if (Util.getDisplayRotation(this) != mDisplayRotation) {setDisplayOrientation();}if (holder.isCreating()) {// Set preview display if the surface is being created and preview// was already started. That means preview display was set to null// and we need to set it now.setPreviewDisplay(holder);}}设置好以上参数后,就可以调用startPreview()进行取景预览startPreview()也是一层层往下调用,最后到Camera的服务端CameraService,我们看下它的过程Camera.java(应用)-------------> Camera.java(框架)-------------->android_hardware_camera.cpp(JNI)-------------------->Camera.cpp(客户端)------------------->CameraService.cpp(服务端)--------------------->CameraHarwareInterface(HAL接口) 在CameraService端将处理preview的请求并进入HAL层status_t CameraService::Client::startPreview() {enableMsgType(CAMERA_MSG_PREVIEW_METADATA);return startCameraMode(CAMERA_PREVIEW_MODE);}先是传递preview的消息到HAL层,然后执行previewstatus_tCameraService::Client::startCameraMode(camera_mode mode) { switch(mode) {case CAMERA_PREVIEW_MODE:if (mSurface == 0 && mPreviewWindow == 0) {LOG1("mSurface is not set yet.");// still able to start preview in this case.}return startPreviewMode();}}status_t CameraService::Client::startPreviewMode() {LOG1("startPreviewMode");status_t result = NO_ERROR;// if preview has been enabled, nothing needs to be doneif (mHardware->previewEnabled()) {return NO_ERROR;}if (mPreviewWindow != 0) {native_window_set_scaling_mode(mPreviewWindow.get(),NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);native_window_set_buffers_transform(mPreviewWindow.get (),mOrientation);}mHardware->setPreviewWindow(mPreviewWindow);result = mHardware->startPreview();return result;}然后就近去HAL层调用,并通过回调函数源源不断的将数据投递到surfaceview的缓存去,因为preview的数据是比较大的,所以数据不会携带着传上上层,而是直接在两个缓存区之间copy,一个是底层采集数据的缓存区,另一个是用于显示的surfaceview缓存区我们看看preview的回调函数是怎么处理的首先在Camera客户端与服务端连接成功的时候就会设置一个回调函数dataCallBackCameraService::Client::Client(const sp<CameraService>& cameraService,const sp<ICameraClient>& cameraClient,const sp<CameraHardwareInterface>& hardware,int cameraId, int cameraFacing, int clientPid) {......mHardware->setCallbacks(notifyCallback,dataCallback,dataCallbackTimestamp,(void *)cameraId);}在上篇有介绍到,client与server连接成功后就会new 一个client返回,在client的构造函数中,就对camera设置了notifyCallback、dataCallback、dataCallbackTimestamp三个回调函数,用于返回底层数据用于处理,看下它的处理方法void CameraService::Client::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) { case CAMERA_MSG_PREVIEW_FRAME:client->handlePreviewData(msgType, dataPtr, metadata);break;.......}继续看handlePreviewData()void CameraService::Client::handlePreviewData(int32_t msgType,const sp<IMemory>& mem,camera_frame_metadata_t *metadata) {sp<ICameraClient> c = mCameraClient;.......if (c != 0) {// Is the received frame copied out or not?if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { LOG2("frame is copied");copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);} else {LOG2("frame is forwarded");mLock.unlock();c->dataCallback(msgType, mem, metadata);}} else {mLock.unlock();}}copyFrameAndPostCopiedFrame就是这个函数执行两个buff 区preview数据的投递voidCameraService::Client::copyFrameAndPostCopiedFrame( int32_t msgType, const sp<ICameraClient>& client,const sp<IMemoryHeap>& heap, size_t offset, size_t size,camera_frame_metadata_t *metadata) {......previewBuffer = mPreviewBuffer;memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size);sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);if (frame == 0) {LOGE("failed to allocate space for frame callback");mLock.unlock();return;}mLock.unlock();client->dataCallback(msgType, frame, metadata);}将数据处理成frame,继续调用客户端client的回调函数client->dataCallback(msgType, frame, metadata);// callback from camera service when frame or image is ready void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,camera_frame_metadata_t *metadata){sp<CameraListener> listener;{Mutex::Autolock _l(mLock);listener = mListener;}if (listener != NULL) {listener->postData(msgType, dataPtr, metadata);}}还记得初始化的时候,在jni里面有设置listener吗?static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,jobject weak_this, jint cameraId){sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);context->incStrong(thiz);camera->setListener(context);}继续 listener->postData(msgType, dataPtr, metadata);void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr,camera_frame_metadata_t *metadata){......switch (dataMsgType) {case CAMERA_MSG_VIDEO_FRAME:// should never happenbreak;default:LOGV("dataCallback(%d, %p)", dataMsgType, dataPtr.get());copyAndPost(env, dataPtr, dataMsgType);break;}}继续copyAndPost(env, dataPtr, dataMsgType);void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int msgType)jbyteArray obj = NULL;// allocate Java byte array and copy dataif (dataPtr != NULL) {.......} else {LOGV("Allocating callback buffer");obj = env->NewByteArray(size);.......env->SetByteArrayRegion(obj, 0, size, data);}} else {LOGE("image heap is NULL");}}// post image data to Javaenv->CallStaticVoidMethod(mCameraJClass,fields.post_event,mCameraJObjectWeak, msgType, 0, 0, obj);if (obj) {env->DeleteLocalRef(obj);}}解释一下标红的部分,先建立一个byte数组obj,将data缓存数据存储进obj数组,CallStaticVoidMethod是C调用java函数,最后执行实在Camera.java(框架)的postEventFromNative()private static void postEventFromNative(Object camera_ref, int what, int arg1, int arg2, Object obj)Camera c = (Camera)((WeakReference)camera_ref).get();if (c == null)return;if (c.mEventHandler != null) {Message m = c.mEventHandler.obtainMessage(what, arg1, arg2, obj);c.mEventHandler.sendMessage(m);}}还是handler处理地public void handleMessage(Message msg) {switch(msg.what) {case CAMERA_MSG_SHUTTER:if (mShutterCallback != null) {mShutterCallback.onShutter();}return;case CAMERA_MSG_RAW_IMAGE:if (mRawImageCallback != null) {mRawImageCallback.onPictureTaken((byte[])msg.obj, mCamera);}return;case CAMERA_MSG_COMPRESSED_IMAGE:if (mJpegCallback != null) {mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera);}return;case CAMERA_MSG_PREVIEW_FRAME:if (mPreviewCallback != null) {PreviewCallback cb = mPreviewCallback;if (mOneShot) {// Clear the callback variable before the callback// in case the app calls setPreviewCallback from// the callback functionmPreviewCallback = null;} else if (!mWithBuffer) {// We're faking the camera preview mode to prevent// the app from being flooded with preview frames.// Set to oneshot mode again.setHasPreviewCallback(true, false);}cb.onPreviewFrame((byte[])msg.obj, mCamera);}return;}}}上面可以看出,这里处理了所有的回调,快门回调mShutterCallback.onShutter(),RawImageCallback.onPictureTaken()拍照数据回调,自动对焦回调等。
Android平台Camera及I2C总线驱动学习⼩结Android平台Camera及I2C总线驱动学习⼩结——基于MSM8x60平台硬件开发⼆部BSP科党潇⼯号:101131511.MSM8x60平台简介High-performance high-level operating system(HLOS) platform(45nm)多核处理器(Modem+Dual Apps in a single chip),⽀持Android TMDual 1.2GHz Scorpion TM +512kB shared L2 cache,eMMC LPDDR2内存专属ARM7 ⽤于功率资源控制及传感器外设操作1080pHD 编解码,Adreno TM 220图形处理器,4-lane MIPI摄像头,最⾼⽀持12M像素WCDMA,GSM,HSDPA,1x advanced,1xEV-DO Rev A/BgpsOne,BT3.0,FM Rx/Tx,WIFI WCN1314AAC,AMR-NB,EVRC,QCELP,etc2.MSM8x60平台Camera及Graphics特性Camera特性:VFE 3.1,MIPI接⼝(4-lane)优异的3A算法(AF,AE,AWB),⾃动帧率AFR(Auto Frame Rate)最⾼⽀持12MegaPixel,12bit/pixel,⽀持BAYER和YUV模式1080p预览@30fps闪光灯⽀持,触摸屏⾃动对焦⽀持业界领先的图像特效集:Hand Jitter Reduction(HJR),Motion ISO,Best-Shot mode,Anti-banding,EV control,JPEG encode & decodeGraphics特性:Adreno 220(MSM v2.0)图形处理器,88M triangles/sOpenGL ES 1.1/ OpenGL ES 1.1/ OpenVG 1.1/SVG tiny 1.2LCD显⽰最⾼⽀持到WSXGA(1440×900),60Hz刷新率。
Android的Camera系统分析一、Camera构架分析Android的Camera包含取景(preview)和拍摄照片(take picture)的功能。
目前Android 发布版的Camera程序虽然功能比较简单,但是其程序的架构分成客户端和服务器两个部分,它们建立在Android的进程间通讯Binder的结构上。
Android中Camera模块同样遵循Andorid的框架,如下图所示Camera ArchitectureCamera模块主要包含了libandroid_runtime.so、libui.so和libcameraservice.so等几个库文件,它们之间的调用关系如下所示:在Camera模块的各个库中,libui.so位于核心的位置,它对上层的提供的接口主要是Camera 类。
libcameraservice.so是Camera的server程序,它通过继承libui.so中的类实现server的功能,并且与libui.so中的另外一部分内容通过进程间通讯(即Binder机制)的方式进行通讯。
libandroid_runtime.so和libui.so两个库是公用的,其中除了Camera还有其他方面的功能。
整个Camera在运行的时候,可以大致上分成Client和Server两个部分,它们分别在两个进程中运行,它们之间使用Binder机制实现进程间通讯。
这样在client调用接口,功能则在server中实现,但是在client中调用就好像直接调用server中的功能,进程间通讯的部分对上层程序不可见。
从框架结构上来看,源码中ICameraService.h、ICameraClient.h和ICamera.h三个类定义了MeidaPlayer的接口和架构,ICameraService.cpp和Camera.cpp两个文件则用于Camera 架构的实现,Camera的具体功能在下层调用硬件相关的接口来实现。
CameraProvider启动流程分析CameraProvider是Android相机框架中的一个重要组件,它负责管理系统中可用的相机设备,并为应用程序提供访问相机功能的接口。
在本文中,我们将对CameraProvider的启动流程进行详细分析。
1. 创建CameraProvider实例:首先,应用程序需要通过CameraX的静态方法`CameraX.initialize(context)`来初始化CameraX库。
在初始化过程中,CameraX会创建一个全局的CameraProvider实例,用于管理系统中的相机设备。
2. 查询可用的相机设备:一旦CameraProvider实例创建完成,应用程序可以通过调用`CameraX.getCameraProvider(`方法来获取CameraProvider实例。
然后,应用程序可以调用CameraProvider的`getCameraIdList(`方法来获取系统中可用的相机设备的ID列表。
3. 创建相机实例:在获取到相机设备的ID列表后,应用程序可以通过调用CameraProvider的`bindToLifecycle(`方法来创建相机实例。
该方法需要传入一个LifecycleOwner对象,用于管理相机实例的生命周期。
4. 配置相机参数:一旦相机实例创建完成,应用程序可以通过调用相机实例的`getCameraControl(`方法来获取相机控制器实例。
然后,应用程序可以使用相机控制器实例来配置相机的各种参数,例如闪光灯模式、曝光模式、对焦模式等。
5. 启动预览:配置相机参数完成后,应用程序可以通过调用相机实例的`getCameraInfo(`方法来获取相机信息实例。
然后,应用程序可以使用相机信息实例来获取相机的预览输出目标,例如SurfaceTexture或SurfaceView。
最后,应用程序可以调用相机实例的`setPreviewSurface(`方法,将预览输出目标设置给相机实例,从而启动相机的预览功能。
Android4.4 Camera app初始化分析Camera app提供的主要功能:预览,拍照,摄影,全景拍摄而这些功能统一组织在CameraActivity这个组件中,并细分到各个模块逐步实现。
其中涉及的类如下图PhotoModule:负责与拍照相关的部分VideoModule:负责与视频录制相关的部分WideAnglePanoramaModule:全景照片的拍摄接下来我们分析PhotoModule启动过程,其他两个模块类似。
首先给出时序图,结合时序图,分析每一步的实现Step1:CameraActivity.onCreate()当在launcher界面点击camera图标的时候,该函数首先被调用。
public void onCreate(Bundle state) {…setContentView(yout.camera_filmstrip);…LayoutInflater inflater = getLayoutInflater();View rootLayout = inflater.inflate(yout.camera, null, false);mCameraModuleRootView = rootLayout.findViewById(R.id.camera_app_root);mPanoStitchingPanel = findViewById(R.id.pano_stitching_progress_panel);mBottomProgress = (ProgressBar) findViewById(R.id.pano_stitching_progress_bar);mCameraPreviewData = new CameraPreviewData(rootLayout,FilmStripView.ImageData.SIZE_FULL, FilmStripView.ImageData.SIZE_FULL); // Put a CameraPreviewData at the first position.mWrappedDataAdapter = new FixedFirstDataAdapter(new CameraDataAdapter(new ColorDrawable(getResources().getColor(R.color.photo_placeholder)) ),mCameraPreviewData);…setModuleFromIndex(moduleIndex);mCurrentModule.init(this, mCameraModuleRootView);…},该函数主要设置activity视图,并根据传过来的intent来判读改启动photomodule还是videomodule,当从launcher 启动的时候moduleIndex肯定是0,所以会调用mCurrentModule = new PhotoModule();新建一个PhotoModule对象,该对象就是负责拍照相关的操作。
Step2:PhotoModule(),对象创建之后,并没有做实质性的动作,我们接着往下看Step3:mCurrentModule.init(this,mCameraModuleRootVie w); mCurrentModule就是PhotoModule类的一个实例,public void init(CameraActivity activity, View parent) {mActivity = activity;mRootView = parent;mUI = new PhotoUI(activity, this, parent); mPreferences = newComboPreferences(mActivity);CameraSettings.upgradeGlobalPreferences(mPreferen ces.getGlobal());mCameraId = getPreferredCameraId(mPreferences);mContentResolver = mActivity.getContentResolver();// Surface texture is from camera screen nail and startPreview needs it.// This must be done before startPreview.mIsImageCaptureIntent = isImageCaptureIntent();mPreferences.setLocalId(mActivity, mCameraId);CameraSettings.upgradeLocalPreferences(mPreferenc es.getLocal());// we need to reset exposure for the previewresetExposureCompensation();initializeControlByIntent();mQuickCapture = mActivity.getIntent().getBooleanExtra(EXTRA_QUICK _CAPTURE, false);mLocationManager = new LocationManager(mActivity, mUI);mSensorManager = (SensorManager)(mActivity.getSystemService(Contex t.SENSOR_SERVICE));brightnessProgressBar = (ProgressBar)mRootView.findViewById(R.id.progress );if (brightnessProgressBar instanceof SeekBar) {SeekBar seeker = (SeekBar) brightnessProgressBar;seeker.setOnSeekBarChangeListener(mSeekListener); }brightnessProgressBar.setMax(MAXIMUM_BRIGHTNESS);brightnessProgressBar.setProgress(mbrightness);skinToneSeekBar = (SeekBar) mRootView.findViewById(R.id.skintoneseek);skinToneSeekBar.setOnSeekBarChangeListener(mskinT oneSeekListener);skinToneSeekBar.setVisibility(View.INVISIBLE);Title = (TextView)mRootView.findViewById(R.id.skintonetit le);RightValue = (TextView)mRootView.findViewById(R.id.skintonerig ht);LeftValue = (TextView)mRootView.findViewById(R.id.skintonelef t);Storage.setSaveSDCard(mPreferences.getString(CameraSettings.KEY_CAMERA_ SAVEPATH, "0").equals("1"));}刚才介绍过Photomodule是负责camera照相功能的,主要协调界面的显示,参数的配置,方便用户根据自己的爱好来设置相关参数。
参数View parent,是拍照界面的根节点,即在cameraactivity中inflate 的yout.camera的camera_app_root视图。
Init函数中做了很多重要的工作。
创建UI视图,初始化基本参数,Step4:new PhotoUI(activity, this, parent)视图的真正创建是在PhotoUI对象中,我们接着往下看public PhotoUI(CameraActivity activity, PhotoController controller, View parent) {mActivity = activity;mController = controller;mRootView = parent;mActivity.getLayoutInflater().inflate(yout.ph oto_module,(ViewGroup) mRootView, true);mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay);mFlashOverlay = mRootView.findViewById(R.id.flash_overlay);mPreviewCover = mRootView.findViewById(R.id.preview_cover);// display the viewmTextureView = (TextureView) mRootView.findViewById(R.id.preview_content);mTextureView.setSurfaceTextureListener(this);mTextureView.addOnLayoutChangeListener(mLayoutLis tener);initIndicators();mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button);mSwitcher = (ModuleSwitcher) mRootView.findViewById(R.id.camera_switcher);mSwitcher.setCurrentIndex(ModuleSwitcher.PHOTO_MODULE_INDEX);mSwitcher.setSwitchListener(mActivity);mMenuButton = mRootView.findViewById(R.id.menu);ViewStub faceViewStub = (ViewStub) mRootView .findViewById(R.id.face_view_stub); if (faceViewStub != null) {faceViewStub.inflate();mFaceView = (FaceView) mRootView.findViewById(R.id.face_view);setSurfaceTextureSizeChangedListener(mFaceView); }mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls);mAnimationManager = new AnimationManager();mOrientationResize = false;mPrevOrientationResize = false;}函数首先inflate yout.photo_module视图,挂在mRootView节点下,mRootView即是yout.camera中的camera_app_root视图,他是photomodule的根视图。