Flutter Web调用setFlashMode在Android Chrome报TypeError问题
Flutter Web启用闪光灯时出现类型错误:
Type Error: true: type 'bool' is not a subtype of type 'JSArray<Object?>?' 问题详情
- 开发Flutter Web应用,需实现手电筒/闪光灯功能
- 在三星Galaxy S21、Google Pixel 6 Pro的Android版Chrome测试,均触发相同错误
- 相机预览、录制功能正常,但调用
controller.setFlashMode(FlashMode.always)时抛出类型错误 - 完整代码如下:
import 'package:flutter/material.dart'; class CameraScreen extends StatefulWidget { const CameraScreen({super.key}); @override State<CameraScreen> createState() => _CameraScreenState(); } class _CameraScreenState extends State<CameraScreen> { late CameraController controller; bool isInitialised = false; Future<void> initialiseCamera() async { final cameras = await availableCameras(); controller = CameraController(cameras.last, ResolutionPreset.max, enableAudio: false); if (!mounted) return; try { await controller.initialize(); setState(() { isInitialised = true; }); } catch (e) { if (e is CameraException) { switch (e.code) { case 'CameraAccessDenied': break; default: break; } } } } void enableFlash() { if (isInitialised) { controller.setFlashMode(FlashMode.always); } } @override void initState() { initialiseCamera(); super.initState(); } @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ Align( alignment: Alignment.center, child: Builder(builder: (context) { if (!isInitialised) { return const CircularProgressIndicator(); } return AspectRatio( aspectRatio: 9 / 16, child: CameraPreview(controller)); }), ), Align( alignment: Alignment.bottomCenter, child: ElevatedButton( onPressed: enableFlash, child: const Text("Flash"), ), ), ], ), ); } }
原因分析
该错误源于Flutter Web的camera插件在处理FlashMode时存在内部类型转换问题,Web端的MediaDevices API与移动端实现逻辑不同,直接调用setFlashMode未做适配导致类型不匹配。
解决方案
方案1:改用Web原生API控制闪光灯
由于Flutter官方camera插件对Web端闪光灯的支持不完善,可直接调用浏览器的MediaDevices API实现功能:
- 在Dart代码中引入
dart:js,调用自定义JS方法:
import 'dart:js' as js; // ... 其他代码保持不变 void enableFlash() { if (isInitialised) { js.context.callMethod('toggleFlash'); } }
- 在
web/index.html中添加JavaScript逻辑:
<script> let flashEnabled = false; async function toggleFlash() { try { // 获取后置摄像头流 const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } }); const videoTrack = stream.getVideoTracks()[0]; // 检查设备是否支持闪光灯 const capabilities = videoTrack.getCapabilities(); if (!capabilities.torch) { console.error('当前设备不支持闪光灯'); return; } // 切换闪光灯状态 flashEnabled = !flashEnabled; await videoTrack.applyConstraints({ advanced: [{ torch: flashEnabled }] }); } catch (err) { console.error('闪光灯控制失败:', err); } } </script>
方案2:升级相机插件并检查配置
- 确保
pubspec.yaml中使用最新版的camera和camera_web插件:
dependencies: flutter: sdk: flutter camera: ^0.10.5+5 camera_web: ^0.3.2+5
- 初始化相机时添加Web端适配配置:
Future<void> initialiseCamera() async { final cameras = await availableCameras(); controller = CameraController( cameras.last, ResolutionPreset.max, enableAudio: false, imageFormatGroup: ImageFormatGroup.jpeg, // Web端推荐格式 ); // ... 其他代码保持不变 }
注意事项
- 需确保用户已授予相机权限,浏览器才允许访问闪光灯
- 部分浏览器或设备可能不支持MediaDevices的torch功能,需做兼容性判断
内容的提问来源于stack exchange,提问作者MikkelT
相关产品推荐
相关产品推荐

