Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: create PlatformType enum for platform categorization #41

Merged
merged 3 commits into from
Mar 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,21 @@ import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.PluginRegistry.Registrar
import java.util.Locale.ENGLISH

class InstalledAppsPlugin : MethodCallHandler, FlutterPlugin, ActivityAware {

class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware {

companion object {

var context: Context? = null

@JvmStatic
fun registerWith(registrar: Registrar) {
context = registrar.context()
register(registrar.messenger())
}

@JvmStatic
fun register(messenger: BinaryMessenger) {
val channel = MethodChannel(messenger, "installed_apps")
channel.setMethodCallHandler(InstalledAppsPlugin())
}
}
private lateinit var channel: MethodChannel
private var context: Context? = null

override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
register(binding.binaryMessenger)
context = binding.applicationContext
channel = MethodChannel(binding.binaryMessenger, "installed_apps")
channel.setMethodCallHandler(this)
}

override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}

override fun onAttachedToActivity(activityPluginBinding: ActivityPluginBinding) {
Expand All @@ -63,54 +50,58 @@ class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware {

override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
if (context == null) {
result.error("", "Something went wrong!", null)
result.error("ERROR", "Context is null", null)
return
}
when (call.method) {
"getInstalledApps" -> {
val includeSystemApps = call.argument("exclude_system_apps") ?: true
val withIcon = call.argument("with_icon") ?: false
val packageNamePrefix: String = call.argument("package_name_prefix") ?: ""
val includeSystemApps = call.argument<Boolean>("exclude_system_apps") ?: true
val withIcon = call.argument<Boolean>("with_icon") ?: false
val packageNamePrefix = call.argument<String>("package_name_prefix") ?: ""
val platformTypeName = call.argument<String>("platform_type") ?: ""

Thread {
val apps: List<Map<String, Any?>> =
getInstalledApps(includeSystemApps, withIcon, packageNamePrefix)
getInstalledApps(includeSystemApps, withIcon, packageNamePrefix, PlatformType.fromString(platformTypeName))
result.success(apps)
}.start()
}

"startApp" -> {
val packageName: String? = call.argument("package_name")
val packageName = call.argument<String>("package_name")
result.success(startApp(packageName))
}

"openSettings" -> {
val packageName: String? = call.argument("package_name")
val packageName = call.argument<String>("package_name")
openSettings(packageName)
}

"toast" -> {
val message = call.argument("message") ?: ""
val short = call.argument("short_length") ?: true
val message = call.argument<String>("message") ?: ""
val short = call.argument<Boolean>("short_length") ?: true
toast(message, short)
}

"getAppInfo" -> {
val packageName: String = call.argument("package_name") ?: ""
result.success(getAppInfo(getPackageManager(context!!), packageName))
val packageName = call.argument<String>("package_name") ?: ""
val platformTypeName = call.argument<String>("platform_type") ?: ""
val platformType = PlatformType.fromString(platformTypeName)
result.success(getAppInfo(getPackageManager(context!!), packageName, platformType))
}

"isSystemApp" -> {
val packageName: String = call.argument("package_name") ?: ""
val packageName = call.argument<String>("package_name") ?: ""
result.success(isSystemApp(getPackageManager(context!!), packageName))
}

"uninstallApp" -> {
val packageName: String = call.argument("package_name") ?: ""
val packageName = call.argument<String>("package_name") ?: ""
result.success(uninstallApp(packageName))
}

"isAppInstalled" -> {
val packageName: String = call.argument("package_name") ?: ""
val packageName = call.argument<String>("package_name") ?: ""
result.success(isAppInstalled(packageName))
}

Expand All @@ -121,7 +112,8 @@ class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware {
private fun getInstalledApps(
excludeSystemApps: Boolean,
withIcon: Boolean,
packageNamePrefix: String
packageNamePrefix: String,
platformType: PlatformType?
): List<Map<String, Any?>> {
val packageManager = getPackageManager(context!!)
var installedApps = packageManager.getInstalledApplications(0)
Expand All @@ -134,7 +126,7 @@ class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware {
packageNamePrefix.lowercase(ENGLISH)
)
}
return installedApps.map { app -> convertAppToMap(packageManager, app, withIcon) }
return installedApps.map { app -> convertAppToMap(packageManager, app, withIcon, platformType) }
}

private fun startApp(packageName: String?): Boolean {
Expand Down Expand Up @@ -178,12 +170,13 @@ class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware {

private fun getAppInfo(
packageManager: PackageManager,
packageName: String
packageName: String,
platformType: PlatformType?
): Map<String, Any?>? {
var installedApps = packageManager.getInstalledApplications(0)
installedApps = installedApps.filter { app -> app.packageName == packageName }
return if (installedApps.isEmpty()) null
else convertAppToMap(packageManager, installedApps[0], true)
else convertAppToMap(packageManager, installedApps[0], true, platformType)
}

private fun uninstallApp(packageName: String): Boolean {
Expand All @@ -197,7 +190,6 @@ class InstalledAppsPlugin() : MethodCallHandler, FlutterPlugin, ActivityAware {
}
}


private fun isAppInstalled(packageName: String?): Boolean {
val packageManager: PackageManager = context!!.packageManager
return try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.sharmadhiraj.installed_apps
enum class PlatformType(val value: String) {
FLUTTER("flutter"),
REACT_NATIVE("react_native"),
XAMARIN("xamarin"),
IONIC("ionic"),
NATIVE_OR_OTHERS("native_or_others");

companion object {
fun fromString(platform: String): PlatformType? {
if (platform.isEmpty()) return null;
return when (platform.lowercase()) {
"flutter" -> FLUTTER
"react_native" -> REACT_NATIVE
"xamarin" -> XAMARIN
"ionic" -> IONIC
else -> NATIVE_OR_OTHERS
}
}
}
}
10 changes: 3 additions & 7 deletions android/src/main/kotlin/com/sharmadhiraj/installed_apps/Util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ import android.os.Build.VERSION_CODES.P
import java.io.File

class Util {

companion object {

fun convertAppToMap(
packageManager: PackageManager,
app: ApplicationInfo,
withIcon: Boolean
withIcon: Boolean,
platformType: PlatformType?,
): HashMap<String, Any?> {
val map = HashMap<String, Any?>()
map["name"] = packageManager.getApplicationLabel(app)
Expand All @@ -26,12 +25,11 @@ class Util {
val packageInfo = packageManager.getPackageInfo(app.packageName, 0)
map["version_name"] = packageInfo.versionName
map["version_code"] = getVersionCode(packageInfo)
map["built_with"] = BuiltWithUtil.getPlatform(packageInfo.applicationInfo)
map["built_with"] = platformType?.value ?: BuiltWithUtil.getPlatform(packageInfo.applicationInfo)
map["installed_timestamp"] = File(packageInfo.applicationInfo.sourceDir).lastModified()
return map
}


fun getPackageManager(context: Context): PackageManager {
return context.packageManager
}
Expand All @@ -41,7 +39,5 @@ class Util {
return if (SDK_INT < P) packageInfo.versionCode.toLong()
else packageInfo.longVersionCode
}

}

}
4 changes: 2 additions & 2 deletions example/ios/Flutter/flutter_export_environment.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/dhirajsharma/Drive/SDKs/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/dhirajsharma/Drive/Desk/Personal/Projects/Flutter/installed_apps/example"
export "FLUTTER_ROOT=/Users/velibacik/development/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/velibacik/Desktop/development/package/installed_apps/example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
Expand Down
8 changes: 5 additions & 3 deletions example/lib/screens/app_info.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:installed_apps/app_info.dart';
import 'package:installed_apps/installed_apps.dart';
import 'package:installed_apps/index.dart';

class AppInfoScreen extends StatelessWidget {
final AppInfo? app;
Expand All @@ -21,7 +20,10 @@ class AppInfoScreen extends StatelessWidget {

Widget _buildAppInfoWithPackageName() {
return FutureBuilder<AppInfo?>(
future: InstalledApps.getAppInfo("com.google.android.gm"),
future: InstalledApps.getAppInfo(
"com.google.android.gm",
BuiltWith.flutter,
),
builder: (BuildContext buildContext, AsyncSnapshot<AppInfo?> snapshot) {
return snapshot.connectionState == ConnectionState.done
? snapshot.hasData && snapshot.data != null
Expand Down
Loading