释放相机
想机是被设备上的应用们共享的资源.你的应用可以在获取相机实例后使用它,并且你的应用必须在用完后释放它,而且在暂停时(Activity.onPause())也要釋放它.如果你的应用没有适当的释放相机,所有后续试图获取相机使用权的操作,包括你自己的应用,都会失败并且导致那些应用关闭.
要释放一个相机对象实例,使用方法Camera.release(),如下代码所示:
public class CameraActivity extends Activity {
private Camera mCamera;
private SurfaceView mPreview;
private MediaRecorder mMediaRecorder;
...
@Override
protected void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
private void releaseMediaRecorder(){
if (mMediaRecorder != null) {
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
}
保存媒体文件
用户创建的媒体文件,比如图片或视频,应该被保存到设备的外部存储中(SD Card) ,这样可以保留系统空间并且使得用户可以不通过设备也能获取这些文件.一个设备上有很多可以存放媒体文件的路径位置,然而只有两个标准的路径对于开发者来说是必须考虑的:
· Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) - 此方法返回标准的,共享的,并且是推荐的存储位置.此路径是被共享的(公开的),所以其它应用可以轻松发现然后读取,修改以及删除此路径下的文件们.如果你的应用被用户卸载,保存在此路径下的文件将被删除.要避免与干涉已存在的图片或视频文件,你应该在路径下为你的应用创建一个子文件夹,如后面例子中所示.此方法从Android 2.2 (API Level 8)中开始可以使用,对于等价的早期API的调用,见"保存共享文件"一节.
· Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) - 此方法返回一个标准的存储图像和视频位置,并且此位置与你的应用会关联起来.如果你的应用被删除,所有此位置下的文件们都将被删除.此位置下的文件不会强制应用安全特性,所以其它应用可以读取,修改以及删除它们.
下面的代码示例演示了如何为一个媒体文件创建一个文件或Uri位置.这个文件可以在通过intent调用一个设备的相机或在创建一个相机应用时使用:
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** 创建一个文件Uri来存储一个图像或视频 */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** 创建一个文件用于存储图像或视频 */
private static File getOutputMediaFile(int type){
// 为了安全,你应该检查SDCard是否被mounted,
// 所以应先调用Environment.getExternalStorageState().
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
//如果你想创建图像并在应用之间共享,还想让你的图像在你的应用卸载后依然存在,
// 这个位置是最好的选择.
// 如果存储位置不存在,创建它.
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// 创建媒体文件的名字
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
注:Environment.getExternalStoragePublicDirectory()只能用于Android 2.2 (API Level 8)或更高版本中.如果你的目标设备使用早期版本,应用用Environment.getExternalStorageDirectory()代替.
相机特性 Features
Android支持大量的相机特性,你可以在你的应用中调节它们.比如图像格式,闪光模式,焦点设置,以及更多.本节列出常用的相机特性,并且简要说明如何使用它们.大多数相机特性可以使用Camera.Parameters 对象取得或设置.然而,有一些重要的特性需要比Camera.Parameters更复杂的方式进行设置,这些特性在以下各节中说明:
· 测光与聚焦区域
· 面部检测
· 定时拍摄视频
对于如何使用那些通过Camera.Parameters控制的一般特性,请见后面的"使用相机特性"一节.
表1. 各版API中引入的常用相机特性表
Feature | API Level | Description |
14 | 检测人脸位置并用结果来计算焦点,测光和白平衡 | |
14 | 在一个图像内指定一个或多个区域来计算白平衡 | |
14 | 在一个图像中设置一个或多个聚焦区域 | |
14 | 停止或开始自动白平衡调整 | |
14 | 停止或开始自动曝光调整 | |
14 | 在拍视频时抓取一个图像 | |
11 | 定时录像 | |
9 | 在一个设备上支持一个或多个相机,包括正面和反面的相机。 | |
9 | 焦距 | |
8 | 设置图像的放大率 | |
8 | 减小或增大曝光级别 | |
5 | 图像中包含或不包含地理位置信息 | |
5 | 设置白平衡的模式 | |
5 | 设置在一个物体上如何聚焦,比如自动,固定,微距,无限远. | |
5 | 场景模式,比如晚上,海滩,雪地或烛光. | |
5 | 设置JPEG图像的压缩级别. | |
5 | 设置闪光灯开,关或自动. | |
5 | 应用一个颜色效果到图像,比如黑白,褐色,反色. | |
5 | 减少在JPEG压缩时的颜色渐变的边缘效应. | |
1 | 指定图像的文件格式 | |
1 | 指定图像的宽和高 |
注: 这些特性并不是在所有的设备上都被支持,因为硬件的差别和软件的实现各有不同.