简介

因工作原因要学习Android的Camera预览功能,这个DEMO有两个Activity,使用Camera库实现

Android Camera预览_第1张图片Android Camera预览_第2张图片

项目地址https://github.com/haowenlai2008/CameraPreview
代码参考了这个老哥https://dotblogs.com.tw/alonstar/2011/06/08/android_camera

Camera预览使用SurfaceView和Camera类,让它们两个联系起来并开启预览的比较关键的代码:

mCamera.setPreviewDisplay(mSurfaceHolder);mCamera.startPreview();

其实就是这两行,把SurfaceView的holder设置到Camera上,开启预览就OK了

最关键的两个工作

  1. 设置SurfaceView的回调
private void initView() {        surfaceView = findViewById(R.id.surfaceView);        mSurfaceHolder = surfaceView.getHolder();        mSurfaceHolder.addCallback(this);    }

让当前Activity实现Surface.Callback接口,让mSurfaceHolder绑定当前Activity作为回调

    @Override    public void surfaceCreated(SurfaceHolder surfaceHolder) {        //检查权限        if (ContextCompat.checkSelfPermission(TestActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {        } else {            CameraOpen();        }    }    @Override    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {        Camera.Parameters parameters = mCamera.getParameters();        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);        mCamera.setParameters(parameters);        mCamera.startPreview();    }    @Override    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {        mCamera.stopPreview();        mCamera.release();        mCamera = null;    }
  1. 绑定SurfaceView的Holder到Camera
//打开照相机    public void CameraOpen() {        try        {            mCamera = Camera.open(cameraId);            mCamera.setDisplayOrientation(90);            mCamera.setPreviewDisplay(mSurfaceHolder);            mCamera.startPreview();        } catch (IOException e) {            mCamera.release();            mCamera = null;            Toast.makeText(TestActivity.this, "surface created failed", Toast.LENGTH_SHORT).show();        }    }

预览界面代码

package com.example.test;import android.Manifest;import android.app.Activity;import android.content.Intent;import android.content.pm.ActivityInfo;import android.content.pm.PackageManager;import android.hardware.Camera;import android.os.Bundle;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.Window;import android.widget.Button;import android.widget.Toast;import androidx.core.content.ContextCompat;import java.io.IOException;public class TestActivity extends Activity implements  SurfaceHolder.Callback{    public Button mButton;    public Button switchBtn;    private Camera mCamera;    private SurfaceView surfaceView;    private SurfaceHolder mSurfaceHolder;    private int cameraId = 1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.test_layour);        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);        initView();        initButton();    }    //视图初始化    private void initView() {        surfaceView = findViewById(R.id.surfaceView);//获得SurfaceView的实例        mSurfaceHolder = surfaceView.getHolder();//获得SurfaceView的Holder        mSurfaceHolder.addCallback(this);//设置Holder的回调    }    //打开照相机    public void CameraOpen() {        try        {            //打开摄像机            mCamera = Camera.open(cameraId);            mCamera.setDisplayOrientation(90);            //绑定Surface并开启预览            mCamera.setPreviewDisplay(mSurfaceHolder);            mCamera.startPreview();        } catch (IOException e) {            mCamera.release();            mCamera = null;            Toast.makeText(TestActivity.this, "surface created failed", Toast.LENGTH_SHORT).show();        }    }    //回调初始化    private void initButton() {        //返回上个界面的按钮        mButton = findViewById(R.id.button2);        mButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Intent intent = new Intent();                intent.setClass(TestActivity.this, MainActivity.class);                startActivity(intent);            }        });        //翻转摄像机的按钮        switchBtn = findViewById(R.id.button3);        switchBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                CameraSwitch();            }        });    }    @Override    public void surfaceCreated(SurfaceHolder surfaceHolder) {        //检查权限        if (ContextCompat.checkSelfPermission(TestActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {        } else {            CameraOpen();        }    }    @Override    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {        Camera.Parameters parameters = mCamera.getParameters();        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);        mCamera.setParameters(parameters);        mCamera.startPreview();    }    @Override    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {        mCamera.stopPreview();        mCamera.release();        mCamera = null;    }    //翻转摄像机    public void CameraSwitch()    {        cameraId = cameraId == 1 ? 0 : 1;        mCamera.stopPreview();        mCamera.release();        mCamera = null;        CameraOpen();    }}

思路很简单,在Surface创建的回调中去打开摄像机并开启摄像机的预览,至于为什么我要使用两个Activity,原因是开启摄像机需要获得权限,如果在打开照相机的Activity请求权限的话,会跳到请求权限成功的回调所在的线程导致照相机打不开。

预览页面的UI布局

<?xml version="1.0" encoding="utf-8"?>    

更多相关文章

  1. Android中自定义权限
  2. Android权限注解
  3. Android 权限的一些细节
  4. 剪切图片-扩展android 选择图片(从手机照相机或手机图片)
  5. Linux 下的ADT 权限问题
  6. android基于AndPermission的权限申请封装类
  7. Android 10 文件读写权限申请
  8. android 6.0权限全面详细分析和解决方案

随机推荐

  1. 大气红色新闻手机端
  2. HTML5 初识
  3. 9.26作业-仿站php.cn手机端
  4. 1.模态框 2.flex布局 3.grid属性
  5. 云服务器的操作系统一般怎么选?选错了可以
  6. HTML伪类、盒子模型学习与应用
  7. Linux-04压缩文件操作
  8. VSCode 中,TS 提示 ”无法找到 *.vue 声
  9. Linux-03文件操作[增删改查]
  10. Linux-02目录操作命令