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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:12:09