Flutter步数统计插件pedometer_plus的使用
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
更多关于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),
),
);
}
}
解释
- 依赖添加:在
pubspec.yaml
文件中添加pedometer_plus
依赖。 - 权限请求:在Android的
AndroidManifest.xml
中添加ACTIVITY_RECOGNITION
权限,在iOS的Info.plist
中添加NSMotionUsageDescription
权限。 - 插件初始化:在
initState
方法中初始化pedometer
实例,并调用_getSteps
方法获取步数。 - 获取步数:
_getSteps
方法检查计步器是否可用,然后获取步数并更新UI。 - UI展示:使用
Text
组件展示步数,使用FloatingActionButton
刷新步数。
通过上述代码,你可以在Flutter应用中实现步数统计功能。确保在实际使用中处理错误和权限请求的用户交互,以提升用户体验。