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

Android应用手电筒切换异常:仅能打开无法关闭

解决Android手电筒切换状态失效问题

问题根源

你推测的没错:isFlashlightOn初始值被硬设为false,注册TorchCallback后立刻调用toggleFlashlight()时,回调还没来得及获取并更新手电筒的真实初始状态。当手电筒本来处于开启状态时,!isFlashlightOn计算结果为true,调用setTorchMode后还是保持开启,自然无法完成关闭操作。

解决方案

不要依赖回调初始化状态,直接通过CameraManager的getTorchMode()方法获取手电筒的当前真实状态,再执行切换逻辑。这个方法从API 23开始可用,正好适配camera2框架的最低版本要求。

修改后的完整代码

import android.app.Activity;
import android.content.Context;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.os.Bundle;
import android.widget.Toast;

public class FlashlightToggleActivity extends Activity {
    private CameraManager cameraManager;
    private String cameraId;
    private boolean isFlashlightOn = false;

    private final CameraManager.TorchCallback torchCallback = new CameraManager.TorchCallback() {
        @Override
        public void onTorchModeChanged(String cameraId, boolean enabled) {
            super.onTorchModeChanged(cameraId, enabled);
            isFlashlightOn = enabled;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            for (String id : cameraManager.getCameraIdList()) {
                if (cameraManager.getCameraCharacteristics(id).get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
                    cameraId = id;
                    break;
                }
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        if (cameraId == null) {
            Toast.makeText(this, "当前设备不支持手电筒", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

        // 关键:先获取手电筒当前真实状态
        try {
            isFlashlightOn = cameraManager.getTorchMode(cameraId);
        } catch (CameraAccessException e) {
            Toast.makeText(this, "获取手电筒状态失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            e.printStackTrace();
            finish();
            return;
        }

        cameraManager.registerTorchCallback(torchCallback, null);
        toggleFlashlight();
    }

    private void toggleFlashlight() {
        try {
            boolean newState = !isFlashlightOn;
            cameraManager.setTorchMode(cameraId, newState);
            Toast.makeText(this, newState ? "手电筒已开启" : "手电筒已关闭", Toast.LENGTH_SHORT).show();
        } catch (CameraAccessException e) {
            Toast.makeText(this, "切换手电筒状态失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
        } finally {
            finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cameraManager.unregisterTorchCallback(torchCallback);
    }
}

额外注意事项

  • 确保在AndroidManifest.xml中添加必要权限:
    <!-- API 23及以上需要 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- API 26及以上可以更精准地申请 -->
    <uses-permission android:name="android.permission.CAMERA_FLASH" />
    <!-- 声明设备支持手电筒特性 -->
    <uses-feature android:name="android.hardware.camera.flash" android:required="false" />
    
  • 对于Android 6.0+(API 23),需要动态申请CAMERA权限,否则会抛出权限异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:25:10