Flutter安卓应用用户使用追踪与等级积分系统实现方案咨询
Hey Ali, let's tackle your two key needs—accurate app usage tracking and a tiered user level system—with practical, actionable steps:
一、精准计算应用使用时长(解决你之前的代码问题)
The main issue with tracking app usage usually comes from not handling all lifecycle states properly. Here's a reliable implementation using Flutter's built-in WidgetsBindingObserver:
Step 1: Create a usage tracker service
Create a singleton class to handle lifecycle events and time tracking:
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class AppUsageTracker extends WidgetsBindingObserver { static final AppUsageTracker _instance = AppUsageTracker._internal(); factory AppUsageTracker() => _instance; AppUsageTracker._internal() { WidgetsBinding.instance.addObserver(this); } DateTime? _sessionStart; int _totalSeconds = 0; // Load saved total usage from local storage on init Future<void> init() async { final prefs = await SharedPreferences.getInstance(); _totalSeconds = prefs.getInt('total_app_usage_seconds') ?? 0; } @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); switch (state) { case AppLifecycleState.resumed: // App is brought to foreground - start timing _sessionStart = DateTime.now(); break; case AppLifecycleState.paused: case AppLifecycleState.inactive: case AppLifecycleState.detached: // App is sent to background - calculate session duration if (_sessionStart != null) { final sessionDuration = DateTime.now().difference(_sessionStart!); _totalSeconds += sessionDuration.inSeconds; // Save to local storage immediately _saveTotalUsage(); // Send updated total to server (add your API call here) _sendUsageToServer(_totalSeconds); _sessionStart = null; } break; } } Future<void> _saveTotalUsage() async { final prefs = await SharedPreferences.getInstance(); await prefs.setInt('total_app_usage_seconds', _totalSeconds); } // Replace this with your actual server API call Future<void> _sendUsageToServer(int totalSeconds) async { // Example: await http.post(Uri.parse('your-server-endpoint'), body: {'usage_seconds': totalSeconds.toString()}); print('Sending total usage: ${totalSeconds ~/ 3600} hours ${(totalSeconds % 3600) ~/ 60} minutes'); } // Get total usage in hours for level calculation double getTotalUsageHours() { return _totalSeconds / 3600; } }
Step 2: Initialize the tracker in your app
In your main app widget, initialize the tracker:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await AppUsageTracker().init(); runApp(const MyApp()); }
This handles all edge cases like screen locks, switching apps, and even app crashes (since we save to local storage after each session).
二、实现等级/积分系统(白银、黄金、铂金等)
You can either build this from scratch (flexible for your needs) or use existing packages to speed things up.
Option 1: Build from scratch (full control)
Define your tier rules and create a simple service to manage user levels:
enum UserTier { bronze, silver, gold, platinum } class UserLevelService { final AppUsageTracker _usageTracker = AppUsageTracker(); UserTier getCurrentTier() { final totalHours = _usageTracker.getTotalUsageHours(); if (totalHours >= 50) return UserTier.platinum; if (totalHours >= 30) return UserTier.gold; if (totalHours >= 10) return UserTier.silver; return UserTier.bronze; } // Get tier-specific benefits List<String> getBenefitsForTier(UserTier tier) { switch (tier) { case UserTier.platinum: return ['Ad-free experience', 'Exclusive content', 'Priority support']; case UserTier.gold: return ['Reduced ads', 'Premium content access']; case UserTier.silver: return ['Basic ad-free sessions']; default: return ['Standard features']; } } }
Option 2: Use existing packages
If you want to avoid boilerplate, consider these Flutter packages:
flutter_points: Handles point accumulation, level progression, and reward rules out of the box.level_up: Simplifies creating tiered systems with custom upgrade conditions and callbacks.
Just add them to your pubspec.yaml and follow their documentation to integrate with your usage tracker.
Extra Tips
- Data Sync: Always sync local usage data with your server periodically (not just on background) to avoid conflicts. Implement a conflict resolution strategy (e.g., take the latest timestamp or sum both values).
- Local Storage: Use
hiveinstead ofshared_preferencesif you need to store more complex user data (like reward history). - User Engagement: Display the current level and progress towards the next tier in a prominent UI (e.g., a progress bar on the home screen) to encourage users to spend more time in the app.
备注:内容来源于stack exchange,提问作者Ali Ahmed

