Kotlin中RecyclerView适配器启动已安装应用时Intent返回null问题
问题原因
- 核心问题:两个数据集不同步,position对应关系完全错位
你当前的代码中维护了两个独立的列表:
- 第一次遍历所有安装包时,你把所有包名无过滤全部存入
packs列表 - 第二次遍历安装包时,你过滤了
appName.startsWith("com.")的条目才存入list列表
这就导致packs的长度远大于list,你用packs[position]取到的包名根本不是当前list[position]对应应用的包名,大多是无启动入口的系统组件包,所以getLaunchIntentForPackage返回null。
- 次要兼容问题:Android 11(API 30)及以上版本缺少包可见性权限
Android 11开始引入包可见性过滤规则,没有相关权限的话,即使包名正确也可能拿不到启动Intent。
解决方案
1. 修正数据结构,同步应用信息和包名
不要维护两个独立列表,直接把包名字段加入你定义的App数据类,一次遍历完成数据加载:
首先修改App实体类:
data class App( val name: String, val image: Drawable, val packageName: String // 新增包名字段 )
然后修改适配器构造逻辑,合并两次遍历:
class AdapterForApps(private var context: Context) : RecyclerView.Adapter<AdapterForApps.AppsViewHolder>() { private var list: MutableList<App> = ArrayList() constructor(context: Context, packageManager: PackageManager): this(context) { val packageInfos = packageManager.getInstalledPackages(0) for (packageInfo in packageInfos) { val appName = packageInfo.applicationInfo.loadLabel(packageManager) as String // 保留原有过滤逻辑 if (appName.startsWith("com.", true)) { continue } val appDrawable = packageInfo.applicationInfo.loadIcon(packageManager) // 同时存入包名 list.add(App(appName, appDrawable, packageInfo.packageName)) } } // 其余适配器原有逻辑保持不变 }
2. 修正点击事件逻辑
直接从当前条目对应的App实体取包名,避免错位问题:
val currentApp = list[position] holder.appName.text = currentApp.name holder.appIcon.setImageDrawable(currentApp.image) holder.itemView.setOnClickListener { val intent = context.packageManager.getLaunchIntentForPackage(currentApp.packageName) print("intent is :$intent ") if (intent != null) { // 新增启动flag,避免非Activity上下文启动报错 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) } }
3. 适配高版本系统权限
如果你的应用targetSdk >= 30,在AndroidManifest.xml中增加包可见性声明:
<!-- 仅查询可启动应用的话推荐用这个,不需要申请全量权限 --> <queries> <intent> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent> </queries> <!-- 如果有特殊需求要查询所有应用,再加这个权限 --> <!-- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> -->
内容的提问来源于stack exchange,提问作者Amer Al Haj Ali
相关产品推荐
相关产品推荐

