本文译自:http://developer.android.com/guide/topics/media/camera.html
Android框架包含了对各种Camera以及其上可用的Camera功能的支持,它允许你在应用程序中抓拍照片和视频。本文讨论快速而简单的拍摄照片和视频的方法,并概要的介绍一个让用户创建定制Camera体验的高级方法。
注意事项
在开启应用程序使用Android设备上的Camera功能之前,要考虑一些打算如何使用这些硬件功能的问题:
1. Camera需求:要考虑应用程序是否必须要运行在有Camera的设备上,如果必须,就要在应用程序的清单中声明Camera需求;
2. 快照或定制Camera:应用程序准备如何使用Camera?是只对抓拍或视频剪辑感兴趣?还是要应用程序提供使用Camera的新方法?对于抓拍或剪辑,要考虑使用既存的Camera应用程序。对于开发定制化的Camera功能,请看下文的“构建Camera应用程序”
3. 存储:图片或视频是只打算让本应用程序可见,还是要共享给其他应用程序使用,如相册或其他媒体和社区应用程序?是否想要这些图片和视频在应用被卸载后还可用?请看下文的“保存媒体文件”是如何解决这些问题的。
基础
Android框架通过Camera API或Camera Intent来支持拍照和录像,以下是相关的类:
Camera
这个类是控制设备Camera的主API。在构建一个Camera应用程序时,它被用于拍照或录像。
SurfaceView
这个类用于向用户实时的展现Camera的预览。
MediaRecorder
这个类用于记录来自Camera的视频
Intent
MediaStore.ACTION_IMAGE_CAPTURE或MediaStore.ACTION_VIDEO_CAPTURE类型的Intent动作被用于不直接使用Camera对象来拍照或录像。
清单声明
在开始使用Camera API开发应用程序之前,要确保清单文件已经有了适当的声明,以允许使用Camera硬件和其他相关的功能。
1. Camera权限:应用程序必须申请使用设备Camera的权限。
<uses-permissionandroid:name="android.permission.CAMERA"/>
注意:如果通过Intent来使用Camera,应用程序就不需要申请这个权限。
2. Camera功能:应用程序还必须要声明打算使用的Camera功能,例如:
<uses-featureandroid:name="android.hardware.camera"/>
把Camera功能添加到应用程序的清单中,会让Google Play防止把程序安装到不包含Camera或不支持你所需要的Camera功能的设备上。关于如何使用基于功能过滤的Google Play,请看Google Play和基于功能的过滤
如果应用程序能够使用Camera或正确的操作Camera功能,但却不需要它,那么就应该在清单中指定android:required属性,并把属性值设置为false:
<uses-feature android:name="android.hardware.camera" android:required="false" />
3. 存储权限:如果应用程序要把图片或视频保存到设备的外部存储器上(如SD卡),就必须在清单中指定这个权限:
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4. 音频录音权限:对于视频采集的音频录音,应用程序必须要申请音频采集权限:
<uses-permissionandroid:name="android.permission.RECORD_AUDIO"/>
5. 位置定位权限:如果应用程序要给图片标记GPS位置信息,就必须申请位置定位权限:
<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
关于获得用户位置的更多信息,请看“定位策略”
使用既存的Camera应用
在应用程序中不需要太多的额外代码就可以快速的开启拍照或录像的方法是:使用Intent来调用一个既存的Android Camera应用程序。一个Camera Intent能够通过既存的Camera应用程序和它返回给应用程序的播放控制来申请采集一张照片或一段视频。本节会向你展示如何使用这项技术来采集一张图片或一段视频。
调用Camera Intent的过程会遵循以下这些大概的步骤:
1. 编写一个Camera Intent:创建一个申请图片或视频的Intent对象,使用以下Intent类型之一:
MediaStore.ACTION_IMAGE_CAPTURE:从一个既存的Camera应用中申请图片功能的Intent动作类型;
MediaStore.ACTION_VIDEO_CAPTURE:从一个既存的Camera应用中申请视频功能的Intent动作类型。
2. 启动Camera的Intent:使用startActivityForResult()方法来执行Camera的Intent。Intent启动后,该Camera应用程序的用户界面会显示在屏幕上,并且用户能够拍照或录像;
3. 接收Intent的结果:在你的应用程序中建立一个onActivityResult()方法来接收来自Camera Intent的回调和数据。当用户完成成拍照或录像(或者是取消操作),系统会调用这个方法。
图像采集Intent
使用Camera Intent来采集图像是你的应用程序用最少的代码来拍照的快捷方式。一个图片采集Intent能够包含以下额外的信息:
MediaStore.EXTRA_OUTPUT:这个设置需要一个指定了保存图片路径和文件名的Uri对象。这个设置是可选,但强烈推荐使用。如果不指定这个值,Camera应用程序会用默认的名称把采集到的图片保存到默认的位置,这些默认值在Intent.getData()方法的返回字段中指定。
以下示例演示了如何构建一个图片采集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);
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
startActivityResult()方法执行完成后,用户就会看到Camera应用程序的界面。用户完成拍照(或取消操作)之后,用户界面就会返回到你的应用程序中,并且你必须监听onActivityResult()方法来接收Intent的结果,并继续你的应用程序的执行。
视频采集Intent
使用Camera Intent采集视频是让你的应用程序能够用最少的代码来录像的一中快捷方式。视频采集Intent能够包含以下额外信息:
MediaStore.EXTRA_OUTPUT:这个设置要求用一个URI来指定保存视频的路径和文件名。虽然它是可选的,但强烈推荐使用这个设置。如果没有指定这个设置,那么Camera应用程序会把采集到的视频用默认的名称保存到默认的位置,默认的设置是在Intent的Intent.getData()方法域中返回的。
MediaStore.EXTRA_VIDEO_QUALITY:这个值的范围是0~1,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()方法被执行时,用户就会看到一个可编辑的Camera应用程序界面。在用户完成录像(或取消操作)之后,该用户界面就会返回到你的应用程序中,并且你必须监听onActivityResult()方法来接收Intent的结果,并继续执行你的应用程序。
接收Camera Intent结果
一旦你构建并执行了一个图片或视频的Camera Intent,那么就必须要配置你应用程序来接收Intent的结果。本节向你展示了如何监听来自Camera Intent的回调,以便应用程序能够对采集到的图片或视频做进一步的处理。
为了接收Intent的结果,必须在启动Intent的那个Activity中重写onActivityResult()方法。下面的示例演示了如何重写onActivityResult()方法来采集图片Camera Intent或视频Camera Intent的返回结果:
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Image saved to:\n" +
data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Video captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Video saved to:\n" +
data.getData(), Toast.LENGTH_LONG).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the video capture
} else {
// Video capture failed, advise user
}
}
}
一旦Activity接收到一个成功的结果,那么你的应用程序就可以访问指定位置中的被采集的图片或视频。