11import 'dart:async' ;
22
3+ import 'package:flutter/foundation.dart' ;
34import 'package:flutter/services.dart' ;
45import 'dart:io' show Platform;
56
67/// Information on app usage.
78class AppUsageInfo {
89 late String _packageName, _appName;
910 late Duration _usage;
10- DateTime _startDate, _endDate, _lastForeground;
11+ final DateTime _startDate, _endDate, _lastForeground;
1112
1213 AppUsageInfo (
1314 String name,
@@ -48,20 +49,28 @@ class AppUsageInfo {
4849
4950/// Singleton class to get app usage statistics.
5051class AppUsage {
51- static const MethodChannel _methodChannel =
52- const MethodChannel ("app_usage.methodChannel" );
52+ static const MethodChannel _methodChannel = MethodChannel (
53+ "app_usage.methodChannel" ,
54+ );
55+ static bool ? _debugIsAndroidOverride;
5356
5457 static final AppUsage _instance = AppUsage ._();
5558 AppUsage ._();
5659 factory AppUsage () => _instance;
5760
61+ @visibleForTesting
62+ static set debugIsAndroidOverride (bool ? value) {
63+ _debugIsAndroidOverride = value;
64+ }
65+
5866 /// Get app usage statistics for the specified interval. Only works on Android.
5967 /// Returns an empty list if called on iOS.
6068 Future <List <AppUsageInfo >> getAppUsage (
6169 DateTime startDate,
6270 DateTime endDate,
6371 ) async {
64- if (! Platform .isAndroid) return [];
72+ final bool isAndroid = _debugIsAndroidOverride ?? Platform .isAndroid;
73+ if (! isAndroid) return [];
6574
6675 if (endDate.isBefore (startDate)) {
6776 throw ArgumentError ('End date must be after start date' );
@@ -72,22 +81,33 @@ class AppUsage {
7281 int start = startDate.millisecondsSinceEpoch;
7382
7483 // Set parameters
75- Map <String , int > interval = {'start' : start, 'end' : end};
84+ final Map <String , int > interval = < String , int > {'start' : start, 'end' : end};
7685
7786 // Get result and parse it as a Map of <String, List<double>>
78- Map usage = await _methodChannel.invokeMethod ('getUsage' , interval);
87+ final Map <Object ?, Object ?> usage =
88+ await _methodChannel.invokeMethod <Map <Object ?, Object ?>>(
89+ 'getUsage' ,
90+ interval,
91+ ) ??
92+ < Object ? , Object ? > {};
7993
8094 // Convert to list of AppUsageInfo
81- List <AppUsageInfo > result = [];
82- for (String key in usage.keys) {
83- List <double > temp = List <double >.from (usage[key]);
95+ final List <AppUsageInfo > result = < AppUsageInfo > [];
96+ for (final MapEntry <Object ?, Object ?> entry in usage.entries) {
97+ final String key = entry.key as String ;
98+ final List <double > temp = List <double >.from (
99+ entry.value as Iterable <Object ?>,
100+ );
84101 if (temp[0 ] > 0 ) {
85- result.add (AppUsageInfo (
102+ result.add (
103+ AppUsageInfo (
86104 key,
87105 temp[0 ],
88106 DateTime .fromMillisecondsSinceEpoch (temp[1 ].round () * 1000 ),
89107 DateTime .fromMillisecondsSinceEpoch (temp[2 ].round () * 1000 ),
90- DateTime .fromMillisecondsSinceEpoch (temp[3 ].round () * 1000 )));
108+ DateTime .fromMillisecondsSinceEpoch (temp[3 ].round () * 1000 ),
109+ ),
110+ );
91111 }
92112 }
93113
0 commit comments