Future<int?> getTotalStepsInInterval(
  DateTime startDate,
  DateTime endDate,
)

Parameters

ParameterTypeRequiredDescription
startDateDateTimeYesStart of time range
endDateDateTimeYesEnd of time range

Returns

  • int: Total steps in the interval
  • null: If no step data available or error occurred

Basic Usage

// Get today's steps
final todaySteps = await health.getTotalStepsInInterval(
  DateTime.now().copyWith(hour: 0, minute: 0, second: 0),
  DateTime.now(),
);

print('Steps today: ${todaySteps ?? 0}');

// Get yesterday's steps
final yesterday = DateTime.now().subtract(Duration(days: 1));
final yesterdaySteps = await health.getTotalStepsInInterval(
  yesterday.copyWith(hour: 0, minute: 0, second: 0),
  yesterday.copyWith(hour: 23, minute: 59, second: 59),
);

print('Steps yesterday: ${yesterdaySteps ?? 0}');

Time Patterns

Today

final now = DateTime.now();
final startOfDay = DateTime(now.year, now.month, now.day);
final todaySteps = await health.getTotalStepsInInterval(startOfDay, now);

This Week

final now = DateTime.now();
final startOfWeek = now.subtract(Duration(days: now.weekday - 1));
final weekStart = DateTime(startOfWeek.year, startOfWeek.month, startOfWeek.day);
final weekSteps = await health.getTotalStepsInInterval(weekStart, now);

This Month

final now = DateTime.now();
final monthStart = DateTime(now.year, now.month, 1);
final monthSteps = await health.getTotalStepsInInterval(monthStart, now);

Custom Range

final start = DateTime(2024, 1, 1);
final end = DateTime(2024, 1, 31);
final januarySteps = await health.getTotalStepsInInterval(start, end);
print('January total: ${januarySteps ?? 0} steps');

Use Cases

Step Goal Tracking

class StepGoal {
  final int dailyGoal;
  
  StepGoal({this.dailyGoal = 10000});
  
  Future<Map<String, dynamic>> getProgress() async {
    final now = DateTime.now();
    final startOfDay = DateTime(now.year, now.month, now.day);
    
    final steps = await health.getTotalStepsInInterval(startOfDay, now);
    final currentSteps = steps ?? 0;
    final percentage = (currentSteps / dailyGoal * 100).clamp(0, 100);
    final remaining = (dailyGoal - currentSteps).clamp(0, dailyGoal);
    
    return {
      'current': currentSteps,
      'goal': dailyGoal,
      'percentage': percentage,
      'remaining': remaining,
      'achieved': currentSteps >= dailyGoal,
    };
  }
}

// Usage
final goal = StepGoal(dailyGoal: 10000);
final progress = await goal.getProgress();
print('${progress['current']} / ${progress['goal']} steps');
print('${progress['percentage'].toStringAsFixed(1)}% complete');

Weekly Step Summary

Future<List<Map<String, dynamic>>> getWeeklySteps() async {
  final now = DateTime.now();
  final weeklySteps = <Map<String, dynamic>>[];
  
  for (int i = 6; i >= 0; i--) {
    final day = now.subtract(Duration(days: i));
    final dayStart = DateTime(day.year, day.month, day.day);
    final dayEnd = dayStart.add(Duration(days: 1));
    
    final steps = await health.getTotalStepsInInterval(dayStart, dayEnd);
    
    weeklySteps.add({
      'date': dayStart,
      'dayName': _getDayName(dayStart.weekday),
      'steps': steps ?? 0,
    });
  }
  
  return weeklySteps;
}

String _getDayName(int weekday) {
  const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
  return days[weekday - 1];
}

// Usage
final weekData = await getWeeklySteps();
for (var day in weekData) {
  print('${day['dayName']}: ${day['steps']} steps');
}

Step Streak Tracking

class StepStreak {
  final int dailyGoal;
  
  StepStreak({this.dailyGoal = 10000});
  
  Future<int> getCurrentStreak() async {
    int streak = 0;
    final now = DateTime.now();
    
    for (int i = 0; i < 365; i++) {
      final day = now.subtract(Duration(days: i));
      final dayStart = DateTime(day.year, day.month, day.day);
      final dayEnd = dayStart.add(Duration(days: 1));
      
      final steps = await health.getTotalStepsInInterval(dayStart, dayEnd);
      
      if (steps != null && steps >= dailyGoal) {
        streak++;
      } else {
        break;
      }
    }
    
    return streak;
  }
}

// Usage
final streakTracker = StepStreak(dailyGoal: 10000);
final streak = await streakTracker.getCurrentStreak();
print('Current streak: $streak days');

Performance Optimization

This method is optimized for step counting:
// ✅ Efficient - uses optimized step total query
final steps = await health.getTotalStepsInInterval(start, end);

// ❌ Less efficient - queries all data points then sums
final dataPoints = await health.getHealthDataFromTypes(
  types: [HealthDataType.STEPS],
  startDate: start,
  endDate: end,
);
final manualTotal = dataPoints
    .map((e) => (e.value as NumericHealthValue).numericValue)
    .fold(0.0, (a, b) => a + b);

Error Handling

try {
  final steps = await health.getTotalStepsInInterval(start, end);
  
  if (steps == null) {
    print('No step data available for this period');
  } else {
    print('Total steps: $steps');
  }
} catch (e) {
  print('Error fetching steps: $e');
}

Platform Differences

  • iOS (HealthKit)
  • Android (Health Connect)
  • Aggregates all step samples from HealthKit
  • Includes steps from iPhone, Apple Watch, and connected apps
  • Automatic deduplication of overlapping data

Comparison with Other Methods

MethodUse CaseReturn Type
getTotalStepsInIntervalQuick total for a periodint?
getHealthDataFromTypesIndividual step samplesList<HealthDataPoint>
getHealthIntervalDataFromTypesSteps bucketed by timeList<HealthDataPoint>

See Also