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

Android 12模拟器中Flutter camera插件takePicture方法无响应

Camera插件takePicture()方法阻塞无响应问题

环境信息

  • camera插件版本:0.10.5+2
  • 测试环境:Android 12 Pixel 6模拟器

问题现象

调用CameraController.takePicture()方法时,程序出现卡死或进入无限循环,后续代码无法执行,且无任何异常抛出。例如以下两个示例中,print('A picture was captured.')语句始终不会执行:

无状态组件示例

import 'package:flutter/material.dart';
import 'package:camera/camera.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final cameraController = CameraController(
    (await availableCameras())[0],
    ResolutionPreset.max,
  );

  await cameraController.initialize();

  final app = MaterialApp(
    home: CameraScreen(
      controller: cameraController,
    ),
  );

  runApp(app);
}

class CameraScreen extends StatelessWidget {
  const CameraScreen({
    super.key,
    required this.controller,
  });

  final CameraController controller;

  Future<void> takePicture() async {
    await controller.takePicture(); // 此调用永远不会返回
    print('A picture was captured.'); // 该行代码永远不会执行
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            CameraPreview(controller),
            ElevatedButton(
              onPressed: takePicture,
              child: const Text('TAKE PICTURE'),
            )
          ],
        ),
      ),
    );
  }
}

有状态组件示例

import 'package:flutter/material.dart';
import 'package:camera/camera.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final app = MaterialApp(
    home: CameraScreen(
      description: (await availableCameras())[0],
    ),
  );

  runApp(app);
}

class CameraScreen extends StatefulWidget {
  const CameraScreen({
    super.key,
    required this.description,
  });

  final CameraDescription description;

  @override
  State<CameraScreen> createState() => _CameraScreenState();
}

class _CameraScreenState extends State<CameraScreen> {
  late CameraController controller;

  Future<void> takePicture() async {
    await controller.takePicture(); // 此调用永远不会返回
    print('A picture was captured.'); // 该行代码永远不会执行
  }

  @override
  void initState() {
    controller = CameraController(
      widget.description,
      ResolutionPreset.max,
    );

    if (controller.value.isInitialized == false) {
      controller.initialize();
    }

    super.initState();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            CameraPreview(controller),
            ElevatedButton(
              onPressed: takePicture,
              child: const Text('TAKE PICTURE'),
            )
          ],
        ),
      ),
    );
  }
}

解决方案

1. 确保相机完全初始化后再操作

有状态组件示例中,initState里的相机初始化未使用await,也未监听初始化状态,可能导致拍照时相机未就绪引发阻塞。修改初始化逻辑:

@override
void initState() {
  super.initState();
  controller = CameraController(
    widget.description,
    ResolutionPreset.max,
  );
  _initCamera();
}

Future<void> _initCamera() async {
  try {
    await controller.initialize();
    if (mounted) setState(() {});
  } catch (e) {
    print('相机初始化失败: $e');
  }
}

2. 给拍照方法添加状态检查与异常捕获

增加相机状态校验,防止重复调用,并捕获可能的异常:

Future<void> takePicture() async {
  if (!controller.value.isInitialized) {
    print('相机未初始化');
    return;
  }
  if (controller.value.isTakingPicture) {
    return; // 避免重复触发拍照
  }
  try {
    final XFile picture = await controller.takePicture();
    print('照片已保存至: ${picture.path}');
  } catch (e) {
    print('拍照失败: $e');
  }
}

3. 升级camera插件版本

0.10.5+2版本存在Android 12兼容性问题,建议升级至最新稳定版(如0.13.x及以上),新版本修复了多个平台适配bug。

4. 调整模拟器配置

  • 在AVD管理器中,确保目标设备的相机功能已启用(进入设备的“Show Advanced Settings”,将Camera选项设置为“Emulated”或关联真实相机)
  • 尝试降低分辨率预设,例如使用ResolutionPreset.medium代替max,高分辨率在模拟器上易引发性能瓶颈

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 03:10:40