183 lines
5.0 KiB
Dart
183 lines
5.0 KiB
Dart
import 'package:flutter/services.dart';
|
||
import '../models/app_usage.dart';
|
||
import '../database/app_usage_dao.dart';
|
||
import 'category_service.dart';
|
||
import 'statistics_service.dart';
|
||
|
||
class TimeTrackingService {
|
||
static const MethodChannel _channel = MethodChannel('autotime_tracker/time_tracking');
|
||
|
||
final AppUsageDao _appUsageDao = AppUsageDao();
|
||
final CategoryService _categoryService = CategoryService();
|
||
final StatisticsService _statisticsService = StatisticsService();
|
||
|
||
/// 检查权限状态
|
||
Future<bool> hasPermission() async {
|
||
try {
|
||
final result = await _channel.invokeMethod<bool>('hasPermission');
|
||
return result ?? false;
|
||
} catch (e) {
|
||
print('Error checking permission: $e');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// 请求权限
|
||
Future<bool> requestPermission() async {
|
||
try {
|
||
final result = await _channel.invokeMethod<bool>('requestPermission');
|
||
return result ?? false;
|
||
} catch (e) {
|
||
print('Error requesting permission: $e');
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// 获取应用使用数据(从系统 API)
|
||
Future<List<AppUsageData>> getAppUsageFromSystem({
|
||
required DateTime startTime,
|
||
required DateTime endTime,
|
||
}) async {
|
||
try {
|
||
final result = await _channel.invokeMethod<List<dynamic>>('getAppUsage', {
|
||
'startTime': startTime.millisecondsSinceEpoch,
|
||
'endTime': endTime.millisecondsSinceEpoch,
|
||
});
|
||
|
||
if (result == null) return [];
|
||
|
||
return result
|
||
.map((item) => AppUsageData.fromMap(Map<String, dynamic>.from(item)))
|
||
.toList();
|
||
} catch (e) {
|
||
print('Error getting app usage from system: $e');
|
||
return [];
|
||
}
|
||
}
|
||
|
||
/// 同步应用使用数据到数据库
|
||
Future<void> syncAppUsageToDatabase({
|
||
required DateTime startTime,
|
||
required DateTime endTime,
|
||
}) async {
|
||
try {
|
||
// 1. 从系统获取数据
|
||
final systemData = await getAppUsageFromSystem(
|
||
startTime: startTime,
|
||
endTime: endTime,
|
||
);
|
||
|
||
if (systemData.isEmpty) {
|
||
print('No app usage data from system');
|
||
return;
|
||
}
|
||
|
||
// 2. 转换为 AppUsage 模型并分类
|
||
final appUsages = <AppUsage>[];
|
||
for (final data in systemData) {
|
||
// 获取分类
|
||
final category = await _categoryService.getCategory(data.packageName);
|
||
|
||
// 创建 AppUsage 对象
|
||
final usage = AppUsage(
|
||
packageName: data.packageName,
|
||
appName: data.appName,
|
||
startTime: data.startTime,
|
||
endTime: data.endTime,
|
||
duration: data.duration,
|
||
category: category,
|
||
deviceUnlockCount: data.deviceUnlockCount ?? 0,
|
||
createdAt: DateTime.now(),
|
||
updatedAt: DateTime.now(),
|
||
);
|
||
|
||
appUsages.add(usage);
|
||
}
|
||
|
||
// 3. 批量插入数据库
|
||
if (appUsages.isNotEmpty) {
|
||
await _appUsageDao.batchInsertAppUsages(appUsages);
|
||
print('Synced ${appUsages.length} app usage records to database');
|
||
}
|
||
|
||
// 4. 更新今日统计
|
||
await _statisticsService.refreshTodayStats();
|
||
} catch (e) {
|
||
print('Error syncing app usage to database: $e');
|
||
rethrow;
|
||
}
|
||
}
|
||
|
||
/// 同步今日数据
|
||
Future<void> syncTodayData() async {
|
||
final now = DateTime.now();
|
||
final startOfDay = DateTime(now.year, now.month, now.day);
|
||
final endOfDay = startOfDay.add(const Duration(days: 1));
|
||
|
||
await syncAppUsageToDatabase(
|
||
startTime: startOfDay,
|
||
endTime: endOfDay,
|
||
);
|
||
}
|
||
|
||
/// 启动后台追踪
|
||
Future<void> startBackgroundTracking() async {
|
||
try {
|
||
await _channel.invokeMethod('startBackgroundTracking');
|
||
} catch (e) {
|
||
print('Error starting background tracking: $e');
|
||
}
|
||
}
|
||
|
||
/// 停止后台追踪
|
||
Future<void> stopBackgroundTracking() async {
|
||
try {
|
||
await _channel.invokeMethod('stopBackgroundTracking');
|
||
} catch (e) {
|
||
print('Error stopping background tracking: $e');
|
||
}
|
||
}
|
||
|
||
/// 检查后台追踪状态
|
||
Future<bool> isBackgroundTrackingActive() async {
|
||
try {
|
||
final result = await _channel.invokeMethod<bool>('isBackgroundTrackingActive');
|
||
return result ?? false;
|
||
} catch (e) {
|
||
print('Error checking background tracking status: $e');
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 系统返回的应用使用数据模型
|
||
class AppUsageData {
|
||
final String packageName;
|
||
final String appName;
|
||
final DateTime startTime;
|
||
final DateTime endTime;
|
||
final int duration; // 秒
|
||
final int? deviceUnlockCount;
|
||
|
||
AppUsageData({
|
||
required this.packageName,
|
||
required this.appName,
|
||
required this.startTime,
|
||
required this.endTime,
|
||
required this.duration,
|
||
this.deviceUnlockCount,
|
||
});
|
||
|
||
factory AppUsageData.fromMap(Map<String, dynamic> map) {
|
||
return AppUsageData(
|
||
packageName: map['packageName'] as String,
|
||
appName: map['appName'] as String,
|
||
startTime: DateTime.fromMillisecondsSinceEpoch(map['startTime'] as int),
|
||
endTime: DateTime.fromMillisecondsSinceEpoch(map['endTime'] as int),
|
||
duration: map['duration'] as int,
|
||
deviceUnlockCount: map['deviceUnlockCount'] as int?,
|
||
);
|
||
}
|
||
}
|
||
|