当前位置: 首页 > news >正文

【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&#xff1a;JDK17 Android Studio&#xff1a;Android Studio Giraffe | 2022.3.1 Android SDK&#xff1a;Android API 34 Gradle: gradle-7.2-bin.zip Ca…...

刷题笔记 day2

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

回归预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络多输入单输出回归预测

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

使用UltraISO制作麒麟v10系统盘

大家好&#xff0c;我是早九晚十二&#xff0c;目前是做运维相关的工作。写博客是为了积累&#xff0c;希望大家一起进步&#xff01; 我的主页&#xff1a;早九晚十二 文章目录 1 背景2 准备工作2.1 镜像准备2.2 制作工具2.3 启动U盘 3 制作步骤3.1 找到ISO文件&#xff0c;右…...

【RabbitMQ】之消息的可靠性方案

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

性能测试/负载测试/压力测试之间的区别

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

Mybatis ,Mybatis-plus列表多字段排序,包含sql以及warpper

根据 mybatis 根据多字段排序已经wrapper 根据多字段排序 首先根据咱们返回前端的数据列来规划好排序字段 如下&#xff1a; 这里的字段为返回VO的字段,要转换成数据库字段然后加入到排序中 示例&#xff0c;穿了 surname,cerRank 多字段,然后是倒序 false 首先创建好映射&am…...

sonarqube PHP编码规范检查

一、PSR规范整理 PHP 已有的编码规范如下 https://blog.csdn.net/qq_40876291/article/details/103848172 1.1 基本编码规范&#xff1a;PSR1 官网规范链接 https://www.php-fig.org/psr/psr-1/ 文件只能使用<?php和<?标记。文件必须仅使用UTF-8&#xff0c;而不使…...

Kylin 麒麟 Qt软件 QtCreator 中文输入法问题

Kylin 麒麟 Qt软件 QtCreator 中文输入法问题 背景&#xff1a; QtCreator 和程序在麒麟系统下没法进行输入&#xff0c;或没法进行输入法的切换。 包括麒麟自带默认搜狗输入法的切换也不行。 使用下面的命令进行安装后&#xff0c;可以正常在QtCreator和程序中使用输入法。 …...

租赁固定资产管理

智能租赁资产管理系统可以为企业单位提供RFID资产管理系统。移动APP资产管理&#xff0c;准确总结易损耗品和固定资金&#xff0c;从入库到仓库库存实时跟踪&#xff0c;控制出库和入库的全过程。同时&#xff0c;备件和耗材与所属资产设备有关&#xff0c;便于备件的申请和管理…...

【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源码矩阵系统开发

一、前言&#xff1a; 抖音SEO源码矩阵系统开发是一项专为抖音平台设计的SEO优化系统&#xff0c;能够帮助用户提升抖音视频的搜索排名和曝光度。为了确保系统运行正常&#xff0c;需要安装FFmpeg和FFprobe工具。FFmpeg是一个用于处理多媒体数据的开源工具集&#xff0c;而FFpr…...

npm install pnpm -g报错解决!

目录 报错信息&#xff1a;&#xff08;反正就是各种err&#xff09; 报错分析&#xff1a; 错误处理&#xff1a; 其它pnpm报错传送门&#xff1a; 报错信息&#xff1a;&#xff08;反正就是各种err&#xff09; npm ERR! code EPERM npm ERR! syscall mkdir npm ERR! pa…...

vue2、vue3生命周期详解以及对比

文章目录 对比vue2-vue3vue3生命周期生命周期的主要阶段详情 vue2 生命周期生命周期钩子函数 总共11个 常用的8个按照这四个阶段我们对应有八个生命周期钩子函数vue生命周期使用场景 对比vue2-vue3 如果熟悉vue2的话&#xff0c;vue3信手拈来&#xff0c;看图 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窗口间消息通知&#xff0c;使用Windows API SendMessage方法跨进程实现消息发送&#xff0c;重写WndProc方法接收消息并消息处理 主要使用到如下三个方法函数&#xff1a; WndProc&#xff1a;主要用在拦截并处理系统消息和自定义消息 可以重写WndProc函数&#xf…...

Netty各组件基本用法、入站和出站详情、群聊系统的实现、粘包和拆包

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

Day03-作业(AxiosElementUI)

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

低代码开发平台源码:基于模型驱动,内置功能强大的建模引擎,零代码也能快速创建智能化、移动化的企业应用程序

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

下载JMeter的历史版本——个人推荐5.2.1版本

官网地址&#xff1a;https://archive.apache.org/dist/jmeter/binaries/...

2023-07-30 LeetCode每日一题(环形链表 II)

2023-07-30每日一题 一、题目编号 142. 环形链表 II二、题目链接 点击跳转到题目位置 三、题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 n…...

设计模式——简单工厂模式

1 概述 将创造对象的工作交给一个单独的类来实现 &#xff0c;这个单独的类就是工厂。 2 实现 假设要做一个计算器的需求&#xff0c;通常我们想到的是这样写&#xff1a; package com.example.easyfactory;import java.util.Scanner;public class Demo1 {public static vo…...

AnimatedVectorDrawable矢量图动画的使用和修改

文章目录 一、前言二、一个矢量图文件三、参考链接 一、前言 矢量可绘制对象可以提供比较复杂的动画效果&#xff0c;只是绘制比较复杂&#xff0c;这里可以让UI使用Adobe After Effects软件制作出相关的矢量图xml文件交由开发使用。只是如果需要重复播放的动画效果时候&#…...

【C++】—— 多态的基本介绍

前言&#xff1a; 在之前的学习过程中&#xff0c;我们已经对继承进行了详细的学习和了解。今天&#xff0c;我将带领大家学习的是关于 多态 的基本知识。 目录 &#xff08;一&#xff09;多态的概念 1、概念 &#xff08;二&#xff09;多态的定义及实现 1、多态的构成条…...

一文详解:自动化测试工具——Selenium

前言 Selenium是一个用于Web应用程序测试的工具。是一个开源的Web的自动化测试工具&#xff0c;最初是为网站自动化测试而开发的&#xff0c;类型像我们玩游戏用的按键精灵&#xff0c;可以按指定的命令自动操作&#xff0c;不同是Selenium可以直接运行在浏览器上&#xff0c;…...

[模版总结] - 集合划分类DFS模版

题目描述 给定一个数组&#xff0c;给定一个数字k, 问能不能讲数组内数等分成k份&#xff0c;使得每一个集合中数和相等。 题目链接 下面两道题问题及其类似&#xff0c;可作为同一类题目思考 Leetcode 698 Leetcode 473 题目思路 这道题是一道经典集合划分类问题&#…...

JavaScript中复制新的数组与原数组删除某个值——不影响新复制的数组的方法详解

系列文章目录 文章目录 系列文章目录前言一、使用slice()方法复制数组二、使用concat()方法复制数组三、使用扩展运算符(...)复制数组总结 前言 在JavaScript中&#xff0c;我们经常需要处理数组的复制和修改。本文将详细介绍如何在JavaScript中复制一个新的数组&#xff0c;并…...

easyui主表子表维护页面

easyui主表子表维护页面 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>Title</title><!-- <#include "common.html"/> --><link rel"stylesheet" type&quo…...

k8s exam

Pause 容器是 Pod 中的第一个启动的容器&#xff0c;其他所有的用户容器都是其子进程当 Pod 被从节点中删除时&#xff0c;与之关联的 emptyDir 中的数据也将被永久删除。持久存储用PV&#xff0c;PVCService 资源定义了如何访问应用&#xff0c;但实际的网络流量管理和路由是由…...

C#,中国福利彩票《刮刮乐》的数学算法(02)——时来运转

1 中国福利彩票 中国福利彩票始于1987年7月27日&#xff0c;以“团结各界热心社会福利事业的人士&#xff0c;发扬社会主义人道主义精神&#xff0c;筹集社会福利资金&#xff0c;兴办残疾人、老年人、孤儿福利事业和帮助有困难的人”、即“扶老、助残、救孤、济困”为宗旨。随…...