如何在 Android 11 上启动 ActivityForResult?

How to startActivityForResult on Android 11?

我正在使用 startActivityForResult() 将图像加载到我的应用程序中,方法如下:

val intentForLoadingImage = Intent(Intent.ACTION_GET_CONTENT)
intentForLoadingImage.type = "image/*"
if (intentForLoadingImage.resolveActivity(packageManager) != null) {
    startActivityForResult(intentForLoadingImage, IMAGE_REQUEST_CODE)
}

我已经用将图像加载到 ImageView 的逻辑覆盖了 onActivityResult()。它适用于所有 android 版本(我的应用程序的 minSdkVersion 是 21)但它在 Android 11 上绝对没有任何作用。因为 intentForLoadingImage.resolveActivity(packageManager) returns null 而 activity for无法开始加载图像。

根据 ACTION_GET_CONTENT documentation,实际字符串是 android.intent.action.GET_CONTENT 不是您代码中的 android.media.action.GET_CONTENT。因此正确的包可见性查询是

<queries>
    <intent>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:mimeType="image/*"/>
    </intent>
</queries>

作为替代方案,您还可以捕获 ActivityNotFoundException,这种情况很少见,其中 Storage Access Framework(处理 ACTION_GET_CONTENT)作为自定义的一部分被禁用只读存储器。这种方法不需要包可见性标签:

val intentForLoadingImage = Intent(Intent.ACTION_GET_CONTENT)
intentForLoadingImage.type = "image/*"
try {
    startActivityForResult(intentForLoadingImage, IMAGE_REQUEST_CODE)
} catch (e: ActivityNotFoundException) {
}

我了解了 package visibility privacy updates on Android 11。其中说,

Android 11 changes how apps can query and interact with other apps that the user has installed on a device. Using the element, apps can define the set of other packages that they can access. This element helps encourage the principle of least privilege by telling the system which other packages 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 or higher, you might need to add the element in your app's manifest file. Within the element, you can specify packages by name, by intent signature, or by provider authority.

因此,我在清单文件中添加了以下标签:

<queries>
    <intent>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:mimeType="image/*"/>
    </intent>
</queries>

就是这样!