如何使用传感器颤振包来开发步进计数器?

时间:2018-06-02 10:32:40

标签: dart flutter google-fit google-fit-sdk flutter-dependencies

我正试图在传感器颤振小部件的帮助下制作一个计步器,我正在查看传感器颤振包代码,但没有从哪里开始获取单点以及如何实现所需的结果。

在传感器颤振小部件的帮助下迈出了什么步骤?或者我也可以在一个颤动的应用程序中使用Google Fit Api来创建自定义步骤计数器。

我添加了

dependencies:
  sensors: "^0.3.3"

到pubspec.yaml

main.dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:sensors/sensors.dart';

import 'snake.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Sensors Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const int _snakeRows = 20;
  static const int _snakeColumns = 20;
  static const double _snakeCellSize = 10.0;

  List<double> _accelerometerValues;
  List<double> _userAccelerometerValues;
  List<double> _gyroscopeValues;
  List<StreamSubscription<dynamic>> _streamSubscriptions =
  <StreamSubscription<dynamic>>[];

  @override
  Widget build(BuildContext context) {
    final List<String> accelerometer =
    _accelerometerValues?.map((double v) => v.toStringAsFixed(1))?.toList();
    final List<String> gyroscope =
    _gyroscopeValues?.map((double v) => v.toStringAsFixed(1))?.toList();
    final List<String> userAccelerometer = _userAccelerometerValues
        ?.map((double v) => v.toStringAsFixed(1))
        ?.toList();

    return new Scaffold(
      appBar: new AppBar(
        title: const Text('Sensor Example'),
      ),
      body: new Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          new Center(
            child: new DecoratedBox(
              decoration: new BoxDecoration(
                border: new Border.all(width: 1.0, color: Colors.black38),
              ),
              child: new SizedBox(
                height: _snakeRows * _snakeCellSize,
                width: _snakeColumns * _snakeCellSize,
                child: new Snake(
                  rows: _snakeRows,
                  columns: _snakeColumns,
                  cellSize: _snakeCellSize,
                ),
              ),
            ),
          ),
          new Padding(
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                new Text('Accelerometer: $accelerometer'),
              ],
            ),
            padding: const EdgeInsets.all(16.0),
          ),
          new Padding(
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                new Text('UserAccelerometer: $userAccelerometer'),
              ],
            ),
            padding: const EdgeInsets.all(16.0),
          ),
          new Padding(
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                new Text('Gyroscope: $gyroscope'),
              ],
            ),
            padding: const EdgeInsets.all(16.0),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    for (StreamSubscription<dynamic> subscription in _streamSubscriptions) {
      subscription.cancel();
    }
  }

  @override
  void initState() {
    super.initState();
    _streamSubscriptions
        .add(accelerometerEvents.listen((AccelerometerEvent event) {
      setState(() {
        _accelerometerValues = <double>[event.x, event.y, event.z];
      });
    }));
    _streamSubscriptions.add(gyroscopeEvents.listen((GyroscopeEvent event) {
      setState(() {
        _gyroscopeValues = <double>[event.x, event.y, event.z];
      });
    }));
    _streamSubscriptions
        .add(userAccelerometerEvents.listen((UserAccelerometerEvent event) {
      setState(() {
        _userAccelerometerValues = <double>[event.x, event.y, event.z];
      });
    }));
  }
}

snake.dart

import 'dart:async';
import 'dart:math' as math;

import 'package:flutter/material.dart';
import 'package:sensors/sensors.dart';

class Snake extends StatefulWidget {
  final int rows;
  final int columns;
  final double cellSize;
  Snake({this.rows = 20, this.columns = 20, this.cellSize = 10.0}) {
    assert(10 <= rows);
    assert(10 <= columns);
    assert(5.0 <= cellSize);
  }

  @override
  State<StatefulWidget> createState() =>
      new SnakeState(rows, columns, cellSize);
}

class SnakeBoardPainter extends CustomPainter {
  GameState state;
  double cellSize;

  SnakeBoardPainter(this.state, this.cellSize);

  @override
  void paint(Canvas canvas, Size size) {
    final Paint blackLine = new Paint()..color = Colors.black;
    final Paint blackFilled = new Paint()
      ..color = Colors.black
      ..style = PaintingStyle.fill;
    canvas.drawRect(
      new Rect.fromPoints(Offset.zero, size.bottomLeft(Offset.zero)),
      blackLine,
    );
    for (math.Point<int> p in state.body) {
      final Offset a = new Offset(cellSize * p.x, cellSize * p.y);
      final Offset b = new Offset(cellSize * (p.x + 1), cellSize * (p.y + 1));

      canvas.drawRect(new Rect.fromPoints(a, b), blackFilled);
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

class SnakeState extends State<Snake> {
  double cellSize;
  GameState state;
  AccelerometerEvent acceleration;

  SnakeState(int rows, int columns, this.cellSize) {
    state = new GameState(rows, columns);
  }

  @override
  Widget build(BuildContext context) {
    return new CustomPaint(painter: new SnakeBoardPainter(state, cellSize));
  }

  @override
  void initState() {
    super.initState();
    accelerometerEvents.listen((AccelerometerEvent event) {
      setState(() {
        acceleration = event;
      });
    });

    new Timer.periodic(const Duration(milliseconds: 200), (_) {
      setState(() {
        _step();
      });
    });
  }

  void _step() {
    final math.Point<int> newDirection = acceleration == null
        ? null
        : acceleration.x.abs() < 1.0 && acceleration.y.abs() < 1.0
        ? null
        : (acceleration.x.abs() < acceleration.y.abs())
        ? new math.Point<int>(0, acceleration.y.sign.toInt())
        : new math.Point<int>(-acceleration.x.sign.toInt(), 0);
    state.step(newDirection);
  }
}

class GameState {
  int rows;
  int columns;
  int snakeLength;
  GameState(this.rows, this.columns) {
    snakeLength = math.min(rows, columns) - 5;
  }

  List<math.Point<int>> body = <math.Point<int>>[const math.Point<int>(0, 0)];
  math.Point<int> direction = const math.Point<int>(1, 0);

  void step(math.Point<int> newDirection) {
    math.Point<int> next = body.last + direction;
    next = new math.Point<int>(next.x % columns, next.y % rows);

    body.add(next);
    if (body.length > snakeLength) body.removeAt(0);
    direction = newDirection ?? direction;
  }
}

1 个答案:

答案 0 :(得分:0)

因此,以noogui的评论为基础:

可以在dart.dev的插件之一https://pub.dev/packages/googleapis中找到Google Fit API。这实际上是所有Google API的集合,因此其中包括Google Fit。

更具体地说,在https://github.com/dart-lang/googleapis/blob/master/generated/googleapis/lib/fitness/v1.dart

正如noogui所提到的,这是从REST API出发的:

该插件网站上没有使用示例,仅提供有关如何启动身份验证的示例,因此您必须参考主要文档以获取指南: