#12 feature/walking

Слито
iwa-24 слито 5 коммит(ов) из iwa-13/feature/walking в iwa-13/main 3 лет назад

+ 3 - 0
app/android/app/src/main/AndroidManifest.xml

@@ -4,6 +4,9 @@
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
+    <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
    <application
         android:label="PhysiGo"
         android:name="${applicationName}"

+ 6 - 2
app/lib/main.dart

@@ -30,12 +30,16 @@ class PhysiGo extends StatelessWidget {
       ),
       initialRoute: '/',
       routes: {
-        '/': (context) => MyHomePage(title: '',),
+        '/': (context) => MyHomePage(
+              title: '',
+            ),
         '/register': (context) => SignupPage(),
         //'/register2': (context) => RegisterScreen2(title: ''),
         //'/register3': (context) => RegisterScreen3(title: ''),
         '/login': (context) => LogIn(title: ''),
-        '/profilePage': (context) => ProfilePage(title: '',),
+        '/profilePage': (context) => ProfilePage(
+              title: '',
+            ),
         '/mainPage': (context) => MainPage()
       },
       //home: const MyHomePage(title: 'Flutter Demo Home Page'),

+ 2 - 5
app/lib/mainPage.dart

@@ -1,4 +1,5 @@
 import 'package:flutter/material.dart';
+import 'package:physigo/walking/walking_permission.dart';
 
 class MainPage extends StatefulWidget {
   const MainPage({Key? key}) : super(key: key);
@@ -30,11 +31,7 @@ class _MainPage extends State<MainPage> {
           ),
         ),
       ),
-      body: Center(
-        child: Column(
-        ),
-
-      ),
+      body: WalkingPermission()
     );
   }
 }

+ 10 - 0
app/lib/walking/models/score.dart

@@ -0,0 +1,10 @@
+class Score {
+  int points;
+  int distance;
+
+  Score({required this.points, required this.distance});
+
+  Map<String, dynamic> toMap(){
+      return{"points" : points, "distance": distance};
+  }
+}

+ 35 - 0
app/lib/walking/services/walking_services.dart

@@ -0,0 +1,35 @@
+import 'package:cloud_firestore/cloud_firestore.dart';
+import 'package:firebase_auth/firebase_auth.dart';
+
+import '../models/score.dart';
+
+class WalkingServices {
+  static final db = FirebaseFirestore.instance;
+
+  static dynamic addScore(Score score) async {
+    // final user = {"score": score.points, "distance": score.distance};
+    final walkingScore = await db
+        .collection("WalkingScores")
+        .where("user", isEqualTo: FirebaseAuth.instance.currentUser?.uid)
+        .get();
+    if(walkingScore.docs.isEmpty){
+      db
+      .collection("WalkingScores")
+      .add({"score":score.points,"user":FirebaseAuth.instance.currentUser?.uid });
+    }
+    else{
+      db
+          .collection("WalkingScores")
+          .doc(walkingScore.docs.first.id)
+          .update({"score": walkingScore.docs.first.get("score") + score.points});
+    }
+    final user = await db
+    .collection("profileInfo")
+    .doc(FirebaseAuth.instance.currentUser?.uid).get();
+    db
+    .collection("profileInfo")
+    .doc(FirebaseAuth.instance.currentUser?.uid)
+    .update({"total_points":user.get("total_points") + score.points});
+
+  }
+}

+ 136 - 0
app/lib/walking/walking_counter.dart

@@ -0,0 +1,136 @@
+import 'dart:async';
+import 'package:flutter/material.dart';
+import 'package:flutter_activity_recognition/flutter_activity_recognition.dart';
+import 'package:geolocator/geolocator.dart' hide ActivityType;
+import 'package:rxdart/rxdart.dart';
+import 'models/score.dart';
+import 'services/walking_services.dart';
+
+class WalkingCounter extends StatefulWidget {
+  WalkingCounter({Key? key}) : super(key: key);
+
+  @override
+  State<WalkingCounter> createState() => _WalkingCounterState();
+}
+
+class _WalkingCounterState extends State<WalkingCounter> {
+  final FlutterActivityRecognition activityRecognition =
+      FlutterActivityRecognition.instance;
+  final StreamController<Position> _streamController =
+      StreamController.broadcast();
+  final StreamController<ActivityType> _simulatedActivityController =
+      StreamController.broadcast();
+  late Stream<dynamic> _activityPositionStream;
+
+  num distance = 0;
+  Position? lastPosition;
+  num points = 0;
+
+  @override
+  void initState() {
+    // _simulatedActivityController.stream.listen(print);
+    // activityRecognition.activityStream.listen((event) {
+    //   print(event.type);
+    // });
+    _activityPositionStream = CombineLatestStream.combine2(
+      _simulatedActivityController.stream,
+      Geolocator.getPositionStream(
+          locationSettings: LocationSettings(distanceFilter: 0)),
+      (ActivityType a, Position b) => [a, b],
+    );
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _streamController.close();
+    super.dispose();
+  }
+
+  void addScore() {
+    WalkingServices.addScore(Score(points: 45, distance: 500));
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    Geolocator.getPositionStream(
+            locationSettings: LocationSettings(distanceFilter: 0))
+        .listen((position) {
+      _streamController.add(position);
+      print(position);
+    });
+    return Scaffold(
+      body: Center(
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            ElevatedButton(
+              onPressed: () =>
+                  _simulatedActivityController.add(ActivityType.WALKING),
+              child: Text("WALKING"),
+            ),
+            ElevatedButton(
+              onPressed: () =>
+                  _simulatedActivityController.add(ActivityType.RUNNING),
+              child: Text("RUNNING"),
+            ),
+            ElevatedButton(
+              onPressed: () =>
+                  _simulatedActivityController.add(ActivityType.STILL),
+              child: Text("STILL"),
+            ),
+            StreamBuilder<dynamic>(
+              stream: _activityPositionStream,
+              builder: (context, snapshot) {
+                if (!snapshot.hasData) {
+                  return CircularProgressIndicator();
+                }
+                var activity = snapshot.data![0];
+                var position = snapshot.data![1];
+                if (activity == ActivityType.WALKING || activity == ActivityType.RUNNING) {
+                  if (lastPosition != null) {
+                    distance = Geolocator.distanceBetween(
+                        lastPosition!.latitude,
+                        lastPosition!.longitude,
+                        position.latitude,
+                        position.longitude);
+                  }
+                }
+                if (distance > 0 && activity == ActivityType.WALKING) {
+                   points += distance / 10;
+                }
+                else if (distance > 0 && activity == ActivityType.RUNNING){
+                   points += distance / 8;
+                }
+                if (activity != ActivityType.WALKING && activity != ActivityType.RUNNING && points>0){
+                  WalkingServices.addScore(Score(
+                      points: points.floor(),distance: 0)
+
+                  );
+                  points=0;
+                }
+                lastPosition = position;
+                print(distance);
+                return Text("$distance");
+              },
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+/*
+Get distance only when walking or running
+
+if (walking || running) {
+  calculateScore()
+}
+*/
+
+// --W---R----W----S----W------
+
+// --P--P--P--P--P--P
+
+// --[W,P]--[W,P]--[R,P]--

+ 79 - 0
app/lib/walking/walking_permission.dart

@@ -0,0 +1,79 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_activity_recognition/flutter_activity_recognition.dart';
+import 'package:flutter_activity_recognition/models/permission_request_result.dart';
+import 'package:geolocator/geolocator.dart';
+import 'package:physigo/walking/walking_counter.dart';
+
+class WalkingPermission extends StatelessWidget {
+  WalkingPermission({Key? key}) : super(key: key);
+  final FlutterActivityRecognition activityRecognition =
+      FlutterActivityRecognition.instance;
+
+  @override
+  Widget build(BuildContext context) {
+    return(
+     FutureBuilder(
+        future: Future.wait([isPermissionGrants(), _getPermissions()]),
+        builder: (context, snapshot) {
+          if (snapshot.connectionState == ConnectionState.waiting) {
+            return CircularProgressIndicator();
+          } else if (snapshot.hasError) {
+            return Text("Error");
+          } else {
+            return WalkingCounter();
+          }
+        },
+      )
+    );
+  }
+
+  Future<void> isPermissionGrants() async {
+    // Check if the user has granted permission. If not, request permission.
+    PermissionRequestResult reqResult;
+    reqResult = await activityRecognition.checkPermission();
+    if (reqResult == PermissionRequestResult.PERMANENTLY_DENIED) {
+      print('Permission is permanently denied.');
+      return Future.error('Activity permissions are denied');
+    } else if (reqResult == PermissionRequestResult.DENIED) {
+      reqResult = await activityRecognition.requestPermission();
+      if (reqResult != PermissionRequestResult.GRANTED) {
+        print('Permission is denied.');
+        return Future.error('Activity permissions are denied');
+      }
+    }
+  }
+
+  Future<void> _getPermissions() async {
+    bool serviceEnabled;
+    LocationPermission permission;
+
+    // Test if location services are enabled.
+    serviceEnabled = await Geolocator.isLocationServiceEnabled();
+    if (!serviceEnabled) {
+      // Location services are not enabled don't continue
+      // accessing the position and request users of the
+      // App to enable the location services.
+      return Future.error('Location services are disabled.');
+    }
+
+    permission = await Geolocator.checkPermission();
+    if (permission == LocationPermission.denied) {
+      permission = await Geolocator.requestPermission();
+      if (permission == LocationPermission.denied) {
+        // Permissions are denied, next time you could try
+        // requesting permissions again (this is also where
+        // Android's shouldShowRequestPermissionRationale
+        // returned true. According to Android guidelines
+        // your App should show an explanatory UI now.
+        return Future.error('Location permissions are denied');
+      }
+    }
+
+    if (permission == LocationPermission.deniedForever) {
+      // Permissions are denied forever, handle appropriately.
+      return Future.error(
+          'Location permissions are permanently denied, we cannot request permissions.');
+    }
+  }
+}

+ 9 - 2
app/pubspec.lock

@@ -160,6 +160,13 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_activity_recognition:
+    dependency: "direct main"
+    description:
+      name: flutter_activity_recognition
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.3.0"
   flutter_compass:
     dependency: transitive
     description:
@@ -199,12 +206,12 @@ packages:
     source: sdk
     version: "0.0.0"
   geolocator:
-    dependency: transitive
+    dependency: "direct main"
     description:
       name: geolocator
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "8.2.0"
+    version: "8.2.1"
   geolocator_android:
     dependency: transitive
     description:

+ 2 - 0
app/pubspec.yaml

@@ -46,6 +46,8 @@ dependencies:
   firebase_messaging: ^11.4.0
   awesome_notifications: ^0.6.21
   firebase_auth: ^3.3.17
+  flutter_activity_recognition: ^1.3.0
+  geolocator: ^8.2.1
 
 dev_dependencies:
   flutter_test: