0

I am using the dB meter app to record noise and show it in decibels with periodic intervals. And I am printing decibels for every second. The app is working fine when active but when I press square button on android (That is pause the app) the decibel reading print -Infinity and the same thig happening when I click on circle button on android (that is inactive mode of the app). The original app git hub source - noise meter app source code.

And what I added to make automatic start and stop is this

  Timer? _iStop;
  Timer? _isStart;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
    _noiseMeter = NoiseMeter(onError);
    _iStop = Timer.periodic(Duration(seconds: 20), (timer){
      setState(() {
        stop();
      });
    });
    _isStart = Timer.periodic(Duration(seconds: 40), (timer){
      setState(() {
        start();
      });
    });
  }

The app starting and stoping with regular time intervals with above mentioned time in the code. but the problem is when I pause or minimize the it is printing -Infinity as decibel reading.

I tried: didChangeAppLifecycleState method but this is to run or pause the app in the background. anyway our app is running in the background. Only thing is that it is showing -Infinity decibel when paused or minimized. Thanks in advance


main.dart

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'app.dart';

ThemeMode appTheme = ThemeMode.system; //dark / light

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // debugShowCheckedModeBanner: false,
      title: 'db Meter',
      home: NoiseApp(),
      darkTheme: ThemeData.dark().copyWith(
        textTheme: ThemeData.dark().textTheme.apply(
              fontFamily: GoogleFonts.comfortaa().fontFamily,
            ),
        primaryTextTheme: ThemeData.dark().textTheme.apply(
              fontFamily: GoogleFonts.comfortaa().fontFamily,
            ),
        accentTextTheme: ThemeData.dark().textTheme.apply(
              fontFamily: GoogleFonts.comfortaa().fontFamily,
            ),
      ),
      theme: ThemeData(
        fontFamily: GoogleFonts.comfortaa().fontFamily,
      ),
      themeMode: appTheme,
    );
  }
}

app.dart

// https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/dynamic_updates/live_update/real_time_line_chart.dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:noise_meter/noise_meter.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:url_launcher/url_launcher.dart';

class NoiseApp extends StatefulWidget {
  @override
  _NoiseAppState createState() => _NoiseAppState();
}

class _NoiseAppState extends State<NoiseApp> {
  bool _isRecording = false;
  // ignore: cancel_subscriptions
  StreamSubscription<NoiseReading>? _noiseSubscription;
  late NoiseMeter _noiseMeter;
  double? maxDB;
  double? meanDB;
  List<_ChartData> chartData = <_ChartData>[];
  // ChartSeriesController? _chartSeriesController;
  late int previousMillis;
  Timer? _iStop;
  Timer? _isStart;

  @override
  void initState() {
    super.initState();
    _noiseMeter = NoiseMeter(onError);
    _iStop = Timer.periodic(Duration(seconds: 20), (timer){
      setState(() {
        stop();
      });
    });
    _isStart = Timer.periodic(Duration(seconds: 40), (timer){
      setState(() {
        start();
      });
    });
  }

  void onData(NoiseReading noiseReading) {
    this.setState(() {
      if (!this._isRecording) this._isRecording = true;
    });
    maxDB = noiseReading.maxDecibel;
    meanDB = noiseReading.meanDecibel;

    chartData.add(
      _ChartData(
        maxDB,
        meanDB,
        ((DateTime.now().millisecondsSinceEpoch - previousMillis) / 1000)
            .toDouble(),
      ),
    );
    print("max db $maxDB");
  }

  void onError(Object e) {
    print(e.toString());
    _isRecording = false;
  }

  void start() async {
    previousMillis = DateTime.now().millisecondsSinceEpoch;
    try {
      _noiseSubscription = _noiseMeter.noiseStream.listen(onData);
    } catch (e) {
      print(e);
    }
  }

  void stop() async {
    try {
      _noiseSubscription!.cancel();
      _noiseSubscription = null;

      this.setState(() => this._isRecording = false);
    } catch (e) {
      print('stopRecorder error: $e');
    }
    previousMillis = 0;
    chartData.clear();
  }

  void copyValue(
    bool theme,
  ) {
    Clipboard.setData(
      ClipboardData(
          text: 'It\'s about ${maxDB!.toStringAsFixed(1)}dB loudness'),
    ).then((_) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          behavior: SnackBarBehavior.floating,
          duration: Duration(milliseconds: 2500),
          content: Row(
            children: [
              Icon(
                Icons.check,
                size: 14,
                color: theme ? Colors.white70 : Colors.black,
              ),
              SizedBox(width: 10),
              Text('Copied')
            ],
          ),
        ),
      );
    });
  }

  openGithub() async {
    const url = 'https://github.com/iqfareez/noise_meter_flutter';
    try {
      await launch(url);
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
        content: Text('Could not launch $url'),
        backgroundColor: Colors.red,
      ));
    }
  }

  @override
  Widget build(BuildContext context) {
    bool _isDark = Theme.of(context).brightness == Brightness.light;
    if (chartData.length >= 25) {
      chartData.removeAt(0);
    }
    return Scaffold(
      appBar: AppBar(
        backgroundColor: _isDark ? Colors.green : Colors.green.shade800,
        title: Text('dB Sound Meter'),
        actions: [
          IconButton(
              tooltip: 'Source code on GitHub',
              icon: Icon(Icons.code_outlined),
              onPressed: openGithub),
          IconButton(
            tooltip: 'Copy value to clipboard',
            icon: Icon(Icons.copy),
            onPressed: maxDB != null ? () => copyValue(_isDark) : null,
          )
        ],
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: FloatingActionButton.extended(
        label: Text(_isRecording ? 'Stop' : 'Start'),
        onPressed: _isRecording ? stop : start,
        icon: !_isRecording ? Icon(Icons.circle) : null,
        backgroundColor: _isRecording ? Colors.red : Colors.green,
      ),
      body: Container(
        child: Column(
          children: [
            Expanded(
              flex: 2,
              child: Center(
                child: Text(
                  maxDB != null ? maxDB!.toStringAsFixed(2) : 'Press start',
                  style: GoogleFonts.exo2(fontSize: 76),
                ),
              ),
            ),
            Text(
              meanDB != null
                  ? 'Mean: ${meanDB!.toStringAsFixed(2)}'
                  : 'Awaiting data',
              style: TextStyle(fontWeight: FontWeight.w300, fontSize: 14),
            ),
            Expanded(
              child: SfCartesianChart(
                series: <LineSeries<_ChartData, double>>[
                  LineSeries<_ChartData, double>(
                      dataSource: chartData,
                      xAxisName: 'Time',
                      yAxisName: 'dB',
                      name: 'dB values over time',
                      xValueMapper: (_ChartData value, _) => value.frames,
                      yValueMapper: (_ChartData value, _) => value.maxDB,
                      animationDuration: 0),
                ],
              ),
            ),
            SizedBox(
              height: 68,
            ),
          ],
        ),
      ),
    );
  }
}

class _ChartData {
  final double? maxDB;
  final double? meanDB;
  final double frames;

  _ChartData(this.maxDB, this.meanDB, this.frames);
}

pubspec.yaml

name: noise_meter_flutter
description: Sound meter

publish_to: "none"

version: 1.1.0-f+3

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  # cupertino_icons: ^1.0.0
  noise_meter: ^3.0.1
  syncfusion_flutter_charts: ^19.1.67
  url_launcher: ^6.0.6
  google_fonts: ^2.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true

when screen visible:

image when running the app on screen visibel to the user

Whe the app is paused or minimized:

image when the app is paused or minimized that is not visible to the user

pmatatias
  • 3,491
  • 3
  • 10
  • 30
yellesh
  • 1
  • 1

0 Answers0