我是靠谱客的博主 乐观灰狼,最近开发中收集的这篇文章主要介绍Android 11获取第三方应用信息,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Android 11之后禁止获取第三方应用信息了,比如想获取已安装的所有应用,如果目标版本设置为Android 11,则获取不到了,解决方案就是设置目标版本比Android 11小。如果设置目标版本为Android 11或更高,只能获取指定的应用的信息,在清单文件中声明要获取的应用的包名,如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <!--注:目标版本为Android 11时,要获取第三方应用的信息,必须在清单文件声明需要查看的应用的包名。-->
    <queries>
        <package android:name="cn.android666.example" />
    </queries>
    
</manifest>

然后在代码中,就可以判断包名为"cn.android666.example"的应用是否安装,如下:

/**
 * 判断指定包名的app是否安装
 * 注:在Android 11版本的时候不允许获取了,不知道把目标版本设置为Android10会不会还给获取呢?答:根据测试,目标版本为22是可以获取的,那目标版本为10应该也可以。
 * 关于Android11包可见性官网连接:
 * https://developer.android.com/about/versions/11/privacy/package-visibility  版本更新的说明
 * https://developer.android.com/training/basics/intents/package-visibility、
 * https://developer.android.com/training/basics/intents/package-visibility-use-cases
 * @param packageName
 */
fun isInstall(packageName: String): Boolean = try {
    mContext.packageManager.getApplicationIcon(packageName)
    true
} catch (e: PackageManager.NameNotFoundException) {
    false
}

更简单的方式是直接添加可以查询所有应用的权限,这样就不需要使用<queries>声明了,如下:

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

这是一个普通权限,不需要动态申请。

看官方文档描述我以为启动第三方应用也需要添加这个设置,但是实验发现并不需要,代码如下:

button.setOnClickListener {
    val intent = Intent()
    // 参数1为应用的进程包名,参数2为Activity的完整类名
    intent.setClassName("cn.android666.acamera", "cn.android666.acamera.MainActivity")
    startActivity(intent)
}

仔细想想,别人是查询,查询的时候才需要有这个机制,而这里打开第三方应用是填了完整的信息了,已经指定要打开哪个应用的哪个界面了,没有查询操作,所以可以正常打开,即使是使用隐藏意图来打开第三方应用,也是没有查询操作的,也可以正常打开,如下:

val intent = Intent()
intent.action = "abc.def.ghi"
intent.addCategory(Intent.CATEGORY_DEFAULT)
startActivity(intent)

比如我们要通过隐式意图来打开一个播放器来播放我们的音频文件,但有可能这个手机上就没有播放器,任何的播放器都没有,则此时startActivity(intent)就会崩溃,所以正确的做法是在启动之前先查询一下是否有能处理此意图的Activity:packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY),完整代码如下:

val intent = Intent()
intent.action = "abc.def.ghi"
intent.addCategory(Intent.CATEGORY_DEFAULT) 
val queryIntentActivities: MutableList<ResolveInfo> = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
Toast.makeText(this, "有能处理的吗? ${queryIntentActivities.size}", Toast.LENGTH_SHORT).show()
queryIntentActivities.forEach { Log.i("ABCD", it.activityInfo.name) } // 打印可处理的应用的对应Activity
if (queryIntentActivities.isNotEmpty()) {
    startActivity(intent)
}

此时就用到了查询的方法,就需要在清单文件添加相应的设置了,否则这个查询将返回空集合。查询方法会显示警告以提醒我们进行设置,如下:
在这里插入图片描述
为了简单,我们就用最简单的方式就行了,添加一个权限:

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

然后运行即可。在我的小米11 pro上(Android13)测试,它还会弹出一个框让确认一下,如下:
在这里插入图片描述

最后

以上就是乐观灰狼为你收集整理的Android 11获取第三方应用信息的全部内容,希望文章能够帮你解决Android 11获取第三方应用信息所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部