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

Android应用从手机启动时手电筒不闪烁仅Studio启动有效问题

手电筒应用启动异常解决方案

问题现象

  • 通过Android Studio构建安装后启动,手电筒可正常闪烁
  • 直接从手机桌面启动应用,手电筒无任何反应

需求目标

实现应用无论通过Android Studio调试启动还是手机桌面手动启动,均能自动触发手电筒闪烁。

问题根源

  1. 权限缺失:调试模式下Android Studio可能自动帮应用授予了相机权限,但手动启动时应用未主动申请权限,导致调用手电筒接口被系统静默拦截。
  2. 无权限校验逻辑:代码中直接调用手电筒控制接口,未处理权限未授予的情况。
  3. 生命周期逻辑不完善:仅在onCreate启动闪烁逻辑,但未在onResume中恢复,可能导致后台切换后功能失效。
  4. 缺少设备兼容性检查:未验证设备是否支持闪光灯,存在崩溃风险。

解决步骤

1. 添加权限声明

在AndroidManifest.xml中添加相机权限(控制手电筒需要此权限):

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

2. 修改MainActivity代码

完善权限申请、兼容性检查及生命周期处理:

package com.example.myflashlight

import android.content.Context
import android.content.pm.PackageManager
import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class MainActivity : AppCompatActivity() {
    private val CAMERA_PERMISSION_REQUEST_CODE = 1001
    private lateinit var cameraManager: CameraManager
    private var cameraId: String? = null
    private lateinit var handler: Handler
    private var isFlashOn = false
    private var isPermissionGranted = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
        handler = Handler(Looper.getMainLooper())
        
        // 检查权限和设备兼容性
        checkPrerequisites()
    }

    private fun checkPrerequisites() {
        // 检查相机权限
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            isPermissionGranted = true
            checkFlashSupport()
        } else {
            // 动态申请权限
            ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.CAMERA), CAMERA_PERMISSION_REQUEST_CODE)
        }
    }

    private fun checkFlashSupport() {
        try {
            for (id in cameraManager.cameraIdList) {
                val characteristics = cameraManager.getCameraCharacteristics(id)
                val isFlashAvailable = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE)
                if (isFlashAvailable == true) {
                    cameraId = id
                    startBlinking()
                    return
                }
            }
            // 设备不支持闪光灯,可在此处添加提示逻辑
        } catch (e: CameraAccessException) {
            e.printStackTrace()
        }
    }

    private fun startBlinking() {
        handler.removeCallbacks(blinkRunnable)
        handler.post(blinkRunnable)
    }

    private val blinkRunnable = object : Runnable {
        @RequiresApi(Build.VERSION_CODES.M)
        override fun run() {
            if (!isPermissionGranted || cameraId == null) return
            
            if (isFlashOn) {
                turnFlashOff()
            } else {
                turnFlashOn()
            }
            handler.postDelayed(this, 1000)
        }
    }

    @RequiresApi(Build.VERSION_CODES.M)
    private fun turnFlashOn() {
        try {
            cameraId?.let {
                cameraManager.setTorchMode(it, true)
                isFlashOn = true
            }
        } catch (e: CameraAccessException) {
            e.printStackTrace()
        }
    }

    @RequiresApi(Build.VERSION_CODES.M)
    private fun turnFlashOff() {
        try {
            cameraId?.let {
                cameraManager.setTorchMode(it, false)
                isFlashOn = false
            }
        } catch (e: CameraAccessException) {
            e.printStackTrace()
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                isPermissionGranted = true
                checkFlashSupport()
            }
        }
    }

    @RequiresApi(Build.VERSION_CODES.M)
    override fun onPause() {
        super.onPause()
        handler.removeCallbacks(blinkRunnable)
        if (isFlashOn) {
            turnFlashOff()
        }
    }

    override fun onResume() {
        super.onResume()
        if (isPermissionGranted && cameraId != null) {
            startBlinking()
        }
    }
}

关键改进点

  • 新增动态权限申请流程,确保手动启动时能获取相机权限
  • 添加闪光灯兼容性检查,避免在无闪光灯设备上执行无效操作
  • 优化cameraId的初始化逻辑,确保找到支持闪光灯的相机
  • 在onResume中恢复闪烁逻辑,解决后台切回后功能停止的问题
  • 增加权限校验,避免无权限时执行手电筒控制操作

内容的提问来源于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.19 23:35:38