Flutter步数统计插件pedometer_plus的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter步数统计插件pedometer_plus的使用

pedometer_plus 是一个用于在Flutter应用中进行步数统计的插件。它利用iOS和Android设备内置的计步器传感器API,提供连续的步数记录和步行状态监测功能。

平台支持

以下是 pedometer_plus 在不同平台上的功能支持情况:

功能 Android iOS
stepStatusStream
stepCountStream (系统中的所有步数)
stepCountStreamFrom (从指定日期开始的步数)
getStepCount (在指定的时间段内的步数)

权限设置

Android

对于Android 10及以上的版本,请在AndroidManifest.xml文件中添加以下权限:

<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />

iOS

在Xcode项目的Info.plist文件中添加以下条目:

<key>NSMotionUsageDescription</key>
<string>This application tracks your steps</string>

示例代码

下面是一个完整的示例程序,展示如何使用pedometer_plus插件来获取步数和步行状态信息。

import 'dart:async';
import 'dart:io';

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

String formatDate(DateTime d) {
  return d.toString().substring(0, 19);
}

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

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Pedometer Example'),
        ),
        body: SingleChildScrollView(
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                _StepStatus(),
                Divider(height: 50),
                _StepCount(),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _StepCount extends StatefulWidget {
  [@override](/user/override)
  _StepCountState createState() => _StepCountState();
}

class _StepCountState extends State<_StepCount> {
  final _pedometer = Pedometer();
  int _stepCounts = 0;
  int _streamedStepCountFromToday = 0;
  int _gettableStepCount = 0;

  [@override](/user/override)
  void initState() {
    super.initState();

    _getStreamGettableStepCount();
    _getStreamStepCountFrom();
    _getStepCount();
  }

  void _getStreamGettableStepCount() async {
    final stepCountStream = _pedometer.stepCountStream();
    stepCountStream.listen(
      (step) {
        print('onGettableStepCount: $step');
        setState(() {
          _gettableStepCount = step;
        });
      },
    ).onError((error) {
      print('onGettableStepCountError: $error');
      print('onGettableStepCountError:Step Count not available');
      setState(() {
        _gettableStepCount = 0;
      });
    });
  }

  void _getStreamStepCountFrom() async {
    if (Platform.isIOS) {
      final now = DateTime.now();
      final todayStart = DateTime(now.year, now.month, now.day);

      final stepCountStream = _pedometer.stepCountStreamFrom(
        from: todayStart,
      );

      stepCountStream.listen((step) {
        print('onStepCountToday: $step');
        setState(() {
          _streamedStepCountFromToday = step;
        });
      }).onError((error) {
        print('onStepCountTodayError: $error');
        print('onStepCountTodayError:Step Count not available');
        setState(() {
          _streamedStepCountFromToday = 0;
        });
      });
    } else if (Platform.isAndroid) {
      print('_getStreamStepCountFrom: Not available on Android');
    }
  }

  Future<void> _getStepCount() async {
    if (Platform.isIOS) {
      final now = DateTime.now();
      final todayStart = DateTime(now.year, now.month, now.day);

      final stepCounts = await _pedometer.getStepCount(
        from: todayStart,
        to: DateTime.now(),
      );

      setState(() {
        _stepCounts = stepCounts;
      });
      print('_getStepCount: $_stepCounts');
    } else if (Platform.isAndroid) {
      print('_getStepCount: Not available on Android');
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Stream Steps Taken', style: TextStyle(fontSize: 30)),
        Text(_gettableStepCount.toString(), style: TextStyle(fontSize: 60)),
        Divider(height: 10),
        Text('Stream Steps Taken From Today', style: TextStyle(fontSize: 30)),
        if (Platform.isIOS)
          Text(_streamedStepCountFromToday.toString(), style: TextStyle(fontSize: 60))
        else if (Platform.isAndroid)
          Text('Not available on Android', style: TextStyle(fontSize: 50)),
        Divider(height: 10),
        Text('Functional Steps Taken From Today', style: TextStyle(fontSize: 30)),
        if (Platform.isIOS)
          ...[
            Text(_stepCounts.toString(), style: TextStyle(fontSize: 60)),
            TextButton(onPressed: _getStepCount, child: Text('Get Step Count')),
          ]
        else if (Platform.isAndroid)
          Text('Not available on Android', style: TextStyle(fontSize: 50)),
      ],
    );
  }
}

class _StepStatus extends StatefulWidget {
  [@override](/user/override)
  _StepStatusState createState() => _StepStatusState();
}

class _StepStatusState extends State<_StepStatus> {
  final _pedometer = Pedometer();

  StepStatus _status = StepStatus.unknown;

  [@override](/user/override)
  void initState() {
    super.initState();

    final _stepStatusStream = _pedometer.stepStatusStream();
    _stepStatusStream.listen(onStepStatusChanged).onError(onStepStatusError);
  }

  void onStepStatusChanged(StepStatus status) {
    print('onStepStatusChanged: $status');
    setState(() {
      _status = status;
    });
  }

  void onStepStatusError(error) {
    print('onStepStatusError: $error');
    print('onStepStatusError: Pedestrian Status not available');
    setState(() {
      _status = StepStatus.unknown;
    });
    print("onStepStatusError:$_status");
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Step Status', style: TextStyle(fontSize: 30)),
        Icon(
          _status == StepStatus.walking ? Icons.directions_walk :
          _status == StepStatus.stopped ? Icons.accessibility_new : Icons.error,
          size: 100,
        ),
        Center(
          child: Text(
            _status.name,
            style: _status == StepStatus.walking || _status == StepStatus.stopped
                ? TextStyle(fontSize: 30)
                : TextStyle(fontSize: 20, color: Colors.red),
          ),
        )
      ],
    );
  }
}

更多关于Flutter步数统计插件pedometer_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter步数统计插件pedometer_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用pedometer_plus插件来统计步数的详细代码示例。这个插件可以帮助你访问设备的步数数据。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加pedometer_plus依赖:

dependencies:
  flutter:
    sdk: flutter
  pedometer_plus: ^4.0.0  # 请确保使用最新版本,版本号可能有所不同

然后运行flutter pub get来安装依赖。

2. 请求权限

在Android和iOS上,访问步数数据需要相应的权限。

Android

android/app/src/main/AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>

iOS

ios/Runner/Info.plist中添加以下权限请求:

<key>NSMotionUsageDescription</key>
<string>We need your permission to access step count data</string>

3. 使用插件

接下来,你可以在你的Flutter代码中使用pedometer_plus插件。以下是一个完整的示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StepCounterScreen(),
    );
  }
}

class StepCounterScreen extends StatefulWidget {
  @override
  _StepCounterScreenState createState() => _StepCounterScreenState();
}

class _StepCounterScreenState extends State<StepCounterScreen> {
  late Pedometer pedometer;
  late int? steps;

  @override
  void initState() {
    super.initState();
    pedometer = Pedometer.getInstance();
    _getSteps();
  }

  Future<void> _getSteps() async {
    try {
      bool isAvailable = await pedometer.isAvailable();
      if (isAvailable) {
        PedometerData? pedometerData = await pedometer.getStepCount();
        if (pedometerData != null) {
          setState(() {
            steps = pedometerData.steps;
          });
        }
      } else {
        setState(() {
          steps = null;
        });
        print("Pedometer is not available on this device.");
      }
    } catch (e) {
      print("Error getting step count: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Step Counter'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Steps:',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 16),
            steps != null
                ? Text(
                    '${steps!}',
                    style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
                  )
                : Text(
                    'Unable to get steps',
                    style: TextStyle(fontSize: 24, color: Colors.red),
                  ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _getSteps,
        tooltip: 'Refresh',
        child: Icon(Icons.refresh),
      ),
    );
  }
}

解释

  1. 依赖添加:在pubspec.yaml文件中添加pedometer_plus依赖。
  2. 权限请求:在Android的AndroidManifest.xml中添加ACTIVITY_RECOGNITION权限,在iOS的Info.plist中添加NSMotionUsageDescription权限。
  3. 插件初始化:在initState方法中初始化pedometer实例,并调用_getSteps方法获取步数。
  4. 获取步数_getSteps方法检查计步器是否可用,然后获取步数并更新UI。
  5. UI展示:使用Text组件展示步数,使用FloatingActionButton刷新步数。

通过上述代码,你可以在Flutter应用中实现步数统计功能。确保在实际使用中处理错误和权限请求的用户交互,以提升用户体验。

回到顶部