demo比较简单,直接上代码:
Activity
public class MainActivity extends AppCompatActivity {
SurfaceView sView;
SurfaceHolder surfaceHodler;
int screenWidth, screenHeight;
// 定义系统所用的照相机
Camera camera;
// 是否存在预览中
boolean isPreview = false;
private String filepath = "";//照片保存路径
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取窗口管理器
WindowManager wm = getWindowManager();
Display display = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
// 获取屏幕的宽和高
display.getMetrics(metrics);
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
sView = (SurfaceView) findViewById(R.id.sView);
// 设置surface不需要自己的维护缓存区
sView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// 获得SurfaceView的SurfaceHolder
surfaceHodler = sView.getHolder();
// 为srfaceHolder添加一个回调监听器
surfaceHodler.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// 如果camera不为null,释放摄像头
System.out.println("释放摄像头");
if (camera != null) {
if (isPreview)
camera.stopPreview();
camera.release();
camera = null;
isPreview = false;
}
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
System.out.println("打开摄像头");
// 打开摄像头
initCamera();
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
System.out.println("摄像头改变");
}
});
}
public void capture(View source) {
sView.setVisibility(View.VISIBLE);
}
private void initCamera() {
if (!isPreview) {
// 此处默认打开后置摄像头
// 通过传入参数可以打开前置摄像头
camera = openFrontFacingCameraGingerbread();
}
if (!isPreview && camera != null) {
Camera.Parameters parameters = camera.getParameters();
// 设置预览照片的大小
parameters.setPreviewSize(screenWidth, screenHeight);
// 设置预览照片时每秒显示多少帧的最小值和最大值
parameters.setPreviewFpsRange(4, 10);
// 设置照片的格式
parameters.setPictureFormat(ImageFormat.JPEG);
parameters.setPreviewSize(800, 480);//图片大小
// 设置JPG照片的质量
parameters.set("jpeg-quality", 100);
// 设置照片的大小
parameters.setPictureSize(screenWidth, screenHeight);
// 通过SurfaceView显示取景画面
try {
camera.setPreviewDisplay(surfaceHodler);
// 系统相机默认是横屏的,我们要旋转90°
camera.setDisplayOrientation(90);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 开始预览
camera.startPreview();
isPreview = true;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (camera != null) {
System.out.println("控制摄像头自动对焦后才拍摄");
// 控制摄像头自动对焦后才拍摄
//camera.autoFocus(autoFocusCallback);
//关闭声音
setCameraSound(true);
camera.takePicture(new Camera.ShutterCallback() {
@Override
public void onShutter() {
// 按下快门瞬间会执行此处代码
}
}, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// 此处代码可以决定是否需要保存原始照片信息
}
}, jpeg);
}
}
}, 1000);
}
}
private Camera openFrontFacingCameraGingerbread() {
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
System.out.println("cameraCount = "+cameraCount);
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
cam = Camera.open(camIdx);
} catch (RuntimeException e) {
Log.e("", "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
System.out.println("获取摄像头");
if (cam == null)
System.out.println("摄像头获取失败");
return cam;
}
Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean arg0, Camera arg1) {
if (arg0) {
//关闭声音
setCameraSound(true);
// takePicture()方法需要传入三个监听参数
// 第一个监听器;当用户按下快门时激发该监听器
// 第二个监听器;当相机获取原始照片时激发该监听器
// 第三个监听器;当相机获取JPG照片时激发该监听器
System.out.println("拍照");
camera.takePicture(new Camera.ShutterCallback() {
@Override
public void onShutter() {
// 按下快门瞬间会执行此处代码
}
}, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// 此处代码可以决定是否需要保存原始照片信息
}
}, jpeg);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// sView.setVisibility(View.GONE);
//
}
}, 1000);
} else {
System.out.println("对焦失败,不拍照");
}
}
};
//创建jpeg图片回调数据对象
Camera.PictureCallback jpeg = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
// 创建一个位于SD卡上的文件
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "aaa");
if (!file.exists()) {
file.mkdir();
}
file = new File(file, System.currentTimeMillis() + ".jpg");
FileOutputStream fileOutStream = null;
try {
fileOutStream = new FileOutputStream(file);
//把位图输出到指定的文件中
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutStream);
fileOutStream.close();
} catch (IOException io) {
io.printStackTrace();
}
camera.stopPreview();//关闭预览 处理数据
camera.startPreview();//数据处理完后继续开始预览
bitmap.recycle();//回收bitmap空间
isPreview = true;
//关闭预览框,回复声音
sView.setVisibility(View.GONE);
setCameraSound(false);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private void setCameraSound(final boolean isSound) {
new Thread(
new Runnable() {
@Override
public void run() {
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamMute(AudioManager.STREAM_SYSTEM, isSound);
}
}
).start();
}
}
XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.jin.activity.MainActivity">
<SurfaceView
android:id="@+id/sView"
android:layout_width="80dp"
android:layout_height="100dp"
android:layout_alignParentRight="true"
android:visibility="gone">SurfaceView>
<Button
android:id="@+id/take"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:onClick="capture"
android:text="开门">Button>
RelativeLayout>
注:
经过测试发现7.0以下手机没问题,而7.0系统手机在Camera.open()出现Camera failed to open: Fail to connect to camera service,就是获取不到相机服务无法打开相机,需要手动在手机设置里面打开相机权限,即可正常使用。因此可以加一个判断:
//判断系统版本大于23,即24(7.0)和以上版本提示打开权限
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
}