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
相关产品推荐
相关产品推荐

