0

I am using pedometer plugin in flutter, and one thing I noticed is that when I open the app after a while, the number of steps displayed does not update until I make steps while the app is opened in order to trigger onData method of the StreamSubscription. It is not setState problem because it updates every second.

Below is part of what I did related to this until now:

class _MyScreenState extends State<MyScreen>
    with AutomaticKeepAliveClientMixin<Page1>, WidgetsBindingObserver {
  StreamSubscription _subscription;
  final Store<AppState> store;

  _MyScreenState(this.store, this.pedometer);

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    setUpPedometer();

}

  void setUpPedometer() {
    _subscription = pedometer.stepCountStream
        .listen(_onData, onError: _onError, cancelOnError: true);
  }

  @override
  Future<Null> didChangeAppLifecycleState(AppLifecycleState state) async {
    if (state == AppLifecycleState.resumed) {
      await resumeCallBack();
    }
  }

  resumeCallBack() {
     // here, I am looking for a way to trigger onData method
  }

  void _onData(int stepCountValue) async {
    print("stepCountValue : ${stepCountValue}");
    store.dispatch(UpdateStepsAction(
        steps: stepCountValue));
}

}
M20
  • 1,032
  • 2
  • 15
  • 34
  • its not clear, is `_onData` called or not? if it is, whats the problem then? – pskink May 21 '19 at 11:59
  • Ok, I will re-write the question. The problem is I want to call _onData myself when the app is resumed, without a real step – M20 May 21 '19 at 12:00
  • its the normal method that takes one `int` parameter... so whats the problem with it? – pskink May 21 '19 at 12:02
  • The problem is I want to access the current stepCountValue in order to update the current steps when the app is resumed; otherwise, the user needs to do some steps for onData to be called. He will see the steps of the last time he opened the app and the steps collected in the background will not be displayed unless he does that. – M20 May 21 '19 at 12:04
  • and `pedometer.stepCountStream` streams always 0, 1, 2, 3 etc? – pskink May 21 '19 at 12:10
  • yes, the stepCountStream works, but is not saved until the user does some steps while the app is opened. I made small update in the code. – M20 May 21 '19 at 12:16
  • you should save the current step number in `didChangeAppLifecycleState` when the `state` is `AppLifecycleState.paused` right? but i dont see it in your code – pskink May 21 '19 at 12:19
  • but the problem is not related to pausing the app, I want to access the last stepCount when the app is resumed without the need for a step to trigger the event. – M20 May 21 '19 at 12:20
  • inside `build` method do something like: `int totalSteps = savedSteps + stepsFromThePedometer` and use it to display the total steps, now inside `resumeCallBack` call `setState(() { savedSteps = getTheSavedSptepsSomehow();});` - it will simply rebuild your `Widget` and you will see the total steps in the next frame, of course you have to call `setState` inside `_onData` too updating `stepsFromThePedometer` variable – pskink May 21 '19 at 12:28
  • I'm looking for how to get `stepsFromThePedometer` without a real step – M20 May 21 '19 at 12:29
  • it is `int stepsFromThePedometer` field in your `_MyScreenState` class – pskink May 21 '19 at 12:30
  • this is the problem I'm having, the stepsFromThePedometer is not updated when the app is resumed unless the user make some steps. So if you open the app after 4 hours of walking, you will not see the current steps unless you make extra steps after you open the app. – M20 May 21 '19 at 12:31
  • call `setState` inside `resumeCallBack` - it will rebuild your widgtet and `build` method will be called – pskink May 21 '19 at 12:33
  • no it did not work, I have countdown on the same screen the setState is called every two seconds. – M20 May 21 '19 at 12:33
  • `setState `is not working? how come? doesnt it rebuild your widget? – pskink May 21 '19 at 12:34
  • no, setState works, but the new steps are not saved because the action is not dispatched (it does not solve the issue, but it works). I need to access to current stepCount from the plugin without a real step – M20 May 21 '19 at 12:35

1 Answers1

0
import 'dart:async';
import 'package:pedometer/pedometer.dart';

class PedometerController{
  static Future<int> getStepsFromPedometer() async{

    StreamController<int> streamHelper = new StreamController();
    var pedometer = Pedometer();
    pedometer.pedometerStream.listen((v){
      streamHelper.sink.add(v);
      streamHelper.close();
    });
    return await whenTrue(streamHelper.stream);
  }

  static Future<int> whenTrue(Stream<int> source) {
    return source.firstWhere((int item) => item > -1);
  }
}
Paltin Yan
  • 21
  • 2
  • 1
    While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained. – borchvm Mar 09 '20 at 13:17