Nie*_*orp 6 android runtime-permissions android-jetpack-compose android-exifinterface photo-picker
我的目标是 Android 13 并使用新的照片选择器来检索图像。例如
val photoPicker = rememberLauncherForActivityResult(
contract = ActivityResultContracts.PickMultipleVisualMedia()
) { uris: List<Uri> -> handleUris(context, uris) ) }) }
photoPicker.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
fun handleUris(context: Context, uris: List<Uri>) {
for (uri in uris) {
context.contentResolver.openInputStream(uri)!!.use { stream ->
ExifInterface(stream).let { exif ->
val dateTime = exif.dateTime // present
val latLng = exif.latLong // always null
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我发现了什么:
自 Android 10 起,当您检索媒体时,GPS 信息不再包含在 EXIF 数据中。根据 2019 年的这段视频,您需要请求运行时权限ACCESS_MEDIA_LOCATION。
他们解释说这是一个运行时权限,但用户无法在系统设置中看到该权限(这本身就很奇怪)。他们还声称您需要READ_EXTERNAL_STORAGE媒体许可。
这篇文档还讨论了媒体位置权限。
使用以下方式请求许可ACCESS_MEDIA_LOCATION:
val locationPermissionState = rememberPermissionState(
permission = ACCESS_MEDIA_LOCATION
)
locationPermissionState.launchPermissionRequest()
Run Code Online (Sandbox Code Playgroud)
它实际上确实会导致一个权限对话框,要求“应用程序访问此设备上的照片和视频”。当授予 EXIF 位置数据时,但仍然不存在。
啊,对了。根据视频我们READ_EXTERNAL_STORAGE也需要。
val locationPermissionState = rememberMultiplePermissionsState(
permissions = listOf(ACCESS_MEDIA_LOCATION, READ_EXTERNAL_STORAGE)
)
Run Code Online (Sandbox Code Playgroud)
没有显示对话框。检查ContextCompat.checkSelfPermission()它似乎我们有ACCESS_MEDIA_LOCATION权限,但没有READ_EXTERNAL_STORAGE。为什么它不显示一个对话框?
查看Android 13 的文档,似乎已READ_EXTERNAL_STORAGE被更细化的权限所取代。
当针对 Android 13 时,您似乎不应READ_EXTERNAL_STORAGE 再使用该权限。对于我们需要的图像READ_MEDIA_IMAGES。但请求该权限也不会显示对话框。
我还尝试了MediaStore.setRequireOriginal(Uri)API,它应该可以防止 EXIF 元数据被编辑,根据文档,当UnsupportedOperationException您没有权限时,这会抛出一个错误ACCESS_MEDIA_LOCATION
。但对我来说,它会抛出一个SecurityException带有消息的Calling uid does not have permission to access picker uri: content://etc。
那么,是的,我如何获取 EXIF 数据中的 GPS 位置?我实际需要哪些权限以及如何请求它们?
编辑:
好的,所以在 Android 11 上,当照片选择器不可用时,它会Intent(Intent.ACTION_OPEN_DOCUMENT)在内部使用。返回的 Uri 如下所示:content://com.android.providers.media.documents/document/image%3A283
我可以从该 uri 检索 GPS 位置,而无需授予ACCESS_MEDIA_LOCATION,READ_MEDIA_IMAGE或READ_EXTERNAL_STORAGE权限。与我能找到的大多数文档相反。也不MediaStore.setRequireOriginal(Uri)需要。
这让我认为这是照片选择器问题而不是权限问题。所以我想我在 Android 13 上进行测试时不使用照片选择器。
我在用着
val photoPicker = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent()
) { uri: Uri? -> }
Run Code Online (Sandbox Code Playgroud)
相反,现在Intent(Intent.ACTION_GET_CONTENT)在内部使用。uri 看起来像这样content://com.android.providers.media.documents/document/image%3A1000000049,我再次能够在没有授予任何上述权限的情况下提取 GPS 数据,并且 no setRequireOriginal。
这让我得出结论,有关媒体位置的文档是错误的......不需要许可(除非他们谈论的是纬度/经度以外的其他元数据)。SecurityException当使用setRequireOriginal和/或 exif 数据编辑时,新的照片选择器 uri 肯定会发生一些事情。我还不知道这是否是预期的行为。
| 归档时间: |
|
| 查看次数: |
1685 次 |
| 最近记录: |