diff --git a/android/build.gradle b/android/build.gradle index 2017346..53c99ea 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -26,6 +26,7 @@ apply plugin: 'kotlin-android' android { compileSdkVersion 31 + namespace = "com.hofinity.device_installed_apps" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 diff --git a/android/src/main/kotlin/com/hofinity/device_installed_apps/AppUtil.kt b/android/src/main/kotlin/com/hofinity/device_installed_apps/AppUtil.kt index afaa360..4be3502 100644 --- a/android/src/main/kotlin/com/hofinity/device_installed_apps/AppUtil.kt +++ b/android/src/main/kotlin/com/hofinity/device_installed_apps/AppUtil.kt @@ -9,45 +9,53 @@ import java.util.* object AppUtil { - internal fun filterApps(apps: List, - bundleIdPrefix: String, - includeSystemApps: Boolean, - onlySystemApps: Boolean, - permissions:List, - shouldHasAllPermissions: Boolean): List { + internal fun filterApps( + apps: List, + bundleIdPrefix: String, + includeSystemApps: Boolean, + onlySystemApps: Boolean, + permissions: List, + shouldHasAllPermissions: Boolean + ): List { var innerApps = apps - if(onlySystemApps) { - innerApps = innerApps.filter { - app -> isSystemApp(app.packageName) + if (onlySystemApps) { + innerApps = innerApps.filter { app -> + isSystemApp(app.packageName) } } else { - if (!includeSystemApps) innerApps = innerApps.filter { - app -> !isSystemApp(app.packageName) + if (!includeSystemApps) innerApps = innerApps.filter { app -> + !isSystemApp(app.packageName) } } - if (bundleIdPrefix.isNotEmpty()) innerApps = innerApps.filter { - app -> app.packageName.startsWith(bundleIdPrefix.lowercase(Locale.ENGLISH)) + if (bundleIdPrefix.isNotEmpty()) innerApps = innerApps.filter { app -> + app.packageName.startsWith(bundleIdPrefix.lowercase(Locale.ENGLISH)) } - if(permissions.isNotEmpty()) innerApps = innerApps.filter { - app -> hasPermissions(app.packageName, permissions, shouldHasAllPermissions) + if (permissions.isNotEmpty()) innerApps = innerApps.filter { app -> + hasPermissions(app.packageName, permissions, shouldHasAllPermissions) } return innerApps } - private fun hasPermissions(bundleId: String, - permissions:List, - shouldHasAllPermissions: Boolean): Boolean { + private fun hasPermissions( + bundleId: String, + permissions: List, + shouldHasAllPermissions: Boolean + ): Boolean { var shouldInclude = false try { - val packageInfo = DeviceInstalledAppsPlugin.getContext()!!.packageManager.getPackageInfo(bundleId, PackageManager.GET_PERMISSIONS) + val packageInfo = + DeviceInstalledAppsPlugin.getContext()!!.packageManager.getPackageInfo( + bundleId, + PackageManager.GET_PERMISSIONS + ) val requestedPermissions = packageInfo.requestedPermissions if (requestedPermissions != null) { - if(shouldHasAllPermissions) { + if (shouldHasAllPermissions) { var count = 0 - for(i in requestedPermissions.indices) { - for(permission in permissions) { + for (i in requestedPermissions.indices) { + for (permission in permissions) { if ((requestedPermissions[i] == permission)) { count++ break @@ -57,41 +65,59 @@ object AppUtil { shouldInclude = (count == permissions.size) } else { var count = 0 - for(i in requestedPermissions.indices) { - for(permission in permissions) { + for (i in requestedPermissions.indices) { + for (permission in permissions) { if ((requestedPermissions[i] == permission)) { count++ shouldInclude = true break } - if(count > 0) break + if (count > 0) break } } } } } catch (e: PackageManager.NameNotFoundException) { - Log.e(DeviceInstalledAppsPlugin.TAG, "Error checking permissions ~~~> ${e.localizedMessage}") + Log.e( + DeviceInstalledAppsPlugin.TAG, + "Error checking permissions ~~~> ${e.localizedMessage}" + ) shouldInclude = false } return shouldInclude } @Suppress("DEPRECATION") - fun appToHashMap(app: ApplicationInfo,includeIcon: Boolean): HashMap { - val pm = DeviceInstalledAppsPlugin.getContext()?.packageManager - val packageInfo = pm?.getPackageInfo(app.packageName, 0) - val map = HashMap() - map["name"] = pm?.getApplicationLabel(app) - map["bundleId"] = app.packageName - map["versionName"] = packageInfo!!.versionName - map["versionCode"] = if (SDK_INT > P) packageInfo.longVersionCode else packageInfo.versionCode.toLong() - map["icon"] = if (includeIcon) DrawableUtils.drawableToByteArray(app.loadIcon(pm)) else ByteArray(0) - return map + fun appToHashMap(app: ApplicationInfo, includeIcon: Boolean): HashMap? { + try { + val pm = DeviceInstalledAppsPlugin.getContext()?.packageManager + val packageInfo = pm?.getPackageInfo(app.packageName, 0) + val map = HashMap() + map["name"] = pm?.getApplicationLabel(app) + map["bundleId"] = app.packageName + map["versionName"] = packageInfo!!.versionName + map["versionCode"] = + if (SDK_INT > P) packageInfo.longVersionCode else packageInfo.versionCode.toLong() + map["icon"] = + if (includeIcon) DrawableUtils.drawableToByteArray(app.loadIcon(pm)) else ByteArray( + 0 + ) + return map + } catch (e: Exception) { + Log.e( + DeviceInstalledAppsPlugin.TAG, + "Trying to get data of an unknown package => ${app.packageName}" + ) + return null; + } } internal fun isSystemApp(bundleId: String): Boolean { if (bundleId.isBlank()) { - Log.e(DeviceInstalledAppsPlugin.TAG, "Error Checking System App ~~~> BundleId is empty!!!") + Log.e( + DeviceInstalledAppsPlugin.TAG, + "Error Checking System App ~~~> BundleId is empty!!!" + ) return false } // try { @@ -102,18 +128,27 @@ object AppUtil { // return false // } try { - val apps = DeviceInstalledAppsPlugin.getContext()!!.packageManager.getInstalledApplications(0) + val apps = + DeviceInstalledAppsPlugin.getContext()!!.packageManager.getInstalledApplications(0) var count = 0 - for(i in apps.indices) { + for (i in apps.indices) { if ((apps[i].packageName == bundleId)) { count++ break } } - if(count > 0) return DeviceInstalledAppsPlugin.getContext()?.packageManager?.getLaunchIntentForPackage(bundleId) == null - else Log.e(DeviceInstalledAppsPlugin.TAG, "Error Checking System App ~~~> BundleId not found") + if (count > 0) return DeviceInstalledAppsPlugin.getContext()?.packageManager?.getLaunchIntentForPackage( + bundleId + ) == null + else Log.e( + DeviceInstalledAppsPlugin.TAG, + "Error Checking System App ~~~> BundleId not found" + ) } catch (e: PackageManager.NameNotFoundException) { - Log.e(DeviceInstalledAppsPlugin.TAG, "Error checking permissions ~~~> ${e.localizedMessage}") + Log.e( + DeviceInstalledAppsPlugin.TAG, + "Error checking permissions ~~~> ${e.localizedMessage}" + ) } return false } diff --git a/android/src/main/kotlin/com/hofinity/device_installed_apps/DeviceInstalledAppsPlugin.kt b/android/src/main/kotlin/com/hofinity/device_installed_apps/DeviceInstalledAppsPlugin.kt index 456d5ce..77bb07b 100644 --- a/android/src/main/kotlin/com/hofinity/device_installed_apps/DeviceInstalledAppsPlugin.kt +++ b/android/src/main/kotlin/com/hofinity/device_installed_apps/DeviceInstalledAppsPlugin.kt @@ -111,7 +111,7 @@ class DeviceInstalledAppsPlugin(): FlutterPlugin, MethodCallHandler, ActivityAwa var apps = context!!.packageManager.getInstalledApplications(0) apps = AppUtil.filterApps(apps, bundleIdPrefix, includeSystemApps, onlySystemApps = false, permissions, shouldHasAllPermissions) - return apps.map { app -> AppUtil.appToHashMap(app, includeIcons) } + return apps.map { app -> AppUtil.appToHashMap(app, includeIcons) }.filterNotNull() } private fun getSystemApps(bundleIdPrefix: String, @@ -121,7 +121,7 @@ class DeviceInstalledAppsPlugin(): FlutterPlugin, MethodCallHandler, ActivityAwa var apps = context!!.packageManager.getInstalledApplications(0) apps = AppUtil.filterApps(apps, bundleIdPrefix,includeSystemApps = true, onlySystemApps = true, permissions, shouldHasAllPermissions) - return apps.map { app -> AppUtil.appToHashMap(app, includeIcons) } + return apps.map { app -> AppUtil.appToHashMap(app, includeIcons) }.filterNotNull() } private fun getAppsBundleIds(bundleIdPrefix: String, diff --git a/example/pubspec.lock b/example/pubspec.lock index aa14038..c24cfee 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,42 +5,42 @@ packages: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.13.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" characters: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.19.1" cupertino_icons: dependency: "direct main" description: @@ -55,23 +55,23 @@ packages: path: ".." relative: true source: path - version: "1.0.0" + version: "1.0.1" fake_async: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" file: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.1" flutter: dependency: "direct main" description: flutter @@ -105,14 +105,30 @@ packages: description: flutter source: sdk version: "0.0.0" - js: + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" + url: "https://pub.dev" + source: hosted + version: "10.0.9" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + url: "https://pub.dev" + source: hosted + version: "3.0.9" + leak_tracker_testing: dependency: transitive description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "3.0.1" lints: dependency: transitive description: @@ -125,42 +141,42 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.16.0" path: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.1" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -173,47 +189,47 @@ packages: dependency: transitive description: name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "5.0.3" sky_engine: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.4" string_scanner: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.1" sync_http: dependency: transitive description: @@ -226,18 +242,18 @@ packages: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.7.4" vector_math: dependency: transitive description: @@ -250,18 +266,18 @@ packages: dependency: transitive description: name: vm_service - sha256: f6deed8ed625c52864792459709183da231ebf66ff0cf09e69b573227c377efe + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "11.3.0" + version: "15.0.0" webdriver: dependency: transitive description: name: webdriver - sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" + sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.1.0" sdks: - dart: ">=3.0.6 <4.0.0" - flutter: ">=3.3.0" + dart: ">=3.7.0-0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index 6402a1b..fc22503 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: device_installed_apps description: Plugin for Flutter with methods related to device installed apps. -version: 1.0.1 +version: 1.0.2 homepage: https://github.com/Hofinity/DeviceInstalledApps-FlutterPlugin environment: