Android Camera开发一之基础知识.docx
- 文档编号:12303594
- 上传时间:2023-04-18
- 格式:DOCX
- 页数:24
- 大小:102.17KB
Android Camera开发一之基础知识.docx
《Android Camera开发一之基础知识.docx》由会员分享,可在线阅读,更多相关《Android Camera开发一之基础知识.docx(24页珍藏版)》请在冰豆网上搜索。
AndroidCamera开发一之基础知识
AndroidCamera开发
(一)之基础知识
概述
Android手机关于Camera的使用,一是拍照,二是摄像,由于Android提供了强大的组件功能,为此对于在Android手机系统上进行Camera的开发,我们可以使用两类方法:
一是借助Intent和MediaStore调用系统CameraApp程序来实现拍照和摄像功能,二是根据CameraAPI自写Camera程序。
基础知识
Android系统提供API来支持自定义相机拍照和系统拍照,以下是有关的类:
Camera
该类提供基础API来使用设备上的相机,且该类可以为你的应用提供拍照和录像相关的API。
SurfaceView
该类用于显示相机的预览数据。
如果你对SurfaceView还不熟悉,请参考AndroidSurfaceView的使用这篇文章。
MediaRecorder
该类提供相机录像相关的API。
注意事项
在你的应用程序能够在Android设备上使用相机之前,你应该考虑几个问题,那就是你的App打算如何使用相机拍照或者录像?
Camera需求的声明:
使用相机功能对于你的应用程序来说是否很重要并且你不希望你的应用程序被安装在没有相机的机器上?
如果是这样,那么你需要把相机需求声明在配置文件里。
调用系统拍照还是自定义相机:
你的应用程序该如何使用相机?
你是否仅仅需要拍摄一张照片或者一个视频,或者你的应用程序希望提供一种使用相机的新的方式?
存储:
是否你的应用生成的图片和视频仅对你的应用可见,还是其他应用程序例如相册或者其他的多媒体和社交App也可以使用它们?
你是否希望你的应用程序被卸载后,这些照片和视频仍然可用,还是一起被删除?
权限申明
CameraPermission-你的应用必须申请相机权限才可以使用设备相机。
name="android.permission.CAMERA"/> 注意: 如果你使用Intent调用系统相机,你的应用无需申请该权限。 StoragePermission-如果你的应用需要保存照片或者视频到设备存储中,你必须在Manifest指定文件的写权限 name="android.permission.WRITE_EXTERNAL_STORAGE"/> AudioRecordingPermission-你必须申请录音权限才能使用相机来录像. name="android.permission.RECORD_AUDIO"/> LocationPermission-当然如果你需要拍摄的照片记录地理位置,你同样需要申请如下权限 name="android.permission.ACCESS_FINE_LOCATION"/> 调用系统相机 你的应用可以通过发送一个Intent到系统相机应用来实现抓取一张照片或者一段视频剪辑,然后将它们返回给你的应用。 使用cameraintent调用系统相机流程如下: (1)ComposeaCameraIntent-创建一个Intent请求用来拍照或者录像,有关的Intent类型如下: MediaStore.ACTION_IMAGE_CAPTURE-该Intentaction类型用于请求系统相机拍照。 MediaStore.ACTION_VIDEO_CAPTURE-该Intentaction类型用于请求系统相机录像。 (2)StarttheCameraIntent-调用activity的startActivityForResult()方法来发送cameraintent请求拍照或者录像,当发送cameraintent以后,当前应用会跳转到系统相机应用app界面,让用户可以拍照或者录像。 (3)ReceivetheIntentResult-在你的应用中实现onActivityResult()回调方法去接收来自系统相机的拍摄结果。 该方法在用户完成拍照或者录像以后由系统调用。 系统拍照 代码如下,按上面的三步走: button1.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent,CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); } }); ... @Override protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ super.onActivityResult(requestCode,resultCode,data); /** *通过data取得数据 */ if(requestCode==CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE){ Bundleextras=data.getExtras(); Bitmapbitmap=(Bitmap)extras.get("data"); image.setImageBitmap(bitmap); } } 但是,现在手机像素这么高,万一图片特别大呢,会不会data过大而FC呢? 放心,Android早就考虑到了,所以,data里面压根就不是完整的图片,它只是一张缩略图。 所以,我们需要获取到拍摄的原图,就不能使用这种方法。 但是我们可以这样做,我们可以指定MediaStore类的一个EXTRA_OUTPUT来指定拍摄图像保存的位置,相当于建立一个临时文件。 在onActivityResult中,我们不使用data来获取图像,而是直接去读这个临时文件即可。 如果自己代码指定了保存图片的uri,data里面就不会保存数据。 button1.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE); UrifileUri=getOutputMediaFileUri(MEDIA_TYPE_IMAGE); intent.putExtra(MediaStore.EXTRA_OUTPUT,fileUri); startActivityForResult(intent,CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); } }); ... @Override protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ /** *通过存储Uri取得数据 */ if(requestCode==CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE){ if(resultCode==RESULT_OK){ image.setImageURI(getOutputMediaFileUri(MEDIA_TYPE_IMAGE)); } } } 这样我们就可以获取到完整的拍摄图片了。 后面你可以让图像显示出来。 下面来看看保存多媒体文件: 拍照或者录像生成的多媒体文件需要保存到手机存储目录中(SDCard),所以在应用中必须有往手机中写文件的权限。 一般可以有多种本地路径来保存多媒体文件,但是主要有如下两种常用的路径: Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) 该方法返回一个标准的外部存储路径去保存照片和视频。 这个路径是公共的,所以其他应用也可以访问,修改,删除该路径下的照片和视频,如果你的应用被卸载了,媒体文件依然存在本地储存中。 为了避免和其他多媒体文件混淆,你应该在公共目录下创建一个子目录来保存你自己应用中的多媒体数据。 Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) 该方法返回一个标准的,唯独当前应用自己可见的路径去保存照片和视频。 如果该应用被卸载,在该目录下的所有多媒体数据将会被移除。 但是有一个好处就是其他应用无法去访问,修改,删除该路径下的文件。 如下示例代码演示如何创建一个路径用来保存照片和视频: publicstaticfinalintMEDIA_TYPE_IMAGE=1; publicstaticfinalintMEDIA_TYPE_VIDEO=2; /**CreateafileUriforsavinganimageorvideo*/ privatestaticUrigetOutputMediaFileUri(inttype){ returnUri.fromFile(getOutputMediaFile(type)); } /**CreateaFileforsavinganimageorvideo*/ privatestaticFilegetOutputMediaFile(inttype){ FilemediaStorageDir=newFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"WatsonCamera"); if(! mediaStorageDir.exists()){ if(! mediaStorageDir.mkdirs()){ returnnull; } } FilemediaFile; if(type==MEDIA_TYPE_IMAGE){ mediaFile=newFile(mediaStorageDir.getPath()+File.separator+"IMG_watson.jpg"); }elseif(type==MEDIA_TYPE_VIDEO){ mediaFile=newFile(mediaStorageDir.getPath()+File.separator+"VID_watson.mp4"); }else{ returnnull; } returnmediaFile; } 系统录像 发送Intent录像携带的外部数据extra的信息如下: MediaStore.EXTRA_OUTPUT 该关键字和拍照使用的关键字一样,意思就是制定一个路径和文件名来构建一个Uri对象来保存录像结果。 MediaStore.EXTRA_VIDEO_QUALITY 该关键字用于指定拍摄的录像质量,参数0表示低质量,参数1表示高质量。 MediaStore.EXTRA_DURATION_LIMIT 该关键之用于指定拍摄的录像的时间限制,单位是秒。 MediaStore.EXTRA_SIZE_LIMIT 该关键字用于指定拍摄的录像文件大小限制,单位值byte。 代码如下,按上面的三步走: button2.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(MediaStore.ACTION_VIDEO_CAPTURE); UrifileUri=getOutputMediaFileUri(MEDIA_TYPE_VIDEO); intent.putExtra(MediaStore.EXTRA_OUTPUT,fileUri); intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,1); startActivityForResult(intent,CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); } }); ... @Override protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ if(requestCode==CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE){ if(resultCode==RESULT_OK){ image.setVisibility(View.VISIBLE); video.setVisibility(View.GONE); image.setImageURI(getOutputMediaFileUri(MEDIA_TYPE_IMAGE)); } }elseif(requestCode==CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE){ if(resultCode==RESULT_OK){ video.setVisibility(View.VISIBLE); image.setVisibility(View.GONE); video.setVideoURI(getOutputMediaFileUri(MEDIA_TYPE_VIDEO)); video.setOnPreparedListener(newMediaPlayer.OnPreparedListener(){ @Override publicvoidonPrepared(MediaPlayermp){ video.start(); } }); video.setOnCompletionListener(newMediaPlayer.OnCompletionListener(){ @Override publicvoidonCompletion(MediaPlayermp){ if(null! =video){ video.stopPlayback(); } } }); } } } 自定义相机 创建一个自定义的相机app基本遵循如下步骤: 检测和访问相机: 首先代码检测该设备相机是否存在,如果存在才能请求访问设备相机。 创建一个预览来显示相机图像: 在你的布局中使用SurfaceView控件,然后在代码中继承SurfaceHolder.Callback接口并且实现接口中的方法来显示来自相机的图像信息。 设置相机基本参数: 根据需求设置相机预览尺寸,图片大小,预览方向,图片方向等。 设置拍照录像监听: 当用户按下按钮时调用Camera.takePicture()或者MediaRecorder.start()来进行拍照或录像。 文件保存: 当拍照结束或者录像视频结束时,需要开启一个后台线程去保存图片或者视频文件。 释放相机资源: Camera硬件是一个共享资源,所以你必须小心的编写你的应用代码来管理相机资源。 一般在Activity的生命周期的onResume中开启相机,在onPause中释放相机。 注意: 当你不在使用相机资源时,记得调用Camera.release()方法来释放相机资源,否则其他应用甚至你自己的应用再次请求访问设备相机时会失败,并且crash。 检测相机硬件是否存在 一般情况,我们会在运行代码时检测该设备是否有相机硬件,如果有相机硬件,才进一步去访问相机,如下是检测相机硬件是否存在是代码示例: /**Checkifthisdevicehasacamera*/ privatebooleancheckCameraHardware(Contextcontext){ if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){ returntrue; }else{ returnfalse; } } Android设备可以有多个相机硬件,现在一般手机都是前后两个camera,因此我们在Android2.3以后也可以使用Camera.getNumberOfCameras()方法来获得当前设备camera个数来判断相机硬件是否存在。 创建Camera预览 Camera预览布局文件: xmlversion="1.0"encoding="utf-8"? > android=" android: layout_width="match_parent" android: layout_height="match_parent" android: orientation="vertical"> android: id="@+id/record_navigation_bar" android: layout_width="match_parent" android: layout_height="48dp" android: background="#F8F8F8"> android: id="@+id/record_act_back" android: layout_width="25dp" android: layout_height="31dp" android: layout_centerVertical="true" android: layout_marginLeft="10dp" android: layout_marginRight="10dp" android: src="@drawable/icon_ll_back"/> android: id="@+id/camera_preview" android: layout_width="match_parent" android: layout_height="fill_parent" android: layout_above="@+id/record_bottom_bar" android: layout_below="@+id/record_navigation_bar"/> android: id="@+id/record_bottom_bar" android: layout_width="match_parent" android: layout_height="60dp" android: layout_alignParentBottom="true" android: background="@drawable/recording_bottom_bar_bg_interview"> android: layout_width="wrap_content" android: layout_height="30dp" android: layout_alignParentRight="true" android: layout_below="@+id/record_navigation_bar" android: layout_marginRight="10dp" android: layout_marginTop="10dp" android: gravity="center_vertical"> android: id="@+id/record_video_tip" android: layout_width="15dp" android: layout_height="15dp" android: layout_marginRight="10dp" android: background="@drawable/record_video_tip"/> android: id="@+id/record_video_time" android: layout_width="wrap_content" android: layout_height="30dp" android: layout_marginRight="10dp" android: gravity="center_vertical" android: text="00: 00" android: textColor="@android: color/white" android: textSize="17sp"/> 然后,我们创建一个Activity,用来展示Camera的预览,那么在这个Activity里面,我们需要做什么呢? 两件事情: 初始化相机 将内容显示到SurfaceView Android的Camera是独享的,如果多处调用,就会抛出异常,所以,我们需要将Camera的生命周期与Sur
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android Camera开发一之基础知识 Camera 开发 基础知识