私が取り組んでいるアプリは、File
写真キャプチャのターゲットとして a を使用します。これは、ユーザーが を使用してカメラアプリを選択することにより、外部で実行されます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>
これらは適切に構成された後はうまく機能しますが、「ギャラリーに保存」機能を実装します。
// 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 }
)
このアプローチは機能するはずですが、元の画像が保存されている場所 (private-app-dir、cache-dir、external-private) に関係なく機能しません。
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
メソッドはほとんどの場合、URI ではなくパスを想定していることに気付きString
ました。そのため、システム コンポーネントであるため、新しい制限は適用されないと思います。