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

