A Flutter plugin to list, inspect, and interact with installed apps on Android devices. Get app details, launch applications, and monitor installation changes programmatically.
Add to your pubspec.yaml:
dependencies:
flutter_device_apps: latest_versionimport 'package:flutter_device_apps/flutter_device_apps.dart';
final apps = await FlutterDeviceApps.listApps(
includeSystem: false,
onlyLaunchable: true,
includeIcons: false,
);
for (final app in apps) {
print('${app.appName} • ${app.packageName}');
}includeSystem: Include pre-installed system apps like Settings, Phone dialer, etc.onlyLaunchable: Only return apps that have launcher icons. Iffalse, includes all installed packages (libraries, services, background apps).includeIcons: Load app icons as bytes.
final info = await FlutterDeviceApps.getApp('com.example.myapp', includeIcon: true);
if (info != null) {
print('Version: ${info.versionName} (${info.versionCode})');
}Most common fields you’ll use (all fields, grouped):
packageName,appName– App identity (e.g.com.example.app, display name)versionName,versionCode– Version infouid– Linux app UID (local metadata; can differ by user profile and device)firstInstallTime,lastUpdateTime– Install / update timesisSystem,enabled– System app & enabled stateiconBytes– Icon bytes (when requested)category– App category code (e.g. game / social / productivity)targetSdkVersion,minSdkVersion– Target & minimum Android SDK levelsprocessName– Process name the app runs inapkPath– Base APK file path (ApplicationInfo.sourceDir)apkSizeBytes– APK size in bytes (base + installed split APK files, may benull)dataPath– App private data path (ApplicationInfo.dataDir)isOnExternalStorage– Raw boolean fromApplicationInfo.FLAG_EXTERNAL_STORAGEinstallLocation– Requested install policy (auto/internalOnly/preferExternal)
final permissions = await FlutterDeviceApps.getRequestedPermissions('com.example.myapp');
if (permissions != null) {
for (final p in permissions) {
print('Permission: $p');
}
}await FlutterDeviceApps.openApp('com.example.myapp');
await FlutterDeviceApps.openAppSettings('com.example.myapp');
await FlutterDeviceApps.uninstallApp('com.example.myapp');// Start listening to app changes.
late final StreamSubscription sub;
sub = FlutterDeviceApps.appChanges.listen(
(e) {
print('App event: ${e.type} → ${e.packageName}');
switch (e.type) {
case AppChangeType.installed:
print('New app installed: ${e.packageName}');
case AppChangeType.removed:
print('App uninstalled: ${e.packageName}');
case AppChangeType.updated:
print('App updated: ${e.packageName}');
case null:
print('Unknown change type');
}
},
onError: (error) => print('Monitoring error: $error'),
);
// if needed, stop listening to app changes.
await sub.cancel();final store = await FlutterDeviceApps.getInstallerStore('com.example.myapp');
if (store != null) {
print('Installed from: $store');
}"com.android.vending"- Google Play Store"com.sec.android.app.samsungapps"- Samsung Galaxy Store"com.huawei.appmarket"- Huawei AppGallery...
No extra permissions needed for basic usage (listing launcher apps and getting app details).
If you want listApps() or getApp() to see all installed applications instead of just launchable ones, add this permission to your AndroidManifest.xml:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />To use the uninstallApp() function, add this permission to your AndroidManifest.xml:
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />MIT © 2026 okmsbun