1、Android Camera开发一之基础知识Android Camera开发(一)之基础知识概述Android手机关于Camera的使用,一是拍照,二是摄像,由于Android提供了强大的组件功能,为此对于在Android手机系统上进行Camera的开发,我们可以使用两类方法:一是借助Intent和MediaStore调用系统Camera App程序来实现拍照和摄像功能,二是根据Camera API自写Camera程序。基础知识Android系统提供API来支持自定义相机拍照和系统拍照,以下是有关的类:Camera 该类提供基础API来使用设备上的相机,且该类可以为你的应用提供拍照和录像相关的
2、API。SurfaceView 该类用于显示相机的预览数据。如果你对SurfaceView还不熟悉,请参考Android SurfaceView的使用这篇文章。MediaRecorder 该类提供相机录像相关的API。注意事项在你的应用程序能够在Android设备上使用相机之前,你应该考虑几个问题,那就是你的App打算如何使用相机拍照或者录像?Camera需求的声明: 使用相机功能对于你的应用程序来说是否很重要并且你不希望你的应用程序被安装在没有相机的机器上?如果是这样,那么你需要把相机需求声明在配置文件里。调用系统拍照还是自定义相机: 你的应用程序该如何使用相机?你是否仅仅需要拍摄一张照片或
3、者一个视频,或者你的应用程序希望提供一种使用相机的新的方式?存储: 是否你的应用生成的图片和视频仅对你的应用可见,还是其他应用程序例如相册或者其他的多媒体和社交App也可以使用它们?你是否希望你的应用程序被卸载后,这些照片和视频仍然可用,还是一起被删除?权限申明Camera Permission - 你的应用必须申请相机权限才可以使用设备相机。注意:如果你使用Intent调用系统相机,你的应用无需申请该权限。Storage Permission - 如果你的应用需要保存照片或者视频到设备存储中,你必须在Manifest指定文件的写权限Audio Recording Permission - 你
4、必须申请录音权限才能使用相机来录像.Location Permission - 当然如果你需要拍摄的照片记录地理位置,你同样需要申请如下权限调用系统相机你的应用可以通过发送一个Intent 到系统相机应用来实现抓取一张照片或者一段视频剪辑,然后将它们返回给你的应用。 使用camera intent调用系统相机流程如下: (1)Compose a Camera Intent - 创建一个Intent请求用来拍照或者录像,有关的Intent类型如下:MediaStore.ACTION_IMAGE_CAPTURE - 该Intent action 类型用于请求系统相机拍照。MediaStore.AC
5、TION_VIDEO_CAPTURE - 该Intent action 类型用于请求系统相机录像。(2)Start the Camera Intent - 调用activity的startActivityForResult()方法来发送camera intent请求拍照或者录像,当发送camera intent 以后,当前应用会跳转到系统相机应用app界面,让用户可以拍照或者录像。 (3)Receive the Intent Result - 在你的应用中实现onActivityResult()回调方法去接收来自系统相机的拍摄结果。该方法在用户完成拍照或者录像以后由系统调用。系统拍照代码如下,
6、按上面的三步走:button1.setOnClickListener(new View.OnClickListener() Override public void onClick(View v) Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); );.Override protected void onActivityResult(int requestCode, int result
7、Code, Intent data) super.onActivityResult(requestCode, resultCode, data); /* * 通过data取得数据 */ if (requestCode = CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) Bundle extras = data.getExtras(); Bitmap bitmap = (Bitmap) extras.get(data); image.setImageBitmap(bitmap); 但是,现在手机像素这么高,万一图片特别大呢,会不会data过大而FC呢?放心,Androi
8、d早就考虑到了,所以,data里面压根就不是完整的图片,它只是一张缩略图。所以,我们需要获取到拍摄的原图,就不能使用这种方法。但是我们可以这样做,我们可以指定MediaStore类的一个EXTRA_OUTPUT来指定拍摄图像保存的位置,相当于建立一个临时文件。在onActivityResult中,我们不使用data来获取图像,而是直接去读这个临时文件即可。如果自己代码指定了保存图片的uri,data里面就不会保存数据。button1.setOnClickListener(new View.OnClickListener() Override public void onClick(View v
9、) Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Uri fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); );. Override protected void onActivityResult(int requestCode,
10、int resultCode, Intent data) /* * 通过存储Uri取得数据 */ if (requestCode = CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) if (resultCode = RESULT_OK) image.setImageURI(getOutputMediaFileUri(MEDIA_TYPE_IMAGE); 这样我们就可以获取到完整的拍摄图片了。后面你可以让图像显示出来。下面来看看保存多媒体文件: 拍照或者录像生成的多媒体文件需要保存到手机存储目录中(SD Card),所以在应用中必须有往手机中写文件的权限。一般可以有多种
11、本地路径来保存多媒体文件,但是主要有如下两种常用的路径:Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) 该方法返回一个标准的外部存储路径去保存照片和视频。这个路径是公共的,所以其他应用也可以访问,修改,删除该路径下的照片和视频,如果你的应用被卸载了,媒体文件依然存在本地储存中。为了避免和其他多媒体文件混淆,你应该在公共目录下创建一个子目录来保存你自己应用中的多媒体数据。Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
12、该方法返回一个标准的,唯独当前应用自己可见的路径去保存照片和视频。如果该应用被卸载,在该目录下的所有多媒体数据将会被移除。但是有一个好处就是其他应用无法去访问,修改,删除该路径下的文件。如下示例代码演示如何创建一个路径用来保存照片和视频: public static final int MEDIA_TYPE_IMAGE = 1; public static final int MEDIA_TYPE_VIDEO = 2; /* Create a file Uri for saving an image or video */ private static Uri getOutputMediaFi
13、leUri(int type) return Uri.fromFile(getOutputMediaFile(type); /* Create a File for saving an image or video */ private static File getOutputMediaFile(int type) File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), WatsonCamera); if (! mediaSto
14、rageDir.exists() if (! mediaStorageDir.mkdirs() return null; File mediaFile; if (type = MEDIA_TYPE_IMAGE) mediaFile = new File(mediaStorageDir.getPath() + File.separator + IMG_watson.jpg); else if(type = MEDIA_TYPE_VIDEO) mediaFile = new File(mediaStorageDir.getPath() + File.separator + VID_watson.m
15、p4); else return null; return mediaFile; 系统录像发送Intent录像携带的外部数据extra的信息如下:MediaStore.EXTRA_OUTPUT 该关键字和拍照使用的关键字一样,意思就是制定一个路径和文件名来构建一个Uri对象来保存录像结果。MediaStore.EXTRA_VIDEO_QUALITY 该关键字用于指定拍摄的录像质量,参数0表示低质量,参数1表示高质量。MediaStore.EXTRA_DURATION_LIMIT 该关键之用于指定拍摄的录像的时间限制,单位是秒。MediaStore.EXTRA_SIZE_LIMIT 该关键字用于
16、指定拍摄的录像文件大小限制,单位值byte。代码如下,按上面的三步走:button2.setOnClickListener(new View.OnClickListener() Override public void onClick(View v) Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); Uri fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); intent.
17、putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); );.Override protected void onActivityResult(int requestCode, int resultCode, Intent data) if (requestCode = CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) if (resultCode = RESULT_OK) image.setVisi
18、bility(View.VISIBLE); video.setVisibility(View.GONE); image.setImageURI(getOutputMediaFileUri(MEDIA_TYPE_IMAGE); else if (requestCode = CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) if (resultCode = RESULT_OK) video.setVisibility(View.VISIBLE); image.setVisibility(View.GONE); video.setVideoURI(getOutputMedia
19、FileUri(MEDIA_TYPE_VIDEO); video.setOnPreparedListener(new MediaPlayer.OnPreparedListener() Override public void onPrepared(MediaPlayer mp) video.start(); ); video.setOnCompletionListener(new MediaPlayer.OnCompletionListener() Override public void onCompletion(MediaPlayer mp) if (null != video) vide
20、o.stopPlayback(); ); 自定义相机创建一个自定义的相机app基本遵循如下步骤:检测和访问相机: 首先代码检测该设备相机是否存在,如果存在才能请求访问设备相机。创建一个预览来显示相机图像: 在你的布局中使用SurfaceView控件,然后在代码中继承SurfaceHolder.Callback接口并且实现接口中的方法来显示来自相机的图像信息。设置相机基本参数: 根据需求设置相机预览尺寸,图片大小,预览方向,图片方向等。设置拍照录像监听: 当用户按下按钮时调用Camera.takePicture()或者MediaRecorder.start()来进行拍照或录像。文件保存: 当拍照
21、结束或者录像视频结束时,需要开启一个后台线程去保存图片或者视频文件。释放相机资源: Camera硬件是一个共享资源,所以你必须小心的编写你的应用代码来管理相机资源。一般在Activity的生命周期的onResume中开启相机,在onPause中释放相机。注意: 当你不在使用相机资源时,记得调用Camera.release()方法来释放相机资源,否则其他应用甚至你自己的应用再次请求访问设备相机时会失败,并且crash。检测相机硬件是否存在一般情况,我们会在运行代码时检测该设备是否有相机硬件,如果有相机硬件,才进一步去访问相机,如下是检测相机硬件是否存在是代码示例:/* Check if this
22、 device has a camera */private boolean checkCameraHardware(Context context) if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA) return true; else return false; Android 设备可以有多个相机硬件,现在一般手机都是前后两个camera,因此我们在Android2.3以后也可以使用Camera.getNumberOfCameras()方法来获得当前设备camera个数来判断相机硬件是否存在。创建Camera预览Camera预览布局文件: 然后,我们创建一个Activity,用来展示Camera的预览,那么在这个Activity里面,我们需要做什么呢?两件事情:初始化相机将内容显示到SurfaceViewAndroid的Camera是独享的,如果多处调用,就会抛出异常,所以,我们需要将Camera的生命周期与Sur
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1