You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用访问外接USB摄像头:官方库及检测问题咨询

Android外接USB摄像头官方解决方案及问题排查

官方支持库:Camera2 API 与 CameraX

Android官方提供Camera2 API(Android 5.0+)和CameraX(Android 5.0+,Jetpack库)作为外接USB摄像头的官方访问方案,二者均支持UVC(USB视频类)标准的外接摄像头。

你的代码无法检测到USB摄像头的原因

你使用cameraManager.cameraIdList无法列出外接摄像头,通常是以下原因:

  • 缺少必要权限或设备配置
  • 未过滤识别外接摄像头的特征
  • 设备不支持USB Host模式或UVC标准

正确实现步骤(Kotlin)

1. 配置Manifest权限

在AndroidManifest.xml中添加以下配置:

<!-- 基础摄像头权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 声明支持USB Host模式 -->
<uses-feature android:name="android.hardware.usb.host" android:required="false" />
<!-- Android 13+ 需添加通知权限(若需后台访问) -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" android:maxSdkVersion="33" />

2. 动态请求权限

在Activity/Fragment中请求CAMERA权限:

private const val REQUEST_CAMERA_PERMISSION = 1001

private fun requestPermissions() {
    val permissions = arrayOf(Manifest.permission.CAMERA)
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, permissions, REQUEST_CAMERA_PERMISSION)
    } else {
        detectUsbCameras()
    }
}

3. 使用Camera2 API检测外接摄像头

通过CameraCharacteristics判断是否为外接摄像头:

private fun detectUsbCameras() {
    val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
    cameraManager.cameraIdList.forEach { cameraId ->
        try {
            val characteristics = cameraManager.getCameraCharacteristics(cameraId)
            // 判断是否为外接摄像头
            val deviceType = characteristics.get(CameraCharacteristics.INFO_DEVICE_TYPE)
            if (deviceType == CameraCharacteristics.INFO_DEVICE_TYPE_EXTERNAL) {
                println("检测到外接USB摄像头,ID: $cameraId")
                // 可进一步获取摄像头参数
                val supportedSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)?.getOutputSizes(ImageFormat.JPEG)
                supportedSizes?.forEach { size ->
                    println("支持分辨率: ${size.width}x${size.height}")
                }
            }
        } catch (e: CameraAccessException) {
            e.printStackTrace()
        }
    }
}

4. 使用CameraX简化开发(推荐)

CameraX封装了底层细节,自动识别外接摄像头:

private fun initCameraX() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
    cameraProviderFuture.addListener({
        val cameraProvider = cameraProviderFuture.get()
        // 筛选外接摄像头
        val cameraSelector = CameraSelector.Builder()
            .requireCameraDeviceType(CameraDeviceType.EXTERNAL)
            .build()
        try {
            val preview = Preview.Builder().build()
            preview.setSurfaceProvider(previewView.surfaceProvider)
            cameraProvider.unbindAll()
            cameraProvider.bindToLifecycle(this, cameraSelector, preview)
            println("成功绑定外接摄像头预览")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }, ContextCompat.getMainExecutor(this))
}

常见问题排查

  • 确认设备支持USB Host模式(需使用OTG线连接摄像头)
  • 确保外接摄像头符合UVC标准(非UVC摄像头可能需要厂商驱动,官方API无法直接支持)
  • Android 10+对USB设备访问有后台限制,需确保应用在前台时访问
  • 可通过UsbManager枚举所有USB设备,确认摄像头是否被系统识别:
val usbManager = getSystemService(Context.USB_SERVICE) as UsbManager
val deviceList = usbManager.deviceList
deviceList.values.forEach { device ->
    println("USB设备: ${device.deviceName}, VID: ${device.vendorId}, PID: ${device.productId}")
}

内容的提问来源于stack exchange,提问作者Rumit Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 04:21:24