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代码

效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/57318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring redis使用报错Read timed out排查解决

文章目录 使用场景报错信息解决方式 使用场景 我们使用redis作为缓存服务&#xff0c;缓存一些业务数据&#xff0c;如路口点位信息、渠化信息、设备信息等有一些需要实时计算的数据&#xff0c;缓存在redis里&#xff0c;如实时信号周期相位、周期内过车数量等有需要不同服务…

docker高级(redis集群三主三从)

1. 新建6个docker容器redis实例 docker run -d --name redis-node-1 --net host --privilegedtrue -v /redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381docker run -d --name redis-node-2 --net host --privilegedtrue -v /…

JVM 访问对象的两种方式

Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。由于 reference 类型在《Java 虚拟机规范》里面只规定了它是一个指向对象的引用&#xff0c;并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置&#xff0c;所以对象访问方式也是由虚拟机实现而…

酒店资产如何管理提升资产利用效率

酒店资产管理系统是一种专门为酒店行业设计的管理软件&#xff0c;可以帮助酒店实现资产的全生命周期管理。一个好的酒店资产管理系统应该具备以下功能&#xff1a;  资产登记&#xff1a;可以对酒店的各种资产进行登记&#xff0c;包括房间、家具、设备等&#xff0c;记录资…

EasyExcel+POI制作带有有效性校验及下拉联动的Excel模板

文章目录 1.背景2.实现功能的Excel特性2.1.特性介绍2.2.下拉框联动2.3.单元格自动匹配Id2.4.错误提示 3.代码实现3.1.基础流程代码3.2.名称管理器配置3.3.有效性配置3.4.函数填充3.5.其他补充 4.总结 1.背景 最近在做一个CRM系统的人员销售目标导入的相关需求&#xff0c;需要…

初试Eureka注册中心

Eureka是spring cloud中的一个负责服务注册与发现的组件。遵循着CAP理论中的A(可用性)P(分区容错性)。一个Eureka中分为eureka server和eureka client。其中eureka server是作为服务的注册与发现中心。 搭建eureka服务 引入eureka依赖 引入SpringCloud为eureka提供的starter依…

Day48|leetcode 198.打家劫舍、213.打家劫舍II、打家劫舍|||

leetcode 198.打家劫舍 题目链接&#xff1a;198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 视频链接&#xff1a;动态规划&#xff0c;偷不偷这个房间呢&#xff1f;| LeetCode&#xff1a;198.打家劫舍_哔哩哔哩_bilibili 题目概述 你是一个专业的小偷&#xff0c;…

最小化安装移动云大云操作系统--BCLinux-for-Euler-22.10-everything-x86_64-230316版

CentOS 结束技术支持&#xff0c;转为RHEL的前置stream版本后&#xff0c;国内开源Linux服务器OS生态转向了开源龙蜥和开源欧拉两大开源社区&#xff0c;对应衍生出了一系列商用Linux服务器系统。BCLinux-for-Euler-22.10是中国移动基于开源欧拉操作系统22.03社区版本深度定制的…

【微服务】06-安全问题

文章目录 1.反跨站请求伪造1.1 攻击过程1.2 攻击核心1.3 如何防御1.4 使用AntiforgeryToken机制来防御用到的类 2. 防开发重定向共计2.1 攻击过程2.2 攻击核心2.3 防范措施 3.防跨站脚本3.1 攻击过程3.2 防范措施 4.跨域请求4.1 同源与跨域4.2 CORS过程4.2 CORS是什么4.3 CORS请…

<C++> SSE指令集

SSE指令集 include库 #include <mmintrin.h> //MMX #include <xmmintrin.h> //SSE(include mmintrin.h) #include <emmintrin.h> //SSE2(include xmmintrin.h) #include <pmmintrin.h> //SSE3(include emmintrin.h) #include <tmmintrin.h> /…

Zabbix 5.0 媒体介质 邮箱配置例子

QQ企业邮箱 参考&#xff1a;zabbix 腾讯企业邮箱配置图_harveymomo的博客-CSDN博客

Linux下的系统编程——vim/gcc编辑(二)

前言&#xff1a; 在Linux操作系统之中有很多使用的工具&#xff0c;我们可以用vim来进行程序的编写&#xff0c;然后用gcc来生成可执行文件&#xff0c;最终运行程序。下面就让我们一起了解一下vim和gcc吧 目录 一、vim编辑 1.vim的三种工作模式 2.基本操作之跳转字符 &a…

无涯教程-机器学习 - 箱形图函数

Box和Whisker图(也简称为boxplots)是另一种有用的技术&#xff0c;可用于检查每个属性的分布情况。以下是此技术的特点- 它本质上是单变量的&#xff0c;总结了每个属性的分布。它为中间值(即中位数)画一条线。它将在25&#xff05;和75&#xff05;周围绘制一个框。它还会绘制…

UE4/5在蓝图细节面板中添加函数按钮(蓝图与c++的方法)

目录 在细节面板中添加按钮使用函数 蓝图的方法 事件 函数 效果 uec的方法 效果 在细节面板中添加按钮使用函数 很多时候&#xff0c;我们可以看到一些插件的actor类中&#xff0c;点击一下之后就可以实现如矩阵一样的效果。 实际上是因为其使用了函数来修改了蓝图中的数…

完美解决Ubuntu网络故障,连接异常,IP地址一直显示127.0.0.1

终端输入ifconfig显示虚拟机IP地址为127.0.0.1&#xff0c;具体输出内容如下&#xff1a; wxyubuntu:~$ ifconfig lo: flags73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen …

周鸿祎为360智脑招贤纳士;LLM时代的选择指南;Kaggle大语言模型实战;一文带你逛遍LLM全世界 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 思否「齐聚码力」黑客马拉松&#xff0c;用技术代码让生活变得更美好 主页&#xff1a;https://pages.segmentfault.com/google-hacka…

kubesphere中部署grafana实现dashboard以PDF方式导出

1&#xff0c;部署grafana-image-renderer 2&#xff0c;部署grafana GF_RENDERING_SERVER_URL http://ip:30323/render #grafana-image-renderer地址 GF_RENDERING_CALLBACK_URL http://ip:32403/ #grafana地址 GF_LOG_FILTERS rend…

【ag-grid-vue】列定义(Updating Column Definitions)

列定义一节解释了如何配置列。可以在初始设置列之后更改列的配置。本节介绍如何更新列定义。 添加和删除列 可以通过更新提供给网格的列定义列表来添加和删除列。当设置新列时&#xff0c;网格将与当前列进行比较&#xff0c;并计算出哪些列是旧的(要删除)、哪些列是新的(创建…

BookStack开源免费知识库docker-compose部署

BookStack&#xff08;书栈&#xff09;是一个功能强大且易于使用的开源知识管理平台&#xff0c;适用于个人、团队或企业的文档协作和知识共享。 一、BookStack特点 简单易用&#xff1a;BookStack提供了一个直观的用户界面&#xff0c;使用户能够轻松创建、编辑和组织文档多…

Kali Linux进行移动应用安全测试

使用Kali Linux进行移动应用安全测试是一项关键任务&#xff0c;可以帮助识别和修复移动应用中的安全漏洞。以下是一个基本的步骤指南&#xff0c;展示如何在Kali Linux中进行移动应用安全测试。 步骤&#xff1a; 准备环境&#xff1a; 确保 已经安装了Kali Linux&#xff0c…