2

我正在开发的应用程序使用 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,所以这让我认为新的限制不适用于它,因为它是一个系统组件。

4

1 回答 1

2

默认情况下,面向 Android 10(API 级别 29)及更高版本的应用会获得对外部存储设备或范围存储的范围访问权限。

因此您需要使其与 scopedStorage 兼容,但您可以使用 Google Android 开发人员指南中提到的这种临时方法。

在您的应用与范围存储完全兼容之前,您可以根据应用的目标 SDK 级别或 requestLegacyExternalStorage 清单属性暂时选择退出:

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10 or higher. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

访问此链接了解更多信息: https ://developer.android.com/training/data-storage/files/external-scoped

于 2019-09-17T07:09:07.763 回答