Android原生模块Camera分析1Word文档下载推荐.docx
《Android原生模块Camera分析1Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Android原生模块Camera分析1Word文档下载推荐.docx(65页珍藏版)》请在冰豆网上搜索。
android.hardware.camera.autofocus"
android:
required="
false"
能够硬件启动照相机设备自动对焦的请求
android.permission.RECORD_AUDIO"
允许应用记录音频信息
android.permission.ACCESS_FINE_LOCATION"
/>
允许应用访问精确(如GPS)性的定位
android.permission.WAKE_LOCK"
允许使用电源锁定管理以使进程休眠或屏幕变暗
android.permission.SET_WALLPAPER"
允许应用设置壁纸
android.permission.WRITE_EXTERNAL_STORAGE"
允许应用写(非读)用户的外部存储器
android.permission.READ_SMS"
允许应用读取短信息.
applicationandroid:
icon="
@drawable/ic_launcher_camera"
label="
@string/camera_label"
taskAffinity="
"
>
<
receiverandroid:
.CameraButtonIntentReceiver"
intent-filter>
actionandroid:
android.intent.action.CAMERA_BUTTON"
/intent-filter>
/receiver>
activityandroid:
.Camera"
照相界面
android:
configChanges="
orientation|keyboardHidden"
方向感应和键盘隐藏
theme="
@android:
style/Theme.Black.NoTitleBar.Fullscreen"
无标题栏
screenOrientation="
landscape"
屏幕定向
clearTaskOnLaunch="
true"
默认初始方向横向
android.task.camera"
android.intent.action.MAIN"
程序启动时默认界面是camera
categoryandroid:
android.intent.category.DEFAULT"
android.intent.category.LAUNCHER"
android.media.action.IMAGE_CAPTURE"
获得图像
android.media.action.STILL_IMAGE_CAMERA"
/activity>
.VideoCamera"
摄像界面
@string/video_camera_label"
@drawable/ic_launcher_video_camera"
(同上)android:
android.task.camcorder"
android.media.action.VIDEO_CAMERA"
android.media.action.VIDEO_CAPTURE"
/application>
简单流程:
由AndroidManifest.xml的android.intent.action.main可知先启动camera的activity。
camera启动
1.一个activity启动调用流程:
onCreate()-->
onStart()-->
onResume()
onCreate():
1.可添加所需布局文件,画界面。
2.开启线程,启动硬件摄像头,调用CameraHolder.instance().open()得到一个android.hardwareCamera实例mCameraDevice
ensureCameraDevice()-->
CameraHolder.instance().open()-->
mCameraDevice.getParameters();
确保摄像头存在,并将摄像头打开。
startPreview();
开始取景预览。
3.创建VideoPreview的SurfaceHolder,同时注册callback函数,当VideoPreview的长宽变化时,调用SurfaceChanged()函数
mSurfaceView=(SurfaceView)findViewById(R.id.camera_preview);
SurfaceHolderholder=mSurfaceView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
4.mIsImageCaptureIntent是否为从短信息或联系人编辑界面发送的intent到camera
mIsImageCaptureIntent=isImageCaptureIntent();
当该函数返回true时,表示从短信息或联系人界面跳转到拍照界面为false时,表示从桌面程序正常启动camera;
要注意两种不同情况所需的右侧界面功能按钮区有变动。
onStart():
1.mSwitcher.setSwitch(SWITCH_CAMERA)设置拍照录像切换按钮切换到照相模式。
onResume()
startPreview()重新开始预览
1.当按home键退出程序时,会掉用stopPreview(),故再次进入时,会执行onResume()函数,在此函数中,应重新开启预览功能。
2.keepScreenOnAwhile()点亮屏幕,防止屏幕变黑。
2.拍照录像切换功能
1.Switcher继承自ImageView,在布局文件中直接布局即可
2.mSwitch为true时,滑块在下方,显示拍照界面;
当mSwitch为false时,滑块在上方,显示录像界面。
3.当点击或触碰拍照录像切换按钮时:
MotionEvent.ACTION_UP-->
tryToSetSwitch()-->
mListener.onSwitchChanged(this,onOff)在camera.java中实现该接口,
调用switchToVideoMode()-->
MenuHelper.gotoVideoMode(this)
-->
startCameraActivity(),并结束当前程序。
3.updateThumbnailButton()更新功能按钮去的到相簿按钮
1.调用事件:
initializeFirstTime初始化时调用
initializeSecondTime()时调用
Intent.ACTION_MEDIA_SCANNER_FINISHED,扫描SD卡结束时调用
2.mThumbController.isUriValid(),当图库里有图片时,值为TRUE;
当图库里无图片时,值为FALSE。
3.updateLastImage()更新到相簿按钮上的显示图片。
4.mThumbController.updateDisplayIfNeeded()-->
if(mUri==null)mButton.setImageDrawable(null);
当图库无照片时,此处不显示任何照片。
4.shutterButton拍照按钮
1.对焦调用流程按下屏幕上的ShutterButton按钮。
ShutterButton.java中的监听线程调用callShutterButtonFocus(),这个函数会调用接口:
ShutterButton.OnShutterButtonListener的函数onShutterButtonFocus()。
Camera.java实现了接口ShutterButton.OnShutterButtonListener。
故Camera.java中的函数onShutterButtonFocus()被调用。
接着的执行流程为----->
doFocus()------>
autoFocus()--->
mCameraDevice.autoFocus()。
2.拍照调用流程之后ShutterButton.java调用performClick(),这个函数中调用了Camera.java中的onShutterButtonClick()接着的执行流程为----->
dosnap()----->
ImagePicture.onSnap()----->
ImageCapture.initiate()
---->
ImageCapture.capture()此函数执行完后,takepicture过程完成takePicture完成后,surfaceChanged()将被调用将刚照下的照片显示在屏幕上。
Camera.java中的回调接口JpegPictureCallback中的函数onPictureTaken()接着执行。
这个函数先调用ImageCapture.storeImage()将jpeg图像数据存储在内存。
3.picture的thumbnail显示过程:
ImageCapture.storeImage()--->
ImageCapture.setLastPictureThumb()--->
mThumbController.setData(uri,lastPictureThumb);
5.布局文件
1.attach_camera_control.xml,当从短信息或联系人界面,进入camera时,右侧功能按钮区的“确定”“重拍”及“取消”
2.camera_control.xml,camera和videocamera主界面右侧的功能按钮区的布局
3.camera.xml,camera主界面左侧预览取景区的布局
4.video_camera.xml,videocamera主界面左侧预览取景区的布局
5.on_screen_hint.xml,SD卡相关信息的输出,如在屏幕下方提示“使用相机前请先插入SD卡。
”
6.照相机SD卡
1.BroadcastReceivermReceiver,接受SD卡发出的状态变化消息。
2.Intent.ACTION_MEDIA_MOUNTED挂在
Intent.ACTION_MEDIA_UNMOUNTED未挂在
Intent.ACTION_MEDIA_CHECKINGSD卡从未插入到插入的过程中会调用此状态
Intent.ACTION_MEDIA_SCANNER_FINISHED扫描SD卡结束,即SD卡进入可使用状态
3.checkStorage()->
calculatePicturesRemaining()->
MenuHelper.calculatePicturesRemaining()计算SD卡剩余空间
4.updateStorageHint()更新界面提示显示文字
其中MenuHelper.NO_STORAGE_ERROR包含SD卡状态:
MEDIA_CHECKING,MEDIA_SHARED,等SD卡被移除状态
state=Environment.getExternalStorageState()获取SD卡状态
如state.equals(Environment.MEDIA_CHECKING)表示SD卡正在准备中mStorageHint=OnScreenHint.makeText(this,noStorageText);
设置当前界面需显示的内容mStorageHint.show();
显示SD卡状态文字
7.摄像机SD卡,比照相机稍微麻烦一些
1.onResume()函数中注册receive事件
IntentFilterintentFilter=
newIntentFilter(Intent.ACTION_MEDIA_MOUNTED);
intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addDataScheme("
file"
);
mReceiver=newMyBroadcastReceiver();
registerReceiver(mReceiver,intentFilter);
mStorageStatus=getStorageStatus(true);
2.classMyBroadcastReceiver处理接收到的如上注册事件
比如其中
if(action.equals(Intent.ACTION_MEDIA_EJECT)){
updateAndShowStorageHint(false);
stopVideoRecording();
}在当拔出SD卡是触发
3.updateAndShowStorageHint()->
getStorageStatus()
此处当remaining==NO_STORAGE_ERROR,可添加如SHARE,CHECKING等状态的处理根据不同的状态,返回不同的值
例如:
if(state.equals(Environment.MEDIA_CHECKING)){
returnSTORAGE_STATUS_PREPARE;
}elseif(state.equals(Environment.MEDIA_SHARED)){
returnSTORAGE_STATUS_SHARE;
}else{
returnSTORAGE_STATUS_NONE;
}
当然,所填家的事件需要在1.2步骤中进行注册并调用此函数
4.showStorageHint()
在switch(mStorageStatus)处理所需显示信息
例如,添加如下case语句,处理如上添加的SHARE状态
caseSTORAGE_STATUS_SHARE:
errorMessage=getString(R.string.sdcard_busy_message);
break;
5.mStorageHint=OnScreenHint.makeText(this,errorMessage);
设置所需显示文字内容
6.mStorageHint.show();
显示在当前摄像机界面中
Camera系统中设置picture大小的流程分析
在Android平台上,设置菜单有两种方式:
通过XML布局来实现和通过Menu.add方法实现。
Camera系统中的菜单可以说是通过XML布局来实现的,但它的实现过程并非像一般文章里介绍的那样简单。
所以,在此我就以设置capture时picture大小为例,将Camera系统中菜单的设置流程作以简单介绍。
1、资源文件分析
在packages/apps/Camera/res/xml/有两个xml文件,分别为Camera_preferences.xml和Video_preferences.xml。
这两个文件中列举了Camera和VideoCamera两种模式下的不同菜单信息。
以Camera_preferences.xml为例,其中关于picture大小的菜单项信息为:
ListPreference
camera:
key="
pref_camera_picturesize_key"
title="
@string/pref_camera_picturesize_title"
entries="
@array/pref_camera_picturesize_entries"
entryValues="
@array/pref_camera_picturesize_entryvalues"
pref_camera_picturesize_title的定义在packages/apps/Camera/res/values/strings.xml中,其中有如下的定义:
-
!
--
Settingsscreen,Picturesizetitle
item>
@string/pref_camera_picturesize_entry_2592x1936<
/item>
@string/pref_camera_picturesize_entry_2048x1536<
@string/pref_camera_picturesize_entry_1600x1200<
@string/pref_camera_picturesize_entry_1024x768<
@string/pref_camera_picturesize_entry_320x240<
/string-array>
pref_camera_picturesize_entryvalues的定义也在
packages/apps/Camera/res/values/arrays.xml中,其中有如下的定义:
-<
string-arrayname="
pref_camera_picturesize_entryvalues"
translatable="
2592x1944<
2592x1936<
2048x1536<
1600x1200<
1024x768<
320x240<
由这些定义,我们可以看出,Android的Camera应用程序支持五种图片大小。
但是硬件并非都支持这些大小。
所以最终的菜单中只会显示这五种大小当中底层硬件所支持的,如果硬件支持的大小与其中任何一种都不匹配,则不会显示出“Picturesize”菜单。
2、菜单的创建
在文件Packages/apps/camera/src/com/android/camera/Camera.java中,函数onCreateOptionsMenu()用来创建Camera系统的菜单。
其具体定义如下:
@Override
publicbooleanonCreateOptionsMenu(Menumenu){
super.onCreateOptionsMenu(menu);
if(mIsImageCaptureIntent){
//Nooptionsmenuforattachmode.
returnfalse;
}else{
addBaseMenuItems(menu);
}