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

Android Studio:CameraManager.turnOnTorchWithStrengthLevel抛出异常如何解决?

解决方案

1. 修复未初始化异常

错误原因很明确:你在cameraManager和cameraId完成初始化之前就调用了turnOnTorchWithStrengthLevel方法。代码里这两个变量的赋值语句在调用之后,导致Kotlin抛出UninitializedPropertyAccessException。

修正后的初始化顺序

把cameraManager和cameraId的初始化代码移到调用手电筒方法之前:

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // 先初始化CameraManager和cameraId
    cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
    try {
        cameraId = cameraManager.cameraIdList[0]
    } catch (e: CameraAccessException) {
        e.printStackTrace()
        Toast.makeText(this, "获取相机ID失败", Toast.LENGTH_SHORT).show()
        return // 初始化失败直接返回,避免后续崩溃
    }

    // 现在可以安全调用手电筒方法
    try {
        cameraManager.turnOnTorchWithStrengthLevel(cameraId, 50)
        isFlashOn = true
    } catch (e: CameraAccessException) {
        e.printStackTrace()
        Toast.makeText(this, "打开手电筒失败", Toast.LENGTH_SHORT).show()
    }

    // 后续SeekBar初始化代码保持不变
    val textView = findViewById<TextView>(R.id.textView)
    val seek = findViewById<SeekBar>(R.id.seekBar)
    seek.min = 100
    seek.max = 1000
    seek.progress = 500
    counter = seek.progress.toFloat()

    seek.setOnSeekBarChangeListener(
        object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(
                seekBar: SeekBar?,
                progress: Int,
                fromUser: Boolean
            ) {
                counter = seek.progress.toFloat()
                val formattedString = String.format("%.0f", counter)
                textView.text = "Milliseconds: $formattedString"
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
            override fun onStopTrackingTouch(seekBar: SeekBar?) = Unit
        },
    )

    handler = Handler(Looper.getMainLooper())
}

2. 完整的手电筒亮度控制流程

除了修复初始化问题,还要确保实现符合Android 13(API 34)的要求:

  • 权限配置:在AndroidManifest.xml中添加必要权限:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-feature android:name="android.hardware.camera.flash" android:required="false" />
    

    注意:Android 6.0及以上版本需要动态申请CAMERA权限。

  • 检查设备支持度:调用亮度控制前,先确认当前相机支持亮度调节:

    private fun isTorchStrengthSupported(): Boolean {
        return try {
            val characteristics = cameraManager.getCameraCharacteristics(cameraId)
            val maxStrength = characteristics.get(CameraCharacteristics.FLASH_INFO_STRENGTH_MAX) ?: 0
            maxStrength > 1 // 最大强度大于1说明支持调节
        } catch (e: CameraAccessException) {
            false
        }
    }
    
  • 适配亮度范围:turnOnTorchWithStrengthLevel的强度参数范围是1到设备支持的最大强度(通过CameraCharacteristics.FLASH_INFO_STRENGTH_MAX获取),不是固定0-100。可以修改SeekBar适配这个范围:

    val maxStrength = cameraManager.getCameraCharacteristics(cameraId)
        .get(CameraCharacteristics.FLASH_INFO_STRENGTH_MAX) ?: 1
    seek.min = 1
    seek.max = maxStrength
    seek.progress = maxStrength / 2 // 默认设为中等亮度
    
  • 动态调节亮度:在SeekBar回调中实时更新手电筒亮度:

    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        if (isFlashOn && fromUser) {
            try {
                cameraManager.setTorchStrengthLevel(cameraId, progress)
            } catch (e: CameraAccessException) {
                e.printStackTrace()
                Toast.makeText(this, "调节亮度失败", Toast.LENGTH_SHORT).show()
            }
        }
        // UI更新代码
        counter = progress.toFloat()
        val formattedString = String.format("%.0f", counter)
        textView.text = "亮度等级: $formattedString"
    }
    

3. 额外注意事项

  • 页面销毁时关闭手电筒,避免资源占用:
    override fun onDestroy() {
        super.onDestroy()
        if (isFlashOn) {
            try {
                cameraManager.setTorchMode(cameraId, false)
            } catch (e: CameraAccessException) {
                e.printStackTrace()
            }
        }
    }
    
  • 捕获相机被占用的异常:如果其他应用正在使用相机,调用手电筒方法会抛出CameraAccessException,需捕获并提示用户。

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:00:36