1、自定义一个SurfaceView
package com.test.camera.preview;
import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera.CameraInfo;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.test.camera.CameraInterface;
import com.test.observer.FrameCallback;
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
Context mContext;
SurfaceHolder mSurfaceHolder;
public CameraSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mSurfaceHolder = getHolder();
mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);//translucent半透明 transparent透明
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSurfaceHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
CameraInterface.getInstance().doOpenCamera(null, CameraInfo.CAMERA_FACING_BACK);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
CameraInterface.getInstance().doStartPreview(mSurfaceHolder, 1.333f);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
CameraInterface.getInstance().doStopCamera();
}
public SurfaceHolder getSurfaceHolder() {
return mSurfaceHolder;
}
public void setFrameCallback(FrameCallback fcb) {
CameraInterface.getInstance().setFrameCallback(fcb);
}
}
2、封装一个CameraInterface类来操作Camera的打开、预览、获取数据等
package com.test.camera;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.view.SurfaceHolder;
import com.test.observer.FrameCallback;
import java.io.IOException;
public class CameraInterface {
private Camera mCamera;
private Camera.Parameters mParams;
private boolean isPreviewing = false;
private static CameraInterface mCameraInterface;
private FrameCallback fcb;
private int mCameraId = -1;
public void setFrameCallback(FrameCallback fcb) {
this.fcb = fcb;
}
public interface CamOpenOverCallback {
void cameraHasOpened();
}
private CameraInterface() {
}
public static synchronized CameraInterface getInstance() {
if (mCameraInterface == null) {
mCameraInterface = new CameraInterface();
}
return mCameraInterface;
}
/**
* 打开Camera
*
* @param callback
*/
public void doOpenCamera(CamOpenOverCallback callback, int cameraId) {
mCamera = Camera.open(cameraId);//0后置 1前置
if (callback != null) {
callback.cameraHasOpened();
}
}
/**
* 开启预览
*
* @param holder
* @param previewRate
*/
public void doStartPreview(SurfaceHolder holder, float previewRate) {
if (isPreviewing) {
mCamera.stopPreview();
return;
}
if (mCamera != null) {
mParams = mCamera.getParameters();
mCamera.setParameters(mParams);
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();//开启预览
} catch (IOException e) {
e.printStackTrace();
}
isPreviewing = true;
mParams = mCamera.getParameters(); //重新get一次
mCamera.setPreviewCallback(mJpegPreviewCallback);
}
}
/**
* 停止预览,释放Camera
*/
public void doStopCamera() {
if (null != mCamera) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
isPreviewing = false;
mCamera.release();
mCamera = null;
}
}
/**
* 获取Camera的数据,
*/
PreviewCallback mJpegPreviewCallback = new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
//传递进来的data,默认是YUV420SP的
fcb.onDecodeFrame(data);
}
};
/**
* 获取Camera.Parameters
*
* @return
*/
public Camera.Parameters getCameraParams() {
if (mCamera != null) {
mParams = mCamera.getParameters();
return mParams;
}
return null;
}
/**
* 获取Camera实例
*
* @return
*/
public Camera getCameraDevice() {
return mCamera;
}
public int getCameraId() {
return mCameraId;
}
}
4、在xml中用写好的自定义SurfaceView
<com.test.camera.preview.CameraSurfaceView
android:id="@+id/surfaceview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
5、添加照相机的相关权限
<!-- 增加文件存储和访问摄像头的权限 -->
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-feature android:glEsVersion="0x00020000"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
6、至此就可以正常显示预览视频啦