You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中获取已安装应用的图标?

在Jetpack Compose中根据包名显示应用图标

步骤1:完善ViewModel,添加应用信息获取逻辑

将普通ViewModel替换为AndroidViewModel以获取上下文,同时补充获取应用图标、名称的逻辑,把包名转换为包含图标信息的实体类:

import android.app.Application
import android.content.pm.PackageManager
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

data class AppInfo(
    val packageName: String,
    val appName: String,
    val appIcon: android.graphics.drawable.Drawable?
)

class MalwareListViewModel(application: Application) : AndroidViewModel(application) {
    private val _appInfoList = MutableStateFlow<List<AppInfo>>(emptyList())
    val appInfoList: StateFlow<List<AppInfo>> = _appInfoList

    // 这里替换成你获取恶意软件包名的原有逻辑
    private fun getMalwarePackageNames(): List<String> {
        return mutableListOf("com.example.test1", "com.example.test2")
    }

    fun loadAppInfo() {
        viewModelScope.launch {
            val packageNames = getMalwarePackageNames()
            val appInfos = withContext(Dispatchers.IO) {
                packageNames.mapNotNull { packageName ->
                    try {
                        val packageManager = getApplication<Application>().packageManager
                        val appInfo = packageManager.getApplicationInfo(packageName, 0)
                        AppInfo(
                            packageName = packageName,
                            appName = packageManager.getApplicationLabel(appInfo).toString(),
                            appIcon = packageManager.getApplicationIcon(appInfo)
                        )
                    } catch (e: PackageManager.NameNotFoundException) {
                        // 处理包名不存在的情况
                        null
                    }
                }
            }
            _appInfoList.value = appInfos
        }
    }
}

步骤2:在Compose中展示应用图标与信息

推荐使用Coil库简化Drawable的加载与显示,也可以手动转换Drawable为Bitmap:

可选:添加Coil依赖

在Module级别的build.gradle.kts中引入Coil:

implementation("io.coil-kt:coil-compose:2.5.0")

Compose UI实现代码

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import android.graphics.BitmapDrawable

@Composable
fun MalwareListScreen(viewModel: MalwareListViewModel) {
    val appInfoList = viewModel.appInfoList.collectAsState()

    LaunchedEffect(Unit) {
        viewModel.loadAppInfo()
    }

    LazyColumn(modifier = Modifier.fillMaxSize()) {
        items(appInfoList.value) { appInfo ->
            Row(modifier = Modifier.fillParentMaxWidth()) {
                // 方式1:用Coil加载Drawable(推荐)
                AsyncImage(
                    model = appInfo.appIcon,
                    contentDescription = appInfo.appName,
                    modifier = Modifier.size(48.dp)
                )

                // 方式2:手动转换Drawable为Bitmap(无需Coil)
                /*
                appInfo.appIcon?.let { drawable ->
                    val bitmap = (drawable as BitmapDrawable).bitmap
                    Image(
                        bitmap = bitmap.asImageBitmap(),
                        contentDescription = appInfo.appName,
                        modifier = Modifier.size(48.dp)
                    )
                }
                */

                Spacer(modifier = Modifier.width(16.dp))
                Column {
                    Text(text = appInfo.appName)
                    Text(text = appInfo.packageName)
                }
            }
        }
    }
}

注意事项

  • 权限配置:Android 11及以上版本需在AndroidManifest.xml中添加<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />,可根据目标SDK版本调整权限范围
  • 异常处理:务必处理应用图标为空、包名不存在的场景,可添加默认占位图
  • 异步安全:使用viewModelScope执行IO操作,避免内存泄漏
  • 工具选择:Coil会自动处理缓存、缩放等逻辑,无需手动管理Bitmap,使用更便捷

内容的提问来源于stack exchange,提问作者acrux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:11:03