diff --git a/lib/application.dart b/lib/application.dart index b68b8ca..855f3cf 100644 --- a/lib/application.dart +++ b/lib/application.dart @@ -6,6 +6,7 @@ import 'package:lightmeter/data/models/ev_source_type.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'data/light_sensor_service.dart'; import 'data/permissions_service.dart'; import 'data/shared_prefs_service.dart'; import 'environment.dart'; @@ -35,6 +36,7 @@ class Application extends StatelessWidget { Provider(create: (_) => UserPreferencesService(snapshot.data!)), Provider(create: (_) => const HapticsService()), Provider(create: (_) => PermissionsService()), + Provider(create: (_) => const LightSensorService()), ], child: StopTypeProvider( child: ThemeProvider( diff --git a/lib/data/light_sensor_service.dart b/lib/data/light_sensor_service.dart new file mode 100644 index 0000000..2eadebd --- /dev/null +++ b/lib/data/light_sensor_service.dart @@ -0,0 +1,9 @@ +import 'package:light_sensor/light_sensor.dart'; + +class LightSensorService { + const LightSensorService(); + + Future hasSensor() async => await LightSensor.hasSensor ?? false; + + Stream luxStream() => LightSensor.lightSensorStream; +} diff --git a/lib/interactors/metering_interactor.dart b/lib/interactors/metering_interactor.dart index 6a58905..3536aa5 100644 --- a/lib/interactors/metering_interactor.dart +++ b/lib/interactors/metering_interactor.dart @@ -1,13 +1,18 @@ +import 'dart:io'; + import 'package:lightmeter/data/haptics_service.dart'; +import 'package:lightmeter/data/light_sensor_service.dart'; import 'package:lightmeter/data/shared_prefs_service.dart'; class MeteringInteractor { final UserPreferencesService _userPreferencesService; final HapticsService _hapticsService; + final LightSensorService _lightSensorService; const MeteringInteractor( this._userPreferencesService, this._hapticsService, + this._lightSensorService, ); double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration; @@ -25,4 +30,14 @@ class MeteringInteractor { } void enableHaptics(bool enable) => _userPreferencesService.haptics = enable; + + Future hasAmbientLightSensor() async { + if (Platform.isAndroid) { + return _lightSensorService.hasSensor(); + } else { + return false; + } + } + + Stream luxStream() => _lightSensorService.luxStream(); } diff --git a/lib/screens/metering/ev_source/light_sensor/bloc_light_sensor.dart b/lib/screens/metering/ev_source/light_sensor/bloc_light_sensor.dart new file mode 100644 index 0000000..0592223 --- /dev/null +++ b/lib/screens/metering/ev_source/light_sensor/bloc_light_sensor.dart @@ -0,0 +1,45 @@ +import 'dart:async'; +import 'package:lightmeter/interactors/metering_interactor.dart'; +import 'package:lightmeter/screens/metering/ev_source/ev_source_bloc.dart'; +import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart'; +import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart' + as communication_event; +import 'package:lightmeter/screens/metering/communication/state_communication_metering.dart' + as communication_states; +import 'package:lightmeter/utils/log_2.dart'; + +import 'event_light_sensor.dart'; +import 'state_light_sensor.dart'; + +class LightSensorBloc extends EvSourceBloc { + final MeteringInteractor _meteringInteractor; + + StreamSubscription? _luxSubscriptions; + + LightSensorBloc( + MeteringCommunicationBloc communicationBloc, + this._meteringInteractor, + ) : super( + communicationBloc, + const LightSensorInitState(), + ); + + @override + void onCommunicationState(communication_states.SourceState communicationState) { + if (communicationState is communication_states.MeasureState) { + if (_luxSubscriptions == null) { + _luxSubscriptions = _meteringInteractor.luxStream().listen((event) { + communicationBloc.add(communication_event.MeasuredEvent(log2(event.toDouble() / 2.5))); + }); + } else { + _luxSubscriptions?.cancel().then((_) => _luxSubscriptions = null); + } + } + } + + @override + Future close() async { + _luxSubscriptions?.cancel().then((_) => _luxSubscriptions = null); + return super.close(); + } +} diff --git a/lib/screens/metering/ev_source/light_sensor/event_light_sensor.dart b/lib/screens/metering/ev_source/light_sensor/event_light_sensor.dart new file mode 100644 index 0000000..bfbe89b --- /dev/null +++ b/lib/screens/metering/ev_source/light_sensor/event_light_sensor.dart @@ -0,0 +1,3 @@ +abstract class LightSensorEvent { + const LightSensorEvent(); +} diff --git a/lib/screens/metering/ev_source/light_sensor/state_light_sensor.dart b/lib/screens/metering/ev_source/light_sensor/state_light_sensor.dart new file mode 100644 index 0000000..ee76c8f --- /dev/null +++ b/lib/screens/metering/ev_source/light_sensor/state_light_sensor.dart @@ -0,0 +1,7 @@ +abstract class LightSensorState { + const LightSensorState(); +} + +class LightSensorInitState extends LightSensorState { + const LightSensorInitState(); +} diff --git a/lib/screens/metering/ev_source/random_ev/bloc_random_ev.dart b/lib/screens/metering/ev_source/random_ev/bloc_random_ev.dart deleted file mode 100644 index 1d72bed..0000000 --- a/lib/screens/metering/ev_source/random_ev/bloc_random_ev.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'dart:math'; -import 'package:lightmeter/screens/metering/ev_source/ev_source_bloc.dart'; -import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart'; -import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart' - as communication_event; -import 'package:lightmeter/screens/metering/communication/state_communication_metering.dart' - as communication_states; - -import 'event_random_ev.dart'; -import 'state_random_ev.dart'; - -class RandomEvBloc extends EvSourceBloc { - final random = Random(); - - RandomEvBloc(MeteringCommunicationBloc communicationBloc) - : super( - communicationBloc, - RandomEvState(Random().nextDouble() * 15), - ); - - @override - void onCommunicationState(communication_states.SourceState communicationState) { - if (communicationState is communication_states.MeasureState) { - communicationBloc.add(communication_event.MeasuredEvent(random.nextDouble() * 15)); - } - } -} diff --git a/lib/screens/metering/ev_source/random_ev/event_random_ev.dart b/lib/screens/metering/ev_source/random_ev/event_random_ev.dart deleted file mode 100644 index 61e5e54..0000000 --- a/lib/screens/metering/ev_source/random_ev/event_random_ev.dart +++ /dev/null @@ -1,3 +0,0 @@ -abstract class RandomEvEvent { - const RandomEvEvent(); -} diff --git a/lib/screens/metering/ev_source/random_ev/state_random_ev.dart b/lib/screens/metering/ev_source/random_ev/state_random_ev.dart deleted file mode 100644 index 1bbec89..0000000 --- a/lib/screens/metering/ev_source/random_ev/state_random_ev.dart +++ /dev/null @@ -1,5 +0,0 @@ -class RandomEvState { - final double ev; - - const RandomEvState(this.ev); -} diff --git a/lib/screens/metering/flow_metering.dart b/lib/screens/metering/flow_metering.dart index 5204301..fa785d6 100644 --- a/lib/screens/metering/flow_metering.dart +++ b/lib/screens/metering/flow_metering.dart @@ -1,14 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lightmeter/data/haptics_service.dart'; +import 'package:lightmeter/data/light_sensor_service.dart'; import 'package:lightmeter/data/models/ev_source_type.dart'; import 'package:lightmeter/data/models/photography_values/photography_value.dart'; import 'package:lightmeter/data/shared_prefs_service.dart'; import 'package:lightmeter/interactors/metering_interactor.dart'; +import 'package:lightmeter/screens/metering/ev_source/light_sensor/bloc_light_sensor.dart'; import 'package:provider/provider.dart'; import 'ev_source/camera/bloc_camera.dart'; -import 'ev_source/random_ev/bloc_random_ev.dart'; import 'bloc_metering.dart'; import 'communication/bloc_communication_metering.dart'; import 'screen_metering.dart'; @@ -18,10 +19,12 @@ class MeteringFlow extends StatelessWidget { @override Widget build(BuildContext context) { + final sourceType = context.watch(); return Provider( create: (context) => MeteringInteractor( context.read(), context.read(), + context.read(), ), child: MultiBlocProvider( providers: [ @@ -34,16 +37,19 @@ class MeteringFlow extends StatelessWidget { context.read(), ), ), - BlocProvider( - create: (context) => CameraBloc( - context.read(), - context.read(), - ), - ), - if (context.read() == EvSourceType.sensor) + if (sourceType == EvSourceType.camera) BlocProvider( - lazy: false, - create: (context) => RandomEvBloc(context.read()), + create: (context) => CameraBloc( + context.read(), + context.read(), + ), + ), + if (sourceType == EvSourceType.sensor) + BlocProvider( + create: (context) => LightSensorBloc( + context.read(), + context.read(), + ), ), ], child: const MeteringScreen(), diff --git a/pubspec.yaml b/pubspec.yaml index e5f51f3..9de9f32 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,6 +17,7 @@ dependencies: sdk: flutter intl: 0.17.0 intl_utils: 2.8.1 + light_sensor: 2.0.2 material_color_utilities: 0.2.0 package_info_plus: 3.0.2 permission_handler: 10.2.0