flutter_app_usage_kit
A Flutter plugin for querying Android app usage statistics via the system's UsageStatsManager API.
Android only. Requires the PACKAGE_USAGE_STATS special permission.
Features
| API |
Description |
AppUsageKit.queryUsageStats |
Aggregated foreground time per app for a time range |
AppUsageKit.queryEvents |
Discrete foreground / background / screen / keyguard events |
AppUsageKit.getInstalledApps |
List all installed apps with name, version, system flag, optional icon |
AppUsageKit.getAppInfo |
Metadata for a single package |
AppUsageKit.hasPermission |
Check if usage-stats permission is granted |
AppUsageKit.openPermissionSettings |
Open the system Usage Access settings screen |
Requirements
- Flutter ≥ 3.24
- Dart ≥ 3.5
- Android API 21 (Android 5.0 Lollipop) or higher
PACKAGE_USAGE_STATS permission granted by the user
Installation
dependencies:
flutter_app_usage_kit: ^0.1.0
Android setup
1. Add the permission to AndroidManifest.xml
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
2. Request permission at runtime
PACKAGE_USAGE_STATS is a special permission — it cannot be requested with the normal runtime-permission API. Direct the user to the system settings screen instead:
if (!await AppUsageKit.hasPermission()) {
await AppUsageKit.openPermissionSettings();
}
Usage
if (!await AppUsageKit.isSupported()) {
// Not Android — plugin will throw UnsupportedPlatformException on any other call
}
Query today's usage
final now = DateTime.now();
final start = DateTime(now.year, now.month, now.day);
final stats = await AppUsageKit.queryUsageStats(start: start, end: now);
for (final s in stats) {
print('${s.packageName}: ${s.totalForegroundTime}');
}
Query recent events
final now = DateTime.now();
final events = await AppUsageKit.queryEvents(
start: now.subtract(const Duration(hours: 1)),
end: now,
);
for (final e in events) {
print('${e.packageName} → ${e.type} at ${e.timestamp}');
}
List installed apps
final apps = await AppUsageKit.getInstalledApps(
includeIcons: true, // fetches PNG bytes — memory-intensive
includeSystemApps: false, // exclude system packages
);
Get info for one app
final info = await AppUsageKit.getAppInfo(
'com.example.myapp',
includeIcon: true,
);
if (info != null) {
print('${info.appName} v${info.versionName}');
}
Error handling
| Exception |
When thrown |
UnsupportedPlatformException |
Called on a non-Android platform |
PermissionDeniedException |
PACKAGE_USAGE_STATS not granted (stats/events only) |
InvalidTimeRangeException |
start is not before end |
try {
final stats = await AppUsageKit.queryUsageStats(start: start, end: end);
} on PermissionDeniedException {
await AppUsageKit.openPermissionSettings();
} on InvalidTimeRangeException {
// fix the time range
}
Models
UsageInfo
| Field |
Type |
Description |
packageName |
String |
App package name |
totalForegroundTime |
Duration |
Total foreground time in the queried window |
lastTimeUsed |
DateTime? |
Last time the app was used (all-time) |
launchCount |
int |
Number of launches (API 28+, else 0) |
UsageEvent
| Field |
Type |
Description |
packageName |
String |
App package name |
type |
UsageEventType |
foreground, background, screenInteractive, etc. |
timestamp |
DateTime |
When the event occurred |
className |
String? |
Activity class name if available |
AppInfo
| Field |
Type |
Description |
packageName |
String |
Package name |
appName |
String |
Human-readable label |
isSystemApp |
bool |
Whether it is a system app |
versionName |
String? |
Version string from the manifest |
iconPng |
Uint8List? |
PNG-encoded launcher icon (if requested) |
License
MIT