android 多媒体和相机详解五
相机
Android框架架包含了各种相机和相机功能的支持,使你可以在你的应用中捕获图像和视频.本文档讨论一个简单快速的获取图像和视频的方法,并概述一个创建自定义用户相机体验的高级方法.
想一想
在使你的应用能使用设备上的相机之前,你应该先想一想你的应用将来会如何使用此硬件.
-
Camera 必须-相机是必须的,你不希望你的应用安装到一个没有相机的设备上.你应该在manifest文件中声明需要相机.
-
快速图像或自定义特性-你的应用将如何使用相机?你仅仅是抓取一个快速图片或视频剪辑,还是提供一个新的使用方式?前者请考虑使用现有的相机应用.后者请阅读后面的"创建一个相机应用"一节.
-
存储 -你的应用产生的图像和视频要给自己看还是共享给其它应用?你想在你的应用被删除后所创建的图像和视频仍然存在吗?请阅读后面的"保存媒体文件"一节来学习如何实现这些操作.
基础知识
Android框架支持通过CameraAPI或Cemeraintent来抓取图像和视频.下面就是相关的类们:
-
Camera
此类是控制设备相机的主要API.此类用于在创建相机应用时获取图片和视频.
-
SurfaceView
此类为用户提供camera的实时图像预览.
-
MediaRecorder
此类用于从camera录制视频.
-
Intent
一个MediaStore.ACTION_IMAGE_CAPTURE或MediaStore.ACTION_VIDEO_CAPTURE型的intent,可以使用它来抓取图像或视频,而不用操作Camera对象们.
Manifest中的声明
在使用CameraAPI开发你的应用之前,你需保证在你的manifest中声明了合适的条目使得有权使用相机和其它相关特性.
-
CameraPermission - 你的应用必须请求使用设备相机的取限.
<uses-permissionandroid:name="android.permission.CAMERA" />
注:如果你通intent使用camera,你的应用不必请求此权限.
-
CameraFeatures - 你的应用必须也要声明要使用的相机特性,比如:
<uses-featureandroid:name="android.hardware.camera" />
对于相机特性列表,请见manifestFeatures Reference.
添加相机特性到你的manifest导致Android市场不会将你的应用安装到没有相机相机特性达不到你所声明要求的设备上.
如果你的应用要使用相机或相机的一些特性,但又不是必须的,你应该在manifest中指定这些需求,但把android:required属性置为false:
<uses-featureandroid:name="android.hardware.camera"android:required="false" />
-
StoragePermission - 如果你的应用要存储图像或视频到外部存储上(SD卡),你必须也声明此权限.
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
AudioRecording Permission - 在使用视频捕获设备来录制音频时,你的应用必须请求音频捕获权限.
<uses-permissionandroid:name="android.permission.RECORD_AUDIO" />
使用现有的相机应用
一个不用写代码来获取图片和视频的快速方法是使用intent来调用现有的Androidcamera 应用.一个cameraintent调用现存的相机应用抓取图片或视频剪辑然后返回的你的应用.本节向你演示如何使用此技术获取图片和视频.
调用一个相机intent,主要有以下步骤:
-
组建一个相机 Intent– 创建一个请求图片或视频的Intent,使用以下intent类型中的一个:
-
MediaStore.ACTION_IMAGE_CAPTURE- 从已存在的相机应用中请求一个图片.
-
MediaStore.ACTION_VIDEO_CAPTURE- 从已存在的相机应用中请求一个视频.
-
-
启动这个相机 Intent-使用startActivityForResult()方法来执行相机intent.在你启动intent后,相机应用的界面会出现在设备屏幕上,然后用户就可以用它来获取图片或视频.
-
接收 Intent 结果-在你的应用中设置一个onActivityResult()方法来接收从相机intent来的回调和数据.当用户获取了一个图或视频之后(或取消了操作),系统就会调用此方法.
图像获取intent
使用相机intent获取图像是使用最少代码获取图像的捷迳.一个图像获取intent包含以下额外信息:
-
MediaStore.EXTRA_OUTPUT-此设置需要一个Uri对象,这个对象指定了一个保存图像的路径和文件名.此设置是可选的,但是强烈建议使用之.如果你没有指定此值,相机应用就会把图像以默认的名字保存到默认的位置.
下面的例子演示了形成一个图像获取intent并执行的方法.此例子中的getOutputMediaFileUri()方法是引用的”保存媒体文件”一节中的例子代码.
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100; private Uri fileUri; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 创建一个获取图像的Intent Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // 创建一个文件来保存图像 intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // 设置图像文件名 // 开始图像获取Intent startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); }
当startActivityForResult()方法被执行,看到一个相机应用的界面.当用户获取了一个图像(或取消了操作),用户界面返回到你的应用,你必须拦截onActivityResult()方法来接收intent的结果然后再继续执行你的应用.
视频获取intent
使用相机intent获取视频是使用最少代码使得你的应用获取视频的捷径.一个视频获取intent可以包含以下额外信息:
-
MediaStore.EXTRA_OUTPUT-此设置需要一个保存视频的路径和文件名的Uri.此设置是可选的但是强列推荐的.如果你不指定此值,相机应用就把请求到的图像以默认的文件名保存到默认的文件夹下,这些信息保存在返回的intent的Intent.getData()字段中.
-
MediaStore.EXTRA_VIDEO_QUALITY- 此值在最低质量最小文件尺寸时是0,在最高质量最大文件尺寸时是1.
-
MediaStore.EXTRA_DURATION_LIMIT- 此值设置获取视频的长度,以秒为单位.
-
MediaStore.EXTRA_SIZE_LIMIT- 此值设置获取视频文件的大小,以字节为单位.
下面的例子演示了如何构建一个视频获取intent并执行它.此例子中的getOutputMediaFileUri()方法是引用的”保存媒体文件”一节中的例子代码.
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200; private Uri fileUri; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //create new Intent Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high // start the Video Capture Intent startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); }
当startActivityForResult()方法执行后,用户看到了一个改良的相机应用界面.在用户完成视频获取(或取消了操作)之后,用户界面返回到你的应用,你必须拦截onActivityResult()方法来接收intent的结果并且继续执行你的应用.