Android studio APK切换多个摄像头(Camera2)
1.先设置camera的权限
<uses-permission android:name="android.permission.CAMERA" />
2.布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextureViewandroid:id="@+id/textureView"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/><Buttonandroid:id="@+id/btnSwitchCamera"android:layout_width="match_parent"android:layout_height="100dp"android:textSize="50dp"android:text="切换相机"/></LinearLayout>
3.主界面代码
package com.example.multiplecamerasimport android.Manifest
import android.content.pm.PackageManager
import android.graphics.SurfaceTexture
import android.hardware.camera2.*
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.Surface
import android.view.TextureView
import android.view.TextureView.SurfaceTextureListener
import android.view.View
import androidx.annotation.NonNull
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.hjq.permissions.OnPermission
import com.hjq.permissions.XXPermissionsclass MainActivity : AppCompatActivity() {private val TAG = MainActivity::class.java.simpleNameprivate var cameraManager: CameraManager? = nullprivate var cameraIds: Array<String>?=nullprivate var currentCameraIdIndex = 0private var cameraDevice: CameraDevice? = nullprivate var textureView: TextureView? = nullprivate var captureRequestBuilder: CaptureRequest.Builder? = nullprivate var cameraCaptureSession: CameraCaptureSession? = nullprivate var surfaceTexture: SurfaceTexture? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)XXPermissions.with(this).request(object : OnPermission {@RequiresApi(Build.VERSION_CODES.LOLLIPOP)override fun hasPermission(granted: List<String>, isAll: Boolean) {Log.e("TAG", "hasPermission=" + granted.size + " " + isAll)initView()}override fun noPermission(denied: List<String>, quick: Boolean) {Log.e("TAG", "noPermission=" + denied.size + " " + quick)}})}@RequiresApi(Build.VERSION_CODES.LOLLIPOP)fun initView(){cameraManager = getSystemService(CAMERA_SERVICE) as CameraManagertextureView = findViewById(R.id.textureView)// 设置 TextureView 的监听器,用于在 SurfaceTexture 准备好时打开相机textureView!!.surfaceTextureListener = surfaceTextureListener// 相机切换按钮的点击事件监听器findViewById<View>(R.id.btnSwitchCamera).setOnClickListener {Log.e("TAG", "switchCamera()=========")switchCamera()}}private val surfaceTextureListener: SurfaceTextureListener = object : SurfaceTextureListener {override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {surfaceTexture = surfaceLog.e("TAG", "onSurfaceTextureAvailable")openCamera()}override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture,width: Int,height: Int) {}override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {return false}override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {}}@RequiresApi(Build.VERSION_CODES.LOLLIPOP)private fun openCamera() {Log.e("TAG", "openCamera============")try {cameraIds = cameraManager!!.cameraIdList} catch (e: Exception) {e.printStackTrace()}if (cameraIds != null && cameraIds!!.isNotEmpty()) {val cameraId = cameraIds!![currentCameraIdIndex]if (ActivityCompat.checkSelfPermission(this,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {// TODO: Consider calling// ActivityCompat#requestPermissions// here to request the missing permissions, and then overriding// public void onRequestPermissionsResult(int requestCode, String[] permissions,// int[] grantResults)// to handle the case where the user grants the permission. See the documentation// for ActivityCompat#requestPermissions for more details.return}Log.e("TAG", "openCamera============$cameraId")cameraManager!!.openCamera(cameraId, cameraCallback, null)}}private val cameraCallback: CameraDevice.StateCallback = @RequiresApi(Build.VERSION_CODES.LOLLIPOP)object : CameraDevice.StateCallback() {@RequiresApi(Build.VERSION_CODES.O)override fun onOpened(@NonNull camera: CameraDevice) {cameraDevice = cameraLog.e("TAG", "onOpened============$cameraDevice")startPreview()}override fun onDisconnected(@NonNull camera: CameraDevice) {cameraDevice!!.close()}override fun onError(@NonNull camera: CameraDevice, error: Int) {cameraDevice!!.close()}}@RequiresApi(Build.VERSION_CODES.O)private fun startPreview() {if (cameraDevice == null) {return}Log.e("TAG", "startPreview=====1=======$cameraDevice")try {val surface = Surface(surfaceTexture)// 创建 CaptureRequest.Builder,并设置 Surface 作为目标captureRequestBuilder = cameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)captureRequestBuilder!!.addTarget(surface)Log.e("TAG", "startPreview===2=========${cameraDevice!!.id}")// 创建相机捕获会话cameraDevice!!.createCaptureSession(listOf(surface),captureSessionCallback,null)} catch (e: Exception) {Log.e("TAG", "e============${e.message}")}}private val captureSessionCallback: CameraCaptureSession.StateCallback =@RequiresApi(Build.VERSION_CODES.LOLLIPOP)object : CameraCaptureSession.StateCallback() {override fun onConfigured(@NonNull session: CameraCaptureSession) {cameraCaptureSession = session// 设置重复预览请求try {cameraCaptureSession!!.setRepeatingRequest(captureRequestBuilder!!.build(),null,null)} catch (e: CameraAccessException) {e.printStackTrace()}}override fun onConfigureFailed(@NonNull session: CameraCaptureSession) {Log.e(TAG, "Failed to configure camera capture session")}}private fun switchCamera() {if (cameraIds != null && cameraIds!!.size > 1) {cameraDevice!!.close()currentCameraIdIndex = (currentCameraIdIndex + 1) % cameraIds!!.sizeval cameraId = cameraIds!![currentCameraIdIndex]try {if (ActivityCompat.checkSelfPermission(this,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {// TODO: Consider calling// ActivityCompat#requestPermissions// here to request the missing permissions, and then overriding// public void onRequestPermissionsResult(int requestCode, String[] permissions,// int[] grantResults)// to handle the case where the user grants the permission. See the documentation// for ActivityCompat#requestPermissions for more details.return}cameraManager!!.openCamera(cameraId, cameraCallback, null)} catch (e: CameraAccessException) {e.printStackTrace()}}}@RequiresApi(Build.VERSION_CODES.LOLLIPOP)override fun onPause() {super.onPause()cameraDevice?.close()}override fun onResume() {super.onResume()if (cameraDevice == null && surfaceTexture != null) {openCamera()}}}
XXPermissions.with(this).request(object : OnPermission {@RequiresApi(Build.VERSION_CODES.LOLLIPOP)override fun hasPermission(granted: List<String>, isAll: Boolean) {Log.e("TAG", "hasPermission=" + granted.size + " " + isAll)}override fun noPermission(denied: List<String>, quick: Boolean) {Log.e("TAG", "noPermission=" + denied.size + " " + quick)}})这部分代码是用来授权AndroidManifest.xml里面权限的第三方sdk代码
效果:
相关文章:

Android studio APK切换多个摄像头(Camera2)
1.先设置camera的权限 <uses-permission android:name"android.permission.CAMERA" /> 2.布局 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"and…...
ChatGPT 对教育的影响,AI 如何颠覆传统教育
胜量老师 来源:BV1Nv4y1H7kC 由Chat GPT引发的对教育的思考,人类文明发展至今一直靠教育完成文明的传承,一个年轻人要经历若干年的学习,才能进入社会投入对文明的建设,而学习中有大量内容是需要记忆和反复训练的。 无…...

Spring(九)声明式事务
Spring整合Junit4和JdbcTemplater如下所示: 我们所使用的junit的jar包不同,可以整合不同版本的junit。 我们导入的依赖如下所示: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.a…...
java中用HSSFWorkbook生成xls格式的excel(亲测)
SXSSFWorkbook类是用于生成XLSX格式的Excel文件(基于XML格式),而不是XLS格式的Excel文件(基于二进制格式)。 如果你需要生成XLS格式的Excel文件,可以使用HSSFWorkbook类。以下是一个简单的示例:…...
做平面设计一般电脑可以吗 优漫动游
平面设计常用的软件如下:Photoshop、AutoCAD、AI等。其中对电脑配置要求高的是AutoCAD,可运行AutoCAD的软件均可运行如上软件。 做平面设计一般电脑可以吗 AutoCAD64位版配置要求:AMDAthlon64位处理器、支持SSE2技术的AMDOpteron处理器、…...

设计模式备忘录+命令模式实现Word撤销恢复操作
文章目录 前言思路代码实现uml类图总结 前言 最近学习设计模式行为型的模式,学到了备忘录模式提到这个模式可以记录一个对象的状态属性值,用于下次复用,于是便想到了我们在Windows系统上使用的撤销操作,于是便想着使用这个模式进…...

Linux centos7 bash编程小训练
训练要求: 求比一个数小的最大回文数 知识点: 一个数字正读反读都一样,我们称为回文数,如5、11、55、121、222等。 我们训练用bash编写一个小程序,由我们标准输入一个整数,计算机将显示出一个比这个数小…...

创作2周年纪念日-特别篇
创作2周年纪念日-特别篇 1. 与CSDN的机缘2. 收获3. 憧憬 1. 与CSDN的机缘 很荣幸,在大学时候,能够接触到CSDN这样一个平台,当时对嵌入式开发、编程、计算机视觉等内容比较感兴趣。后面一个很偶然的联培实习机会,让我接触到了Pych…...

【UE5】用法简介-使用MAWI高精度树林资产的地形材质与添加风雪效果
首先我们新建一个basic工程 然后点击floor按del键,把floor给删除。 只留下空白场景 点击“地形” 在这个范例里,我只创建一个500X500大小的地形,只为了告诉大家用法,点击创建 创建好之后有一大片空白的地形出现 让我们点左上角…...

兼容AD210 车规级高精度隔离放大器:ISO EM210
车规级高精度隔离放大器:ISO EM210 Pin-Pin兼容AD210的低成本,小体积DIP标准38Pin金属外壳封装模块,能有效屏蔽现场EMC空间干扰。功能设计全面,采用非固定增益方式,输入信号经过输入端的前置放大器(增益为1-100&#x…...

R语言常用数组函数
目录 1.array 2.matrix 3.data.matrix 4.lower.tri 5.mat.or.vec 6.t:转置矩阵 7.cbind 8.rbind 9.diag 10.aperm:对数组进行轴置换(维度重排)操作 11.%*%:乘法操作要求矩阵 A 的列数等于矩阵 B 的行数 12.crossprod…...

前端开发之Element Plus的分页组件el-pagination显示英文转变为中文
前言 在使用element的时候分页提示语句是中文的到了element-plus中式英文的,本文讲解的就是怎样将英文转变为中文 效果图 解决方案 如果你的element-plus版本为2.2.29以下的 import { createApp } from vue import App from ./App.vue import ElementPlus from …...

基于Java+SpringBoot+Vue前后端分离社区医院管理系统设计和实现
博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…...
浅谈单例模式在游戏开发中的应用
前言 如果在外部想在不同的时间结点、不同的位置访问某类中的成员且想要保持访问时,成员地址唯一。那么可以考虑将该类声明为静态类,但若是成员中包含公共的数据类型,此时便可以考虑将该类做成一个单例。 单例模式 由于类中的数据&#x…...

Stable Diffusion WebUI 整合包
现在网络上出现的各种整合包只是整合了运行 Stable Diffusion WebUI(以下简称为 SD-WebUI)必需的 Python 和 Git 环境,并且预置好模型,有些整合包还添加了一些常用的插件,其实际与手动进行本地部署并没有区别。 不过&a…...
什么是 RESTful API
什么是 RESTful API? RESTful API是一种设计哲学和架构风格,它基于 HTTP 协议和其状态管理原则,用于构建分布式系统。RESTful API 遵循以下设计原则: 资源层:API 应该代表一种资源,例如一个用户、一个订单…...

如何搭建关键字驱动自动化测试框架?
前言 那么这篇文章我们将了解关键字驱动测试又是如何驱动自动化测试完成整个测试过程的。关键字驱动框架是一种功能自动化测试框架,它也被称为表格驱动测试或者基于动作字的测试。关键字驱动的框架的基本工作是将测试用例分成四个不同的部分。首先是测试步骤&#x…...

WPF实战项目十二(API篇):配置AutoMapper
1、新建类库WPFProjectShared,在类库下新建文件夹Dtos,新建BaseDto.cs,继承INotifyPropertyChanged,实现通知更新。 public class BaseDto : INotifyPropertyChanged{public int Id { get; set; }public event PropertyChangedEv…...
Linux 内核模块加载过程之重定位
文章目录 一、内核模块符号解析1.1 内核模块重定位函数调用1.1.1 struct load_info info1.1.2 copy_module_from_user 1.2 simplify_symbols1.2.1 simplify_symbols1.2.2 resolve_symbol_wait1.2.3 resolve_symbol1.2.4 find_symbol 二、 apply_relocations2.1 apply_relocatio…...
Flink流批一体计算(19):PyFlink DataStream API之State
目录 keyed state Keyed DataStream 使用 Keyed State 实现了一个简单的计数窗口 状态有效期 (TTL) 过期数据的清理 全量快照时进行清理 增量数据清理 在 RocksDB 压缩时清理 Operator State算子状态 Broadcast State广播状态 keyed state Keyed DataStream 使用 k…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...