Android Camera预览
16lz
2021-01-23
简介
因工作原因要学习Android的Camera预览功能,这个DEMO有两个Activity,使用Camera库实现
项目地址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了
最关键的两个工作
- 设置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; }
- 绑定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"?>
更多相关文章
- Android中自定义权限
- Android权限注解
- Android 权限的一些细节
- 剪切图片-扩展android 选择图片(从手机照相机或手机图片)
- Linux 下的ADT 权限问题
- android基于AndPermission的权限申请封装类
- Android 10 文件读写权限申请
- android 6.0权限全面详细分析和解决方案