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

Flutter使用light 3.0.1包获取环境光单值失败:持续输出无法停止

问题:调用ImagePicker后无法停止环境光传感器的持续输出

我在调用ImagePicker获取图片后,使用light 3.0.1包获取环境光传感器的单次数值,但即便调用了.stopListening()函数,程序仍持续打印lux值,无法停止。

调用代码

final light = AmbientLightDetector();
light.startListening();

final image = await ImagePicker().pickImage(source: option);
int luxValue = int.parse(light.luxString);

light.stopListening();
logger.i(luxValue);

AmbientLightDetector类实现

class AmbientLightDetector {
  final logger = Logger();
  String luxString = '';
  Light? light;
  StreamSubscription? subscription;

  void startListening() {
    light = Light();
    try {
      subscription = light?.lightSensorStream.listen(onData);
    } on LightException catch (e) {
      logger.e(e);
    }
  }

  int onData(int luxValue) {
    logger.i(luxValue);
    return luxValue;
  }

  void stopListening() {
    subscription?.cancel();
  }
}

我曾尝试用Duration延迟获取数值,但程序还是持续打印lux值:

light.startListening();

final image = await ImagePicker().pickImage(source: option);
int luxValue = await Future.delayed(
  const Duration(seconds: 1),
  () {
    // 等待1秒后获取当前lux值
    return int.parse(light.luxString);
  },
);
light.stopListening();

解决方案

问题核心在于:现有代码未在获取单次数值后立即终止传感器监听,且luxString从未被正确更新。以下是具体调整方案:

1. 重构AmbientLightDetector类

添加专门的单次数值获取方法,获取到第一个数据后自动取消订阅,避免持续输出:

class AmbientLightDetector {
  final logger = Logger();
  String luxString = '';
  Light? light;
  StreamSubscription? subscription;

  // 获取单次环境光数值,完成后自动停止监听
  Future<int> getSingleLuxValue() async {
    light = Light();
    final completer = Completer<int>();

    try {
      subscription = light?.lightSensorStream.listen((luxValue) {
        logger.i(luxValue);
        luxString = luxValue.toString();
        // 获取到第一个数值后立即终止订阅
        subscription?.cancel();
        subscription = null; // 清空引用避免内存泄漏
        completer.complete(luxValue);
      });
    } on LightException catch (e) {
      logger.e(e);
      completer.completeError(e);
    }

    return completer.future;
  }

  // 手动停止监听的兜底方法
  void stopListening() {
    subscription?.cancel();
    subscription = null;
  }
}

2. 修改调用逻辑

直接使用新方法获取单次数值,无需手动管理start/stop:

final lightDetector = AmbientLightDetector();

final image = await ImagePicker().pickImage(source: option);
// 自动获取单次lux值并停止监听
int luxValue = await lightDetector.getSingleLuxValue();

logger.i(luxValue);
// 可选:兜底调用,确保监听完全终止
lightDetector.stopListening();

关键说明

  • 用Completer将传感器的Stream流转换为Future,实现异步获取单次数值。
  • 监听到第一个数值后立即取消订阅,彻底终止传感器的持续输出。
  • 清空subscription引用,避免内存泄漏和重复取消的潜在问题。

内容的提问来源于stack exchange,提问作者G THARUN KUMAR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 07:32:36