Skip to content

Instantly share code, notes, and snippets.

@wangyung
Created August 6, 2023 05:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wangyung/e6e8e7b1a2c24ea31e92094b968025f7 to your computer and use it in GitHub Desktop.
Save wangyung/e6e8e7b1a2c24ea31e92094b968025f7 to your computer and use it in GitHub Desktop.
Create files in Android's external folder
/**
* Exports file to the given target folder on Android.
*
* ref: https://stackoverflow.com/questions/75055593/access-images-in-external-storage-created-by-my-app
*/
@Throws(IOException::class)
suspend fun exportImage(
contentResolver: ContentResolver,
file: File,
targetFolder: String,
rootDirectory: String = Environment.DIRECTORY_PICTURES
) = withContext(Dispatchers.IO) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
saveImageApi29(contentResolver, file, targetFolder, rootDirectory)
} else {
saveImageLegacy(contentResolver, file, targetFolder, rootDirectory)
}
}
@RequiresApi(29)
@Throws(IOException::class)
private fun saveImageApi29(
contentResolver: ContentResolver,
file: File,
targetFolder: String,
rootDirectory: String
) {
val contentUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
val path = "$rootDirectory/$targetFolder"
val projection = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, file.name)
put(MediaStore.Images.Media.SIZE, file.length())
put(MediaStore.Images.Media.RELATIVE_PATH, path)
}
contentResolver.insert(contentUri, projection)?.also { uri ->
contentResolver.openOutputStream(uri)?.use { outputStream ->
val fileStream = FileInputStream(file)
fileStream.copyTo(outputStream)
}
} ?: throw IOException("Can't create file ${file.name} in path $path")
}
@Throws(IOException::class)
private fun saveImageLegacy(
contentResolver: ContentResolver,
file: File,
targetFolder: String,
rootDirectory: String
) {
val collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val dir = Environment.getExternalStoragePublicDirectory(rootDirectory).absolutePath + "/$targetFolder"
val directory = File(dir)
if (!directory.exists())
directory.mkdirs()
val image = File(dir, file.name)
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, image.name)
put(MediaStore.Images.Media.SIZE, image.length())
put(MediaStore.Images.Media.MIME_TYPE, "image/png")
put(MediaStore.Images.Media.DATA, image.path)
}
contentResolver.insert(collection, values)?.also { uri ->
contentResolver.openOutputStream(uri)?.use { outputStream ->
val fileStream = FileInputStream(file)
fileStream.copyTo(outputStream)
}
} ?: throw IOException("Can't create file ${file.name} in path $dir")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment