一、调用系统照相机和摄像机功能
调用系统摄像头进行拍照和摄像是通过隐式启动系统Activity 实现的,无需给自己的工程添加权限,直接调用即可。因此我们只需知道系统照相机和摄像机Activity 的action 和category 就可以了
步骤
1、打开Android 源码,查看”\packages\apps\”文件文件目录下的Camera 应用,即系统摄像头的应用程序。打开其清单文件文件,查看其Activity 的action 和category 信息
2、Camera 类的action 和category 如下
照相机的意图过滤器
<intent-filter>
<action android:name="android.media.action.IMAGE_CAPTURE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
摄像机的意图过滤器
<intent-filter>
<action android:name="android.media.action.VIDEO_CAMERA" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
3、采用隐式调用的方式调用Activity
由于希望在调用拍照或摄像功能后将结果返回到当前应用的Activity,所以在开启Activity 时不能使用startActivity 方法,而是使用startActivityForResult 方法开启Activity,并重写onActivityResult 方法处理回传的数据
布局文件比较简单,界面只有两个按钮,一个用于打开照相机,一个用于打开摄像机。这里只给出核心代码清单
拍照功能核心代码
public void take(View view){
//创建一个Intent 对象
Intent intent = new Intent();
//设置Action
intent.setAction("android.media.action.IMAGE_CAPTURE");
//创建一个文件
File file = new
File(Environment.getExternalStorageDirectory().getAbsolutePath(),"my.jpg");
//创建uri 对象
Uri uri = Uri.fromFile(file);
//设置图片的输出路径
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
//开启Activity
startActivityForResult(intent, 100);
}
摄像功能核心代码
public void video(View view){
Intent intent = new Intent();
intent.setAction("android.media.action.VIDEO_CAPTURE");
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath(),"myVedio.mp4");
Uri uri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, 101);
}
二、编码实现照相功能
使用Camera+SurfaceView 控件可实现自定义照相机功能。接下来我将具体的步骤展示出来
1、编写布局文件,该布局只有一个SurfaceView 控件和一个Button 作为拍照按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http:///apk/res/android"
xmlns:tools="http:///tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<SurfaceView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="takeImage"
android:text="拍照"/>
</LinearLayout>
2、在清单文件中添加2 个权限信息
添加第一个权限是因为我们代码使用到系统照相机,第二个是因为我们需要把照好的相片保存到sdcard 上
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//声明成员变量
private Camera camera;//照相机对象
private SurfaceHolder holder;//SurfaceView 的辅助类
//获取SurfaceView 控件的实例,通过其辅助类SurfaceHolder 对象添加CallBack 接口的实现
//获取预览画面的SurfaceView 控件
SurfaceView surfaceView = (SurfaceView) findViewById();
//得到预览画面的辅助类
holder = surfaceView.getHolder();
//添加回调方法
holder.addCallback(new Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
//打开摄像头
camera = Camera.open();
//设置预览显示的位置
camera.setPreviewDisplay(holder);
//开启预览
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//停止预览界面
camera.stopPreview();
//释放摄像头
camera.release();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
//添加点击拍照按钮的点击事件:设置摄像头自动对焦,对焦完成后保存图片并重新预览
//拍照
public void takeImage(View view) {
if (camera == null) {
Toast.makeText(this, "照相机还没打开。", Toast.LENGTH_SHORT).show();
return;
}
//点击拍照按钮,摄像头自动对焦,对焦完成后拍照并保存
camera.autoFocus(new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
//对焦完成,拍照并保存
camera.takePicture(null, null, new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//设置照片保存路径
String path =
Environment.getExternalStorageDirectory().getAbsolutePath() + "/" +
UUID.randomUUID().toString() + ".jpg";
try {
FileOutputStream outputStream = new FileOutputStream(path);
//将照片字节数组写到文件中
outputStream.write(data);
outputStream.close();
//重新开启预览
camera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
}
三、总结
Camera
方法 | 说明 |
open() | 打开摄像头 |
release() | 释放摄像头 |
setPreviewDisplay() | 设置预览显示的位置 |
startPreview() | 开启预览 |
stopPreview() | 停止预览界面 |
autoFocus() | AutoFocusCallback |
takePicture() | 对焦完成 |