walking.dart 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_activity_recognition/flutter_activity_recognition.dart';
  4. import 'package:geolocator/geolocator.dart' hide ActivityType;
  5. import 'package:rxdart/rxdart.dart';
  6. import '../models/score.dart';
  7. import '../services/walking_services.dart';
  8. class Walking extends StatefulWidget {
  9. Walking({Key? key}) : super(key: key);
  10. @override
  11. State<Walking> createState() => _WalkingState();
  12. }
  13. class _WalkingState extends State<Walking> {
  14. final FlutterActivityRecognition activityRecognition = FlutterActivityRecognition.instance;
  15. final StreamController<Position> _streamController = StreamController.broadcast();
  16. late Stream<dynamic> _activityPositionStream;
  17. num distance = 0;
  18. Position? lastPosition;
  19. num points = 0;
  20. num totalPoints = 0;
  21. num totalDistance = 0;
  22. @override
  23. void initState() {
  24. _activityPositionStream = CombineLatestStream.combine2(
  25. activityRecognition.activityStream,
  26. Geolocator.getPositionStream(locationSettings: LocationSettings(distanceFilter: 0)),
  27. (Activity a, Position b) => [a, b],
  28. );
  29. _activityPositionStream.listen(_calculatePoints);
  30. super.initState();
  31. }
  32. @override
  33. void dispose() {
  34. _streamController.close();
  35. super.dispose();
  36. }
  37. void _updatePoints(num newPoints) {
  38. setState(() {
  39. totalPoints += newPoints;
  40. points += newPoints;
  41. });
  42. }
  43. void _updateDistance(num newDistance) {
  44. setState(() {
  45. totalDistance += newDistance;
  46. });
  47. }
  48. void _calculatePoints(dynamic activityPosition) {
  49. var activity = activityPosition[0] as Activity;
  50. var position = activityPosition[1];
  51. if (activity.type == ActivityType.WALKING || activity.type == ActivityType.RUNNING) {
  52. if (lastPosition != null) {
  53. distance = Geolocator.distanceBetween(
  54. lastPosition!.latitude, lastPosition!.longitude, position.latitude, position.longitude);
  55. _updateDistance(distance);
  56. }
  57. }
  58. if (distance > 0 && activity.type == ActivityType.WALKING) {
  59. _updatePoints(distance / 10);
  60. } else if (distance > 0 && activity.type == ActivityType.RUNNING) {
  61. _updatePoints(distance / 8);
  62. }
  63. if (activity.type != ActivityType.WALKING && activity.type != ActivityType.RUNNING && points.floor() > 0) {
  64. WalkingServices.addScore(Score(points: points.floor(), distance: 0));
  65. setState(() {
  66. points = 0;
  67. });
  68. }
  69. lastPosition = position;
  70. }
  71. @override
  72. Widget build(BuildContext context) {
  73. return Scaffold(
  74. body: Center(
  75. child: Column(
  76. mainAxisAlignment: MainAxisAlignment.center,
  77. children: [
  78. Text(
  79. "Walked distance since start:\n${totalDistance.round()} m",
  80. textAlign: TextAlign.center,
  81. style: const TextStyle(fontSize: 24),
  82. ),
  83. const SizedBox(height: 32),
  84. Text(
  85. "Earned points since start:\n${totalPoints.floor()} pts",
  86. textAlign: TextAlign.center,
  87. style: const TextStyle(fontSize: 24),
  88. ),
  89. ],
  90. ),
  91. ),
  92. );
  93. }
  94. }