Android 2023年后获取自研已安装用户应用列表的可行性及实现方法
实现方案:获取自己开发的Android应用列表(Android 11+兼容)
该需求完全可以实现,且无需使用QUERY_ALL_PACKAGES这类敏感权限,以下是具体操作步骤:
核心思路
由于你知晓自己开发的所有应用的包名,可通过精准包名查询的方式绕过系统对应用列表的限制,同时结合应用签名验证或自定义跨应用通信机制,确保只获取自己开发的应用。
1. 声明可查询的目标包名(Android 11+必备)
在主应用的AndroidManifest.xml中添加<queries>标签,列出所有自己开发的应用包名,系统会允许主应用查询这些指定包名的应用状态:
<manifest ...> <queries> <package android:name="com.yourteam.app.moduleA" /> <package android:name="com.yourteam.app.moduleB" /> <!-- 依次添加所有自己开发的应用包名 --> </queries> <!-- 其他Manifest配置 --> </manifest>
2. 单个应用安装状态查询
通过PackageManager直接查询指定包名的应用是否存在,代码示例(Kotlin):
fun isSelfAppInstalled(packageName: String, context: Context): Boolean { return try { // 传入0表示仅获取基础包信息,无需额外权限 context.packageManager.getPackageInfo(packageName, 0) true } catch (e: PackageManager.NameNotFoundException) { // 包名不存在,说明应用未安装 false } }
3. 批量获取自己的应用列表
维护一个自己开发的应用包名与名称的映射列表,遍历调用上述方法,筛选出已安装的应用:
// 预定义自己的应用包名与名称映射 private val selfApps = mapOf( "com.yourteam.app.moduleA" to "模块A", "com.yourteam.app.moduleB" to "模块B", "com.yourteam.app.moduleC" to "模块C" ) fun getInstalledSelfApps(context: Context): List<String> { val installedApps = mutableListOf<String>() selfApps.forEach { (packageName, appName) -> if (isSelfAppInstalled(packageName, context)) { installedApps.add(appName) } } return installedApps }
4. 进阶:通过签名验证筛选(可选)
如果所有自己开发的应用使用同一签名证书,可通过验证应用签名的方式,确保查询到的应用确实是自己开发的(避免包名被恶意仿冒):
private fun getSelfAppSignature(context: Context): String? { return try { val packageInfo = context.packageManager.getPackageInfo( context.packageName, PackageManager.GET_SIGNATURES ) packageInfo.signatures.firstOrNull()?.toCharsString() } catch (e: Exception) { null } } fun isTrustedSelfApp(packageName: String, context: Context): Boolean { val selfSignature = getSelfAppSignature(context) ?: return false return try { val targetInfo = context.packageManager.getPackageInfo( packageName, PackageManager.GET_SIGNATURES ) targetInfo.signatures.any { it.toCharsString() == selfSignature } } catch (e: PackageManager.NameNotFoundException) { false } }
将此方法与安装状态查询结合,即可确保仅获取签名一致的自己开发的应用。
5. 跨应用主动通信(可选)
如果需要实时感知自己应用的安装/卸载状态,可在每个自己开发的应用中添加自定义广播:
- 子应用安装完成后发送自定义广播:
// 子应用的安装完成广播(在Receiver或Application类中发送) val intent = Intent("com.yourteam.SELF_APP_INSTALLED") intent.putExtra("package_name", packageName) intent.putExtra("app_name", "模块A") context.sendBroadcast(intent)
- 主应用注册广播接收器,接收并记录已安装的自己应用:
class SelfAppReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { intent?.let { val packageName = it.getStringExtra("package_name") val appName = it.getStringExtra("app_name") // 将信息存入本地数据库或内存列表 } } }
同时在主应用Manifest中注册接收器:
<receiver android:name=".SelfAppReceiver"> <intent-filter> <action android:name="com.yourteam.SELF_APP_INSTALLED" /> </intent-filter> </receiver>
注意事项
- 避免使用
QUERY_ALL_PACKAGES权限:该权限属于敏感权限,Google Play审核时会要求提供合理的使用理由,而通过<queries>精准声明包名的方式更合规。 - 包名必须准确:确保
selfApps映射中的包名与自己开发的应用完全一致,否则会导致查询失败。
内容的提问来源于stack exchange,提问作者user15108413
相关产品推荐
相关产品推荐

