安卓获取所有可用摄像头并指定预览

在Android设备中,做预览拍照的需求的时候,我们会指定

CameraSelector DEFAULT_FRONT_CAMERA前置
或者后置CameraSelector DEFAULT_BACK_CAMERA

如果你使用的是平板或者工业平板,那么就会遇到多摄像头以及外置摄像头问题,简单的指定前后置是不行的,哪怕是USB 外置也有挂载两个的情况 ,本文就是写于两个外置的特殊情况作为验证,所以我们必须能获取所有可用的摄像头,我们以最新的预览拍照控件为例(
单摄像头推荐PreviewView+CameraSelector 与挂载的位置相关 且绑定了activity lifecycle
多摄像头推荐Surfaceview+CameraId 与id相关 surfaceview方式获取id在下面

PreviewView

为例初始化的时候需要使用

CameraSelector去绑定拍照的UseCase
    @MainThread@NonNullpublic Camera bindToLifecycle(@NonNull LifecycleOwner lifecycleOwner,@NonNull CameraSelector cameraSelector,@NonNull UseCase... useCases) {if (getCameraOperatingMode() == CAMERA_OPERATING_MODE_CONCURRENT) {throw new UnsupportedOperationException("bindToLifecycle for single camera is not "+ "supported in concurrent camera mode, call unbindAll() first");}setCameraOperatingMode(CAMERA_OPERATING_MODE_SINGLE);Camera camera = bindToLifecycle(lifecycleOwner, cameraSelector, null, emptyList(),useCases);return camera;}

因为我们需要获取所有可用的摄像头类似旧版的CameraId

将下面代码放入activity获取

   val cameraProviderFuture = ProcessCameraProvider.getInstance(this)cameraProviderFuture.addListener({LogUtils.log("摄像头结果返回")val cameraProvider = cameraProviderFuture.get()var textC = ""val cameraInfos = cameraProvider.availableCameraInfosvar isSupportBack = falsevar isSupportFront = falsevar isExternal = falsevar isUnknow = falsefor (cameraInfo in cameraInfos) {when (cameraInfo.lensFacing) {CameraSelector.LENS_FACING_FRONT -> {isSupportFront = truetextC += "\n前置 lensFacing:[${cameraInfo.lensFacing},${cameraInfo.cameraSelector}]"}CameraSelector.LENS_FACING_BACK -> {isSupportBack = truetextC += "\n后置 lensFacing:[${cameraInfo.lensFacing},${cameraInfo.cameraSelector}]"}CameraSelector.LENS_FACING_EXTERNAL -> {isExternal = truetextC += "\n外置 lensFacing:[${cameraInfo.lensFacing},${cameraInfo.cameraSelector}]"}CameraSelector.LENS_FACING_UNKNOWN -> {isUnknow = truetextC += "\n未知 lensFacing:[${cameraInfo.lensFacing},${cameraInfo.cameraSelector}]"}}}LogUtils.logI("init","设备支持情况:后置:${isSupportBack},前置:${isSupportFront},外置:${isExternal},未知:${isUnknow}")binding.tvCheckResult.text = "len:$textC\n" +"设备支持情况:后置:${isSupportBack},前置:${isSupportFront},外置:${isExternal},未知:${isUnknow}"}, ContextCompat.getMainExecutor(this))

工业平板做的产品摄像头一般固定获取之后指定即可,也可以自己编辑优先级逻辑,下面是插两个摄像头的例子

可以使用上述打印的具体摄像头(推荐) 也可以自己bulid,自己build有局限性比如两个外置,你使用2去build就不行了

        val selector: CameraSelector = if (isSupportBack) {CameraSelector.DEFAULT_BACK_CAMERA} else if (isSupportFront) {CameraSelector.DEFAULT_FRONT_CAMERA} else if (isExternal) {CameraSelector.Builder().requireLensFacing(2).build()} else if (isUnknow) {CameraSelector.Builder().requireLensFacing(1).build()} else {CameraSelector.DEFAULT_BACK_CAMERA}

// 如果你使用的是surfaceview+cameraId 而且是多预览 

   val cameraManager =activity.getSystemService(AppCompatActivity.CAMERA_SERVICE) as CameraManagerval cameraIds = cameraManager.cameraIdListfor (cameraId in cameraIds) {val characteristics = cameraManager.getCameraCharacteristics(cameraId)val facing = characteristics.get(CameraCharacteristics.LENS_FACING)}

明确了cameraId 其他通过预览的示例代码 我也传一下吧,由于每个摄像头是独立 有多少个预览就new多少个出来 

class CameraUtils {val TAG = "CameraUtils"private var mCameraDevice: CameraDevice? = nullprivate var mCaptureSession: CameraCaptureSession? = nullprivate var mPreviewBuilder: CaptureRequest.Builder? = nullfun bindSurfaceView(activity: Activity,surfaceView: SurfaceView,len: Int,cId: String?): String {val cameraManager =activity.getSystemService(AppCompatActivity.CAMERA_SERVICE) as CameraManagersurfaceView.holder.setFixedSize(9999, 9999)LogUtils.logI(TAG, "bindSurfaceView")val cameraId = cId ?: getCameraId(cameraManager, len)try {LogUtils.log("len:$len cameraId:$cameraId")if (TextUtils.isEmpty(cameraId)) {LogUtils.logE(TAG, "cameraId  null")return "cameraId  null"}if (ActivityCompat.checkSelfPermission(activity,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {LogUtils.logE(TAG, "没有权限")return "没有权限"}cameraManager.openCamera(cameraId!!, object : CameraDevice.StateCallback() {override fun onOpened(camera: CameraDevice) {LogUtils.logE(TAG, "onOpened cameraId:$cameraId")mCameraDevice = cameracreateCaptureSession(camera, surfaceView)}override fun onDisconnected(camera: CameraDevice) {LogUtils.logE(TAG, "onDisconnected cameraId:$cameraId")}override fun onError(camera: CameraDevice, error: Int) {LogUtils.logE(TAG, "onError:$error cameraId:$cameraId")}}, null)} catch (e: CameraAccessException) {e.printStackTrace()LogUtils.logE(TAG, "onError:$e")return "onError:$e"}return "cameraId:$cameraId"}/*** 创建CaptureSession*/private fun createCaptureSession(camera: CameraDevice, surfaceView: SurfaceView) {try {surfaceView.run {val surfaceHolder: SurfaceHolder = getHolder()surfaceHolder.setFixedSize(getWidth(), getHeight())val surfaces: MutableList<Surface> = ArrayList()surfaces.add(surfaceHolder.surface)mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)mPreviewBuilder?.addTarget(surfaceHolder.surface)camera.createCaptureSession(surfaces,object : CameraCaptureSession.StateCallback() {override fun onConfigured(session: CameraCaptureSession) {mCaptureSession = sessionupdatePreview()}override fun onConfigureFailed(session: CameraCaptureSession) {// 配置会话失败}},null)}} catch (e: CameraAccessException) {e.printStackTrace()}}private fun updatePreview() {if (mCameraDevice == null) {LogUtils.logE(TAG, "mCameraDevice null")return}if (mCaptureSession == null) {LogUtils.logE(TAG, "mCaptureSession null")return}if (mPreviewBuilder == null) {LogUtils.logE(TAG, "mPreviewBuilder null")return}LogUtils.logI(TAG, "updatePreview.")try {mCaptureSession?.setRepeatingRequest(mPreviewBuilder!!.build(), null, null)} catch (e: Exception) {e.printStackTrace()LogUtils.logE(TAG, "updatePreview: $e")}}@Throws(CameraAccessException::class)private fun getCameraId(cameraManager: CameraManager, len: Int): String? {val cameraIds = cameraManager.cameraIdListfor (cameraId in cameraIds) {val characteristics = cameraManager.getCameraCharacteristics(cameraId)val facing = characteristics.get(CameraCharacteristics.LENS_FACING)//            CameraCharacteristics.LENS_FACING_BACK CameraCharacteristics.LENS_FACING_FRONTif (facing != null && facing == len) {return cameraId}}return null}}

比如用RecyclerView 多个item预览  可以这样初始化

    fun getOneUtils(index: Int): CameraUtils {var cache = mCameraUnitsMap[index]if (cache == null) {cache = CameraUtils()mCameraUnitsMap[index] = cache}return cache}

使用

   val text = getOneUtils(position).bindSurfaceView(this@CameraInfoActivity,holder.getView(R.id.surfaceView),len, cameraId)

如果是uniapp同学需要买相关插件的可以留言联系

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

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

相关文章

【报错记录】Ubuntu22.04解决开机卡在 /dev/sda5 : clean , *files , *blocks

一个愿意伫立在巨人肩膀上的农民...... 一、错误现象 本人的电脑安装Windows10和Ubuntu22.04双系统&#xff0c;一次训练中电脑死机无法开机&#xff0c;重启之后便出现如下错误&#xff0c;在网上寻找过很多方法均无效&#xff0c;在root下禁用了samba服务&#xff0c;也无济…

利用代理IP爬取Zillow房产数据用于数据分析

引言 最近数据分析的热度在编程社区不断攀升&#xff0c;有很多小伙伴都开始学习或从事数据采集相关的工作。然而&#xff0c;网站数据已经成为网站的核心资产&#xff0c;许多网站都会设置一系列很复杂的防范措施&#xff0c;阻止外部人员随意采集其数据。为了解决这个问题&a…

Kafka系列教程 - Kafka 生产者 -2

1. 生产者简介 不管是把 Kafka 作为消息队列系统、还是数据存储平台&#xff0c;总是需要一个可以向 Kafka 写入数据的生产者和一个可以从 Kafka 读取数据的消费者&#xff0c;或者是一个兼具两种角色的应用程序。 使用 Kafka 的场景很多&#xff0c;诉求也各有不同&#xff…

语音芯片赋能可穿戴设备:开启个性化音频新体验

在科技日新月异的今天&#xff0c;语音芯片与可穿戴设备的携手合作&#xff0c;正引领我们步入一个前所未有的个性化音频时代。这一创新融合&#xff0c;用户可以享受到更加个性化、沉浸式的音频体验。下面将详细介绍语音芯片与可穿戴设备合作的优点和具体应用。 1. 定制化音效…

1. Flink自定义Source

一. Source 简介 DataStream是Flink的低级API&#xff0c;用于进行数据的实时处理&#xff0c;Flink编程模型分为Source、Transformation、Sink三个部分&#xff0c;如下图所示。 默认Flink提供了大量的内置Source&#xff0c;常见的Source如下&#xff1a; 基于文件的Sour…

Yolov8界面可视化

本教程使用的是Pyside6 1、安装PySide6模块 pip install pyside6 安装完成之后&#xff0c;会有一个designer.exe可执行文件&#xff0c;打开之后&#xff0c;我们可以通过拖拉拽的方式来布局我们的界面。 designer.exe文件位置&#xff0c;一般位于当前虚拟环境下面的路径…

谷粒商城—分布式高级①.md

1. ELASTICSEARCH 1、安装elastic search dokcer中安装elastic search (1)下载ealastic search和kibana docker pull elasticsearch:7.6.2 docker pull kibana:7.6.2(2)配置 mkdir -p /mydata/elasticsearch/config mkdir -p /mydata/elasticsearch/data echo "h…

系统性能优化

一、概述 性能优化的目标&#xff1a;是提高系统或应用程序的响应时间、吞吐量、cpu、内存、磁盘IO、网络、流量、JVM、Tomcat、DB等方面的性能指标。 性能优化需要有一些技巧&#xff1a;对于整个产品或项目而言&#xff0c;比如可以从前端优化、后端优化、架构优化、高并发…

基于STM32设计的粮食仓库(粮仓)环境监测系统

一、前言 当前项目使用的相关软件工具、传感器源代码工程已经上传到网盘&#xff08;实时更新项目内容&#xff09;&#xff1a;https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?fromfrom_copylink 1.1 项目开发背景 随着现代农业的发展和粮食储存规模的…

基于STM32的智能导盲/智能拐杖系统

基于STM32的智能导盲/智能拐杖系统 持续更新&#xff0c;欢迎关注!!! ** 基于STM32的智能导盲/智能拐杖系统 ** 据统计&#xff0c;全球视障人士的数量已经超过2.5亿&#xff0c;其中大部分人需要一种有效的辅助器具来帮助他们感知周围环境&#xff0c;安全行走。 近年来&am…

关于idea-Java-servlet-Tomcat-Web开发中出现404NOT FOUND问题的解决

在做web项目时&#xff0c;第一次使用servlet开发链接前端和后端的操作&#xff0c;果不其然&#xff0c;遇到了诸多问题&#xff0c;而遇到最多的就是运行项目打开页面时出现404NOT FOUND的情况。因为这个问题我也是鼓捣了好久&#xff0c;上网查了许多资料才最终解决&#xf…

【数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;编写一个程序实现链栈的基本运算。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 初始化栈、销毁栈、判断栈是否为空、进栈、出栈、取栈…

与 Cursor AI 对话编程:2小时开发报修维修微信小程序

本文记录了如何通过与 Cursor AI 对话&#xff0c;全程不写一行代码的情况下&#xff0c;完成一个完整的报修小程序。整个过程展示了 AI 如何帮助我们&#xff1a; 生成代码 、解决问题、优化实现、完善细节。 先看一下效果图&#xff1a; 一、项目配置 首先我是这样和 AI 对…

基于windows环境使用nvm安装多版本nodejs

目录 前言 一、卸载node 二、nvm是什么&#xff1f; 三、nvm安装 1.官网下载 nvm 包 2. 安装nvm-setup.exe 3. 配置路径和下载镜像 4. 检查安装是否完成 四、 使用nvm安装node 五、修改npm默认镜像源为淘宝镜像 六、环境变量配置 1. 新建目录 2. 设置环境变量 七…

MVP模式的理解和实践

MVP&#xff08;Model-View-Presenter&#xff09;模式是一种用于组织代码的架构模式&#xff0c;主要用于用户界面的开发。它通过将应用程序的三个主要组件分开&#xff0c;提高了应用的可维护性和可测试性。本文将详细介绍MVP模式的理解和实践&#xff0c;并通过Java语言提供…

在Liunx中安装JDK、Tomcat、mysql、lrzsz、Nginx

一.软件安装方式 在Linux系统中&#xff0c;安装软件的方式主要有四种&#xff0c;这四种安装方式的特点如下&#xff1a; 二.安装JDK 上述我们介绍了Linux系统软件安装的四种形式&#xff0c;接下来我们就通过第一种(二进制发 布包)形式来安装JDK。 在/下创建soft目录&…

神经网络基础-初识神经网络

人工神经网络&#xff08; Artificial Neural Network&#xff0c; 简写为ANN&#xff09;也简称为神经网络&#xff08;NN&#xff09;&#xff0c;是一种模仿生物神经网络结构和功能的计算模型。人脑可以看做是一个生物神经网络&#xff0c;由众多的神经元连接而成。各个神经…

Python中PyTorch详解

文章目录 Python中PyTorch详解一、引言二、PyTorch核心概念1、张量&#xff08;Tensor&#xff09;1.1、创建张量1.2、张量操作 2、自动求导&#xff08;Autograd&#xff09;2.1、自动求导示例 三、构建神经网络1、使用nn模块2、优化器&#xff08;Optimizer&#xff09; 四、…

云服务器挖矿程序占用资源处理

云服务器挖矿程序占用资源处理 文章目录 云服务器挖矿程序占用资源处理top查看服务器后台运行情况关闭病毒删除病毒文件top 云服务器通过手机短信发送了多次预警&#xff0c;疑似出现挖矿程序&#xff0c;登录口令可能已经被暴力破解。处理方法是立即更改口令&#xff0c;然后处…

电脑文件夹打不开了,能打开但是会闪退,提示“找不到iUtils.dll”是什么原因?

电脑运行时常见问题解析&#xff1a;文件夹打不开、闪退及“找不到iUtils.dll”报错 在使用电脑的过程中&#xff0c;我们可能会遇到文件夹打不开、软件闪退或系统报错等问题&#xff0c;特别是提示“找不到iUtils.dll”的报错&#xff0c;更是让人困惑不已。今天我将为大家详…