【Android】使用 CameraX 实现基础拍照功能
目录
目录
1. 基础开发环境
2. 添加相关依赖
3. APP 布局
4. 主流程逻辑
5. 调试或安装 APK
1. 基础开发环境
JDK:JDK17
Android Studio:Android Studio Giraffe | 2022.3.1
Android SDK:Android API 34
Gradle: gradle-7.2-bin.zip
CameraX Version: 1.1.0-alpha05
2. 添加相关依赖
在 build.gradle 中添加 CameraX 的相关依赖
// *** Camera 相关依赖 ***def cameraxVersion = "1.1.0-alpha05";implementation "androidx.camera:camera-core:${cameraxVersion}"implementation "androidx.camera:camera-camera2:${cameraxVersion}"implementation "androidx.camera:camera-lifecycle:${cameraxVersion}"implementation 'androidx.camera:camera-view:1.0.0-alpha25'// ***********************
在 AndroidManifest.xml 文件中注册相机权限
<!-- 这个权限声明意味着此 Android 应用程序需要设备具有摄像头功能才能正常运行,并且如果设备没有摄像头,则应用程序将无法在该设备上安装或运行。"android:required = "true"" 表示摄像头功能是必需的,而不是可选的。 --><uses-featureandroid:name="android.hardware.camera"android:required="true" /><!-- 注册相机权限 --><!-- 这个权限允许应用程序读取摄像头的输入并拍照或录制视频。如果没有这个权限,应用程序将无法访问设备的相机功能。 --><uses-permission android:name="android.permission.CAMERA" /><!-- 这个权限允许应用程序录制音频。 --><uses-permission android:name="android.permission.RECORD_AUDIO" /><!-- 这个权限允许应用程序向外部存储(例如SD卡)写入数据。而这个权限只适用于 Android 版本号不大于 28 的设备。 --><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"android:maxSdkVersion="28" />
3. APP 布局
使用 LinearLayout 布局,其中添加一个 PreviewView 用来显示相机画面的预览,添加一个 Button 用来控制拍照。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:divider="@color/black"android:gravity="center"android:orientation="vertical"tools:context=".MainActivity"><androidx.camera.view.PreviewViewandroid:id="@+id/previewView"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="3" /><Buttonandroid:id="@+id/captureButton"android:layout_width="wrap_content"android:layout_height="100dp"android:layout_weight="1"android:text="@string/capture_button" /></LinearLayout>
<resources><string name="app_name">camera-image-capture</string><string name="capture_button">拍照</string>
</resources>
4. 主流程逻辑
package com.example.capture;import android.content.ContentValues;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;import com.google.common.util.concurrent.ListenableFuture;import java.util.concurrent.ExecutionException;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private ListenableFuture<ProcessCameraProvider> processCameraProviderListenableFuture;PreviewView previewView;Button captureButton;private ImageCapture imageCapture;@Overrideprotected void onCreate(Bundle savedInstanceState) {// onCreate 在活动被创建时被调用的。// 它的作用是对活动进行初始化,例如加载布局文件,设置事件监听器和初始化变量等。// `Bundle savedInstanceState` 参数用于保存活动状态,以便在活动被销毁后能够恢复它的状态。super.onCreate(savedInstanceState);// 将指定的布局文件加载到当前 Activity 中并显示在屏幕上。setContentView(R.layout.activity_main);// 从当前布局中查找具有指定 ID 的视图,并将其返回为 Java 对象。previewView = findViewById(R.id.previewView);captureButton = findViewById(R.id.captureButton);// 将当前类实现的 OnClickListener 接口设置为 captureButton 的点击事件监听器,// 以便在单击 captureButton 时调用类中的 onClick() 方法来处理点击事件。captureButton.setOnClickListener(this);// 这行代码的作用是获取相机提供者的实例,它是使用 Android CameraX API 实现相机功能的关键对象之一,// 通过它可以获取相机设备、预览用例、图像分析用例等等,从而实现相机应用的各种功能。// 此代码返回一个ListenableFuture对象,用于异步获取相机提供者的实例。processCameraProviderListenableFuture = ProcessCameraProvider.getInstance(this);// 监听摄像头的准备情况。准备好时,该代码块中的 start() 方法将被调用,以便启动相机。processCameraProviderListenableFuture.addListener(() -> {try {ProcessCameraProvider processCameraProvider = processCameraProviderListenableFuture.get();start(processCameraProvider);} catch (ExecutionException | InterruptedException e) {throw new RuntimeException(e);}// 将监听器绑定到主线程,以确保在 UI 上下文中运行该代码块。}, ContextCompat.getMainExecutor(this));}private void start(ProcessCameraProvider processCameraProvider) {// 取消当前已经绑定的摄像头设备,释放它们的资源,以便其他应用或者进程可以使用这些摄像头设备。// 这个方法通常在摄像头应用程序退出或者暂停时调用,以确保摄像头设备不会一直占用系统资源。processCameraProvider.unbindAll();// 创建一个相机选择器对象,并指定选择前置摄像头。CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_FRONT).build();// 创建一个相机预览对象// 并将其与一个 SurfaceView 组件(previewView)的 SurfaceProvider 绑定,从而在该组件上显示相机预览画面。Preview preview = new Preview.Builder().build();preview.setSurfaceProvider(previewView.getSurfaceProvider());// 创建一个 ImageCapture 对象,用于拍摄照片。// 设置拍照模式为最小化延迟模式,这意味着拍照时将尽可能快地捕获图像。imageCapture = new ImageCapture.Builder().setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY).build();// 在 Android 设备上启动相机,并将其与当前生命周期绑定,以便在应用程序暂停或停止时释放相机资源。// 该方法接受一个 `CameraSelector` 对象用于选择相机设备,一个 `Preview` 对象用于显示预览,以及一个 `ImageCapture` 对象用于捕获图像。processCameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);}@Overridepublic void onClick(View view) {// onClick(View view) 的作用是为按钮或其他视图设置点击事件处理程序。// 当用户点击该视图时,该方法会被调用并执行其中的代码。if (view.getId() == R.id.captureButton) {captureImage();}}private void captureImage() {long timeStamp = System.currentTimeMillis();// 通过 ContentValues 对象设置文件名和文件类型ContentValues contentValues = new ContentValues();contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, timeStamp);contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");imageCapture.takePicture(// 第一个参数 OutputFileOptions 指定了照片保存的位置和格式等信息。new ImageCapture.OutputFileOptions.Builder(getContentResolver(),MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues).build(),// 第二个参数 Executor 指定了保存照片时要运行的线程。ContextCompat.getMainExecutor(this),// 第三个参数 OnImageSavedCallback 指定了保存照片完成后的回调函数,可以在其中进行一些提示或其他操作。new ImageCapture.OnImageSavedCallback() {@Overridepublic void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {Toast.makeText(MainActivity.this, "Saving...", Toast.LENGTH_SHORT).show();}@Overridepublic void onError(@NonNull ImageCaptureException exception) {Toast.makeText(MainActivity.this, "Error: " + exception.getMessage(), Toast.LENGTH_SHORT).show();}});}
}
5. 调试或安装 APK
使用 USB 调试或者 Build 出 APK(Build -> Make Project)然后找到 app-debug.apk 文件进行安装。
注意:由于代码逻辑中没有权限申请部分,需要在安装好后手动开启拍照权限。
6. 项目完整代码
https://gitee.com/hl0929/camera-image-capture
相关文章:
【Android】使用 CameraX 实现基础拍照功能
目录 目录 1. 基础开发环境 2. 添加相关依赖 3. APP 布局 4. 主流程逻辑 5. 调试或安装 APK 1. 基础开发环境 JDK:JDK17 Android Studio:Android Studio Giraffe | 2022.3.1 Android SDK:Android API 34 Gradle: gradle-7.2-bin.zip Ca…...

刷题笔记 day2
力扣 1089 复写零 思路:双指针 第一步:利用指针 cur 去记录最后一位要复写的数 , 利用指针 dest 指向最后一位数所要复写的位置; 实现过程:最开始 cur 指向0,dest 指向 -1 , 当arr[cur] ! …...

回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测
回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现SO-CNN-LS…...

使用UltraISO制作麒麟v10系统盘
大家好,我是早九晚十二,目前是做运维相关的工作。写博客是为了积累,希望大家一起进步! 我的主页:早九晚十二 文章目录 1 背景2 准备工作2.1 镜像准备2.2 制作工具2.3 启动U盘 3 制作步骤3.1 找到ISO文件,右…...

【RabbitMQ】之消息的可靠性方案
目录 一、数据丢失场景二、数据可靠性方案 1、生产者丢失消息解决方案2、MQ 队列丢失消息解决方案3、消费者丢失消息解决方案 一、数据丢失场景 MQ 消息数据完整的链路为:从 Producer 发送消息到 RabbitMQ 服务器中,再由 Broker 服务的 Exchange 根据…...

性能测试/负载测试/压力测试之间的区别
做测试一年多来,虽然平时的工作都能很好的完成,但最近突然发现自己在关于测试的整体知识体系上面的了解很是欠缺,所以,在工作之余也做了一些测试方面的知识的补充。不足之处,还请大家多多交流,互相学习。 …...

Mybatis ,Mybatis-plus列表多字段排序,包含sql以及warpper
根据 mybatis 根据多字段排序已经wrapper 根据多字段排序 首先根据咱们返回前端的数据列来规划好排序字段 如下: 这里的字段为返回VO的字段,要转换成数据库字段然后加入到排序中 示例,穿了 surname,cerRank 多字段,然后是倒序 false 首先创建好映射&am…...
sonarqube PHP编码规范检查
一、PSR规范整理 PHP 已有的编码规范如下 https://blog.csdn.net/qq_40876291/article/details/103848172 1.1 基本编码规范:PSR1 官网规范链接 https://www.php-fig.org/psr/psr-1/ 文件只能使用<?php和<?标记。文件必须仅使用UTF-8,而不使…...
Kylin 麒麟 Qt软件 QtCreator 中文输入法问题
Kylin 麒麟 Qt软件 QtCreator 中文输入法问题 背景: QtCreator 和程序在麒麟系统下没法进行输入,或没法进行输入法的切换。 包括麒麟自带默认搜狗输入法的切换也不行。 使用下面的命令进行安装后,可以正常在QtCreator和程序中使用输入法。 …...

租赁固定资产管理
智能租赁资产管理系统可以为企业单位提供RFID资产管理系统。移动APP资产管理,准确总结易损耗品和固定资金,从入库到仓库库存实时跟踪,控制出库和入库的全过程。同时,备件和耗材与所属资产设备有关,便于备件的申请和管理…...
【Kubernetes】Kubernetes的概念
Kubernetes 一、Kubernetes 概述1.Kubernetes 是什么?2. Kubernetes 的作用3. 为什么要用 Kubernetes?4. Kubernetes 的概念5. Kubernetes 的主要功能6. Kubernetes 集群架构与组件二、Kubernetes 的组件1. Master 组件1.1 Kube-apiserver1.2 Kube-controller-manager1.3 Kub…...

抖音短视频seo源码矩阵系统开发
一、前言: 抖音SEO源码矩阵系统开发是一项专为抖音平台设计的SEO优化系统,能够帮助用户提升抖音视频的搜索排名和曝光度。为了确保系统运行正常,需要安装FFmpeg和FFprobe工具。FFmpeg是一个用于处理多媒体数据的开源工具集,而FFpr…...
npm install pnpm -g报错解决!
目录 报错信息:(反正就是各种err) 报错分析: 错误处理: 其它pnpm报错传送门: 报错信息:(反正就是各种err) npm ERR! code EPERM npm ERR! syscall mkdir npm ERR! pa…...

vue2、vue3生命周期详解以及对比
文章目录 对比vue2-vue3vue3生命周期生命周期的主要阶段详情 vue2 生命周期生命周期钩子函数 总共11个 常用的8个按照这四个阶段我们对应有八个生命周期钩子函数vue生命周期使用场景 对比vue2-vue3 如果熟悉vue2的话,vue3信手拈来,看图 vue3生命周期 on…...

JSON动态生成表格
<!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><script>var fromjava"{\"total\":3,\"students\":[{\"name\":\"张三\",\&q…...
C# Winform中使用SendMessage方法(发送消息与接收消息)
C# Winform窗口间消息通知,使用Windows API SendMessage方法跨进程实现消息发送,重写WndProc方法接收消息并消息处理 主要使用到如下三个方法函数: WndProc:主要用在拦截并处理系统消息和自定义消息 可以重写WndProc函数…...

Netty各组件基本用法、入站和出站详情、群聊系统的实现、粘包和拆包
Netty Bootstrap和ServerBootstrapFuture和ChannelFutureChannelSelectorNioEventLoop和NioEventLoopGroupByteBuf示例代码 Channel相关组件入站详情出站详情对象编解码ProtoBuf和ProtoStuffnetty实现群聊系统粘包和拆包TCP协议特点举个例子 Bootstrap和ServerBootstrap Boots…...

Day03-作业(AxiosElementUI)
作业1: 根据需求完成如下页面数据列表展示 需求:Vue挂载完成后,通过axios发送异步请求到服务端,获取学生列表数据,并通过Vue展示在页面上 获取数据url:http://yapi.smart-xwork.cn/mock/169327/student 素材: <!DOCTYPE html…...

低代码开发平台源码:基于模型驱动,内置功能强大的建模引擎,零代码也能快速创建智能化、移动化的企业应用程序
管理后台低代码PaaS平台是一款基于 Salesforce Platform 的开源替代方案,旨在为企业提供高效、灵活、易于使用的低代码开发平台。低代码PaaS平台的10大核心引擎功能:1.建模引擎 2.移动引擎 3.流程引擎 4.页面引擎 5.报表引擎 6.安全引擎 7.API引擎 8.应用集成引擎 9…...

下载JMeter的历史版本——个人推荐5.2.1版本
官网地址:https://archive.apache.org/dist/jmeter/binaries/...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...