在 Android 11 上调用 getPackageInfo 时出现 NameNotFoundException

NameNotFoundException when calling getPackageInfo on Android 11

在将 targetSdkVersion 设置为 30 (Android 11) 后,我在对已知存在的包执行 packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS) 时得到 android.content.pm.PackageManager$NameNotFoundException

堆栈跟踪如下:

android.content.pm.PackageManager$NameNotFoundException: com.google.android.apps.maps
        at android.app.ApplicationPackageManager.getPackageInfoAsUser(ApplicationPackageManager.java:202)
        at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:174)

https://developer.android.com/preview/privacy/package-visibility所述:

Android 11 changes how apps can query and interact with other apps that the user has installed on a device. Using the new element, apps can define the set of other apps that they can access. This element helps encourage the principle of least privilege by telling the system which other apps to make visible to your app, and it helps app stores like Google Play assess the privacy and security that your app provides for users.

If your app targets Android 11, you might need to add the element in your app's manifest file. Within the element, you can specify apps by package name or by intent signature.

因此您要么必须停止正在做的事情,要么请求访问有关某些软件包的信息,或者 - 如果您有理由这样做 - 使用权限 QUERY_ALL_PACKAGES.

查询特定包并与之交互

要查询特定包并与之交互,您可以像这样更新 AndroidManifest.xml

<manifest ...>
    ...
    <queries>
        <package android:name="com.example.store" />
        <package android:name="com.example.services" />
    </queries>
    ...
     <application ...>
    ...
</manifest>

查询所有应用程序并与之交互

我有一个应用需要能够为所有应用请求信息。您所要做的就是将以下内容添加到 AndroidManifest.xml:

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

AndroidManifest.xml 中需要为 Android 11 添加这个,它对我有用

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


    <queries>
        <intent>
            <action android:name="android.intent.action.MAIN" />
        </intent>
    </queries>