【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/...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
