千家信息网

怎样进行Android CameraX打开摄像头预览

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,怎样进行Android CameraX打开摄像头预览,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。前言目标很简单,用CameraX打开摄
千家信息网最后更新 2026年11月01日怎样进行Android CameraX打开摄像头预览

怎样进行Android CameraX打开摄像头预览,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

前言

目标很简单,用CameraX打开摄像头预览,实时显示在界面上。看看CameraX有没有Google说的那么好用。先按最简单的来,把预览显示出来。

引入依赖

模块gradle的一些配置,使用的Android SDK版本为31,启用了databinding

apply plugin: 'com.android.application'apply plugin: 'kotlin-android'apply plugin: 'kotlin-android-extensions'apply plugin: 'kotlin-kapt'android {    compileSdkVersion 31    buildToolsVersion "31.0.0"    defaultConfig {        minSdkVersion 21        targetSdkVersion 31    }    dataBinding {        enabled = true    }}

引入CameraX依赖(CameraX 核心库是用camera2实现的),目前主要用1.1.0-alpha11版本

dependencies {    implementation "androidx.camera:camera-core:1.1.0-alpha11"    implementation "androidx.camera:camera-camera2:1.1.0-alpha11"    implementation "androidx.camera:camera-lifecycle:1.1.0-alpha11"    implementation "androidx.camera:camera-view:1.0.0-alpha31"    implementation "androidx.camera:camera-extensions:1.0.0-alpha31"}

使用1.0.2版本的CameraX核心库会报错,找不到getOrCreateInstance方法。

??? bug "NoSuchMethodError getOrCreateInstance"

```logCrashHandler: In thread: Thread[main,5,main]    UncaughtException detected: java.lang.NoSuchMethodError: No static method getOrCreateInstance(Landroid/content/Context;)Lcom/google/common/util/concurrent/ListenableFuture; in class Landroidx/camera/core/CameraX; or its super classes (declaration of 'androidx.camera.core.CameraX' appears in /data/app/com.rustfisher.tutorial2020-1/base.apk)    at androidx.camera.lifecycle.ProcessCameraProvider.getInstance(ProcessCameraProvider.java:149)    at com.rustfisher.tutorial2020.camera.SimplePreviewXAct.onCreate(SimplePreviewXAct.java:36)    at android.app.Activity.performCreate(Activity.java:6161)    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2507)    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2640)    at android.app.ActivityThread.access$800(ActivityThread.java:182)    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1493)    at android.os.Handler.dispatchMessage(Handler.java:111)    at android.os.Looper.loop(Looper.java:194)    at android.app.ActivityThread.main(ActivityThread.java:5682)    at java.lang.reflect.Method.invoke(Native Method)    at java.lang.reflect.Method.invoke(Method.java:372)    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:963)    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:758)```

权限

需要动态申请android.permission.CAMERA权限

本文略过动态申请权限的地方

界面

CameraX为开发者贴心地准备了androidx.camera.view.PreviewView

把它放在一个FrameLayout里,如下的act_simple_preivew_x.layout

                

开启预览

在activity中开启相机预览

// SimplePreviewXAct.javaimport android.os.Bundle;import androidx.annotation.NonNull;import androidx.annotation.Nullable;import androidx.appcompat.app.AppCompatActivity;import androidx.camera.core.Camera;import androidx.camera.core.CameraSelector;import androidx.camera.core.Preview;import androidx.camera.lifecycle.ProcessCameraProvider;import androidx.core.content.ContextCompat;import androidx.databinding.DataBindingUtil;import androidx.lifecycle.LifecycleOwner;import com.google.common.util.concurrent.ListenableFuture;// import com.rustfisher.tutorial2020.R;// import com.rustfisher.tutorial2020.databinding.ActSimplePreivewXBinding;import java.util.concurrent.ExecutionException;public class SimplePreviewXAct extends AppCompatActivity {    private ActSimplePreivewXBinding mBinding;    private ListenableFuture cameraProviderFuture;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mBinding = DataBindingUtil.setContentView(this, R.layout.act_simple_preivew_x);        cameraProviderFuture = ProcessCameraProvider.getInstance(this);        cameraProviderFuture.addListener(() -> {            try {                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();                bindPreview(cameraProvider);            } catch (ExecutionException | InterruptedException e) {                // 这里不用处理            }        }, ContextCompat.getMainExecutor(this));    }    void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {        Preview preview = new Preview.Builder().build();        CameraSelector cameraSelector = new CameraSelector.Builder()                .requireLensFacing(CameraSelector.LENS_FACING_BACK)                .build();        preview.setSurfaceProvider(mBinding.previewView.getSurfaceProvider());        Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);    }}

注意我们这里使用的是androidx.appcompat.app.AppCompatActivity

为了获得ProcessCameraProvider,用ProcessCameraProvider.getInstance方法拿到一个cameraProviderFuture。
在cameraProviderFuture完成后取出ProcessCameraProvider(cameraProvider)。

要开启预览,通过Preview.Builder构建一个Preview。用CameraSelector来选择后置摄像头。
Preview的SurfaceProvider由layout中的androidx.camera.view.PreviewView提供。

cameraProvider.bindToLifecycle绑定上后,启动摄像头预览

运行测试

运行到手机上,打开这个Activity就可以看到摄像头预览。图像宽高比正常,没有拉伸现象。

荣耀 EMUI 3.1 Lite,Android 5.1 运行正常

Redmi 9A,MIUI 12.5.1稳定版,Android 10 运行正常

一加5,H2OS 10.0.3,Android 10 运行正常

增加开关

在layout里加2个按钮,控制相机开关

                        

根layout换成LinearLayout

修改bindPreview方法,先检查传入的ProcessCameraProvider是否为空

private void bindPreview(ProcessCameraProvider cameraProvider) {    if (cameraProvider == null) {        Toast.makeText(getApplicationContext(), "没获取到相机", Toast.LENGTH_SHORT).show();        return;    }    Preview preview = new Preview.Builder().build();    CameraSelector cameraSelector = new CameraSelector.Builder()            .requireLensFacing(CameraSelector.LENS_FACING_BACK)            .build();    preview.setSurfaceProvider(mBinding.previewView.getSurfaceProvider());    Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);}

修改后的activity部分代码

import android.os.Bundle;import android.widget.Toast;import androidx.annotation.Nullable;import androidx.appcompat.app.AppCompatActivity;import androidx.camera.core.Camera;import androidx.camera.core.CameraSelector;import androidx.camera.core.Preview;import androidx.camera.lifecycle.ProcessCameraProvider;import androidx.core.content.ContextCompat;import androidx.databinding.DataBindingUtil;import com.google.common.util.concurrent.ListenableFuture;// import com.rustfisher.tutorial2020.R;// import com.rustfisher.tutorial2020.databinding.ActSimplePreivewXBinding;import java.util.concurrent.ExecutionException;public class SimplePreviewXAct extends AppCompatActivity {    private ActSimplePreivewXBinding mBinding;    private ListenableFuture mCameraProviderFuture;    private ProcessCameraProvider mCameraProvider;    private boolean mRunning = false;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mBinding = DataBindingUtil.setContentView(this, R.layout.act_simple_preivew_x);        mCameraProviderFuture = ProcessCameraProvider.getInstance(this);        mCameraProviderFuture.addListener(() -> {            try {                mCameraProvider = mCameraProviderFuture.get();            } catch (ExecutionException | InterruptedException e) {                // 这里不用处理            }        }, ContextCompat.getMainExecutor(this));        mBinding.start.setOnClickListener(v -> {            if (mCameraProvider != null && !mRunning) {                bindPreview(mCameraProvider);            }        });        mBinding.end.setOnClickListener(v -> {            mCameraProvider.unbindAll();            mRunning = false;        });    }    private void bindPreview(ProcessCameraProvider cameraProvider) {        if (cameraProvider == null) {            Toast.makeText(getApplicationContext(), "没获取到相机", Toast.LENGTH_SHORT).show();            return;        }        Preview preview = new Preview.Builder().build();        CameraSelector cameraSelector = new CameraSelector.Builder()                .requireLensFacing(CameraSelector.LENS_FACING_BACK)                .build();        preview.setSurfaceProvider(mBinding.previewView.getSurfaceProvider());        Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);        mRunning = true;    }}

拿到mCameraProvider后不要立刻绑定生命周期。

如果要开启预览,则调用bindPreview(mCameraProvider)。记录一下现在相机已经开启预览mRunning = true。

如果要停止预览,则解绑生命周期mCameraProvider.unbindAll()。这个方法需要在主线程调用。

运行起来后,可以用按钮来控制相机预览的开关。相比之前,PreviewView的高度变小了一点(让了点位置给按钮)。
但视频宽高比例正常,没有被拉伸。默认的配置下,还有自动对焦的功能。

从简单的打开相机预览来看,CameraX简化了开发者的工作。提供了PreviewView,开发者不需要自定义SurfaceView或者TextureView。实时预览中,相机能够自动对焦。

看完上述内容,你们掌握怎样进行Android CameraX打开摄像头预览的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

相机 摄像头 摄像 方法 运行 开发者 按钮 权限 版本 开发 不用 内容 动态 周期 实时 更多 核心 生命 界面 问题 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海喔噻互联网科技有限公司 博彦科技互联网金融 互联网科技公司经营范围 科技互联网公司装修 互联网科技公司官网 壕鑫互联网络科技 长亮科技互联网金融 互联网金融和金融科技 佰商互联网科技有限公司 镁科技互联网资讯平台 昭通云南众福互联网科技有限公司 湖南诚度互联网科技有限公司 花神(南京)互联网科技有限公司 崇明区互联网教育科技售后服务 河南住房之家互联网科技 企晟互联网信息科技有限公司 合肥互联网科技公司公章图片 皮皮虾互联网科技有限公司 21世纪互联网科技成就 中国新注册互联网科技 西安纸贵互联网科技有限公司 广州互联网科技公司 金融科技与互联网金融 互联网科技作文 互联网 科技馆 江苏南京365互联网科技 科技互联网的估值 南山科技园互联网公司有哪些 亳州好赞互联网科技有限公司 科技互联网专业工作会议发言稿
0