我正在开发的应用程序使用 aFile
作为照片捕获的目标。这是由用户使用选择相机应用程序在外部执行的Intent(ACTION_IMAGE_CAPTURE)
。自从将 build 和 target-sdk 升级到 29 后,出现了一系列问题,首先是限制自由访问外部存储上的文件。第一个更改是使用应用程序的私有缓存目录之一,例如:
File.createTempFile("tempImage", ".jpg", context.cacheDir)
或应用程序私有外部存储目录:
File.createTempFile("tempImage", ".jpg", context.getExternalFilesDir(Environment.DIRECTORY_PICTURES))
结合 FileProvider 访问file_paths.xml
,例如:
<paths>
<external-path name="images" path="Pictures/" /><!-- prior to SDK-29, use public external storage -->
<external-files-path name="externalImages" path="Pictures/" />
<files-path name="internalImages" path="internalImages/"/>
<cache-path name="cache" path="/" />
</paths>
这些在正确配置后现在运行良好,但是实现了“保存到图库”功能,例如:通知其他应用程序新图像不再适用于运行 Android-10 的设备
// use FileProvider to make this new photo publicly accessible
val shareableUri = FileProvider.getUriForFile(context, FILE_PROVIDER_AUTHORITY, newImage)
context.sendBroadcast(
Intent(ACTION_MEDIA_SCANNER_SCAN_FILE).apply { data = uris.externalUri }
)
这种方法应该有效,但不管原始图像保存在哪里(私有应用程序目录、缓存目录、外部私有)
MediaScannerConnection.scanFile(context, arrayOf(newImage.absolutePath), arrayOf("image/jpeg")) { path: String, uri: Uri? ->
if (uri == null) {
throw IllegalStateException("media scan failed...")
} else {
// successful
}
}
Android 的 SDK-29 中是否有新的限制需要更改 MediaScanning,特别是与扫描(可能)私有图像文件的方式有关?我注意到MediaScanner
方法大多期望String
路径而不是 URI,所以这让我认为新的限制不适用于它,因为它是一个系统组件。