package com.myapplist import android.content.Intent import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.content.pm.ResolveInfo import com.facebook.fbreact.specs.NativeMyAppListSpec import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.WritableArray import com.facebook.react.bridge.WritableMap import com.facebook.react.module.annotations.ReactModule @ReactModule(name = MyAppListModule.NAME) class MyAppListModule(reactContext: ReactApplicationContext) : NativeMyAppListSpec(reactContext) { override fun getName(): String { return NAME } override fun getInstalledApps(promise: Promise) { try { val packageManager = reactApplicationContext.packageManager val result: WritableArray = Arguments.createArray() val uniquePackages = mutableSetOf() // Get user-facing apps (apps with launcher intent) val launcherIntent = Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_LAUNCHER) } val launcherApps = packageManager.queryIntentActivities(launcherIntent, 0) // Add launcher apps to the result for (resolveInfo in launcherApps) { val packageName = resolveInfo.activityInfo.packageName if (!uniquePackages.contains(packageName)) { uniquePackages.add(packageName) addAppToResult(packageManager, packageName, result) } } // Get sharing apps val shareIntent = Intent(Intent.ACTION_SEND).apply { type = "*/*" } val shareApps = packageManager.queryIntentActivities(shareIntent, 0) for (resolveInfo in shareApps) { val packageName = resolveInfo.activityInfo.packageName if (!uniquePackages.contains(packageName)) { uniquePackages.add(packageName) addAppToResult(packageManager, packageName, result) } } // Get browser apps val browserIntent = Intent(Intent.ACTION_VIEW).apply { addCategory(Intent.CATEGORY_BROWSABLE) data = android.net.Uri.parse("http://") } val browserApps = packageManager.queryIntentActivities(browserIntent, 0) for (resolveInfo in browserApps) { val packageName = resolveInfo.activityInfo.packageName if (!uniquePackages.contains(packageName)) { uniquePackages.add(packageName) addAppToResult(packageManager, packageName, result) } } // Get camera apps val cameraIntent = Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE) val cameraApps = packageManager.queryIntentActivities(cameraIntent, 0) for (resolveInfo in cameraApps) { val packageName = resolveInfo.activityInfo.packageName if (!uniquePackages.contains(packageName)) { uniquePackages.add(packageName) addAppToResult(packageManager, packageName, result) } } // Get gallery/photo apps val galleryIntent = Intent(Intent.ACTION_PICK).apply { type = "image/*" } val galleryApps = packageManager.queryIntentActivities(galleryIntent, 0) for (resolveInfo in galleryApps) { val packageName = resolveInfo.activityInfo.packageName if (!uniquePackages.contains(packageName)) { uniquePackages.add(packageName) addAppToResult(packageManager, packageName, result) } } // Get music/media apps val musicIntent = Intent(Intent.ACTION_VIEW).apply { type = "audio/*" } val musicApps = packageManager.queryIntentActivities(musicIntent, 0) for (resolveInfo in musicApps) { val packageName = resolveInfo.activityInfo.packageName if (!uniquePackages.contains(packageName)) { uniquePackages.add(packageName) addAppToResult(packageManager, packageName, result) } } promise.resolve(result) } catch (e: Exception) { promise.reject("GET_APPS_ERROR", "Failed to get installed apps: ${e.message}") } } private fun addAppToResult(packageManager: PackageManager, packageName: String, result: WritableArray) { try { val packageInfo = packageManager.getPackageInfo(packageName, 0) val applicationInfo = packageManager.getApplicationInfo(packageName, 0) // Only include user-installed apps or system apps that are user-facing if ((applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) == 0 || isUserFacingSystemApp(packageManager, packageName)) { val app: WritableMap = Arguments.createMap() app.putString("packageName", packageName) app.putString("appName", packageManager.getApplicationLabel(applicationInfo).toString()) app.putString("versionName", packageInfo.versionName ?: "Unknown") app.putInt("versionCode", packageInfo.versionCode) app.putBoolean("isSystemApp", (applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0) result.pushMap(app) } } catch (e: Exception) { // Skip this package if we can't get its info } } private fun isUserFacingSystemApp(packageManager: PackageManager, packageName: String): Boolean { try { // Check if the system app has a launcher intent (user-facing) val launcherIntent = Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_LAUNCHER) setPackage(packageName) } val activities = packageManager.queryIntentActivities(launcherIntent, 0) return activities.isNotEmpty() } catch (e: Exception) { return false } } companion object { const val NAME = "MyAppList" } }