获取手机上所有应用的信息,解决访问不到应用包名-Android 11以上的软件包可见性

目的:想获取手机上所有应用的基本信息,如包名,版本号,图标什么的.

通过packageManager.getInstalledPackages方法,代码如下


    @SuppressLint("QueryPermissionsNeeded")
    fun getInstalledPackagesInfo(context: Context): MutableList<AppInfo> {
    
    
        // app包名包含的字符
        val searchStringJlc = "tencent"
        // app包名包含的字符
        val searchStringJls = "ali"
        // 可配置的app, provider中包含的字符
        val searchProviderConfig = "jlcProvider"

        val packageManager = context.packageManager
        //获取应用的Activity和 Content Provider 的信息
        val packages =
            packageManager.getInstalledPackages(PackageManager.GET_ACTIVITIES or PackageManager.GET_PROVIDERS)
        packageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES)
        val appList = mutableListOf<AppInfo>()
        LogUtils.d("检查的包名:${
      
      packages.toString()}")
        for (packageInfo in packages) {
    
    
            val packageName = packageInfo.packageName
            if (packageName.contains(searchStringJlc) || packageName.contains(searchStringJls,ignoreCase = true)
            ) {
    
    
                val applicationInfo = packageManager.getApplicationInfo(packageName, 0)
                val appName = packageManager.getApplicationLabel(applicationInfo).toString()
                val versionName = packageInfo.versionName
                val versionCode =
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
    
    
                        packageInfo.longVersionCode
                    } else {
    
    
                        packageInfo.versionCode.toLong()
                    }
                val authorityList = mutableListOf<String>()

                // 获取应用的 Content Provider 的 authority
                val providers = packageManager.queryContentProviders(
                    packageName,
                    packageInfo.applicationInfo.uid,
                    0
                )
                for (providerInfo in providers) {
    
    
                    if (providerInfo.authority.contains(searchProviderConfig)) {
    
    
                        authorityList.add(providerInfo.authority)
                    }
                }

                // 获取应用的图标
                val appIcon = packageManager.getApplicationIcon(applicationInfo)

                // 构造 AppInfo 对象并添加到列表
                val appInfo =
                    AppInfo(
                        packageName,
                        appName,
                        versionName,
                        versionCode,
                        authorityList,
                        appIcon
                    )
                LogUtils.d("收录的应用:${
      
      appInfo.toString()}")
                appList.add(appInfo)
            }
        }
        return appList

    }
/**
 * 应用信息
 */
data class AppInfo(
    //应用包名
    val packageName: String,
    //应用名称
    var appName: String,
    // 版本名称
    var versionName: String,
    //版本号
    var versionCode: Long,
    // provider名称
    var authority: MutableList<String>,
    // 应用图标
    var icon: Drawable,
)

问题,在Android11 设备上三方包名被加密显示了

如下,获取的包名

检查的包名:[PackageInfo{
    
    88c0018 com.miui.screenrecorder},
 PackageInfo{
    
    6338a71 com.miui.contentextension}, 
 PackageInfo{
    
    c869056 com.qualcomm.qti.qcolor}, 
 PackageInfo{
    
    dc9d8d7 com.google.android.ext.services},
  PackageInfo{
    
    c4d05c4 com.qualcomm.qti.improvetouch.service}, ....

解决办法

方法一、在AndroidManifest,xml 配置查询所有应用及与之交互

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
    tools:ignore="QueryAllPackagesPermission" />

实测有效

方法二、如果上面权限失效,添加 queries访问指定具体应用的包名

在AndroidManifest,xml 配置访问 特定应用可访问包信息

<manifest xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 联网权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- Android 11的 软件包可见性 权限允许你获取应用的包大小信息,以及访问与包相关的其他信息,例如应用名称、版本名称等。 -->
    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
        tools:ignore="QueryAllPackagesPermission" />
    <!--针对性配置(如果上面权限失效),特定应用可访问包信息-->
    <queries>
       <!--微信-->
        <package android:name="com.tencent.mm" />
        <!--支付宝-->
        <package android:name="com.eg.android.AlipayGphone" />
        <package android:name="hk.alipay.wallet" />
    </queries>
    <application
        android:name=".MApplicaiton"
...

实测有效

参考:Android 11 适配 软件包可见性

猜你喜欢

转载自blog.csdn.net/ly_xiamu/article/details/132428433