diff --git a/README.md b/README.md index a5ea45f..8cf0688 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ possible. ``` dart List apps = await InstalledApps.getInstalledApps( bool excludeSystemApps, + bool excludeUnlaunchable, bool withIcon, String packageNamePrefix ); diff --git a/android/src/main/kotlin/com/sharmadhiraj/installed_apps/InstalledAppsPlugin.kt b/android/src/main/kotlin/com/sharmadhiraj/installed_apps/InstalledAppsPlugin.kt index 5cf0e6c..8215a7f 100644 --- a/android/src/main/kotlin/com/sharmadhiraj/installed_apps/InstalledAppsPlugin.kt +++ b/android/src/main/kotlin/com/sharmadhiraj/installed_apps/InstalledAppsPlugin.kt @@ -68,12 +68,13 @@ class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware { } when (call.method) { "getInstalledApps" -> { - val includeSystemApps = call.argument("exclude_system_apps") ?: true + val excludeSystemApps = call.argument("exclude_system_apps") ?: true + val excludeLaunchableApps = call.argument("exclude_unlaunchable") ?: true val withIcon = call.argument("with_icon") ?: false val packageNamePrefix: String = call.argument("package_name_prefix") ?: "" Thread { val apps: List> = - getInstalledApps(includeSystemApps, withIcon, packageNamePrefix) + getInstalledApps(excludeSystemApps, excludeLaunchableApps, withIcon, packageNamePrefix) result.success(apps) }.start() } @@ -120,6 +121,7 @@ class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware { private fun getInstalledApps( excludeSystemApps: Boolean, + excludeUnlaunchable: Boolean, withIcon: Boolean, packageNamePrefix: String ): List> { @@ -128,6 +130,8 @@ class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware { if (excludeSystemApps) installedApps = installedApps.filter { app -> !isSystemApp(packageManager, app.packageName) } + if (excludeUnlaunchable) + installedApps = installedApps.filter { app -> isLaunchable(packageManager, app.packageName) } if (packageNamePrefix.isNotEmpty()) installedApps = installedApps.filter { app -> app.packageName.startsWith( @@ -163,6 +167,10 @@ class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware { } } + private fun isLaunchable(packageManager: PackageManager, packageName: String): Boolean { + return packageManager.getLaunchIntentForPackage(packageName) != null + } + private fun openSettings(packageName: String?) { if (!isAppInstalled(packageName)) { print("App $packageName is not installed on this device.") diff --git a/example/lib/screens/app_list.dart b/example/lib/screens/app_list.dart index 708d67e..16f46e5 100644 --- a/example/lib/screens/app_list.dart +++ b/example/lib/screens/app_list.dart @@ -18,7 +18,7 @@ class AppListScreen extends StatelessWidget { Widget _buildBody() { return FutureBuilder>( - future: InstalledApps.getInstalledApps(true, true), + future: InstalledApps.getInstalledApps(false, true, true), builder: ( BuildContext buildContext, AsyncSnapshot> snapshot, diff --git a/example/lib/screens/home.dart b/example/lib/screens/home.dart index 53be99d..b8e4fa0 100644 --- a/example/lib/screens/home.dart +++ b/example/lib/screens/home.dart @@ -23,7 +23,7 @@ class HomeScreen extends StatelessWidget { _buildListItem( context, "Installed Apps", - "Get installed apps on device. With options to exclude system app, get app icon & matching package name prefix.", + "Get installed apps on device. With options to exclude system app, exclude unlaunchable apps, get app icon & matching package name prefix.", () => Navigator.push( context, MaterialPageRoute(builder: (context) => AppListScreen()), diff --git a/lib/installed_apps.dart b/lib/installed_apps.dart index a3d12d2..57bd285 100644 --- a/lib/installed_apps.dart +++ b/lib/installed_apps.dart @@ -8,12 +8,14 @@ class InstalledApps { /// Retrieves a list of installed apps on the device. /// /// [excludeSystemApps] specifies whether to exclude system apps from the list. + /// [excludeUnlaunchable] specifies whether to exclude apps that cannot be launched /// [withIcon] specifies whether to include app icons in the list. /// [packageNamePrefix] is an optional parameter to filter apps with package names starting with a specific prefix. /// /// Returns a list of [AppInfo] objects representing the installed apps. static Future> getInstalledApps([ bool excludeSystemApps = true, + bool excludeUnlaunchable = true, bool withIcon = false, String packageNamePrefix = "", ]) async { @@ -21,6 +23,7 @@ class InstalledApps { "getInstalledApps", { "exclude_system_apps": excludeSystemApps, + "exclude_unlaunchable": excludeUnlaunchable, "with_icon": withIcon, "package_name_prefix": packageNamePrefix, },