Files, Medias, Folder Picker and File saver library for Kotlin Multiplatform and Compose Multiplatform
Picker Kotlin is a library that allows you to pick and save files in a simple way. On each platform, it uses the native file picker API to provide a consistent experience.
Pick a file, a directory or save a file in common code:
// Pick a file
val file = Picker.pickFile()
// Pick a directory
val directory = Picker.pickDirectory()
// Save a file
val file = Picker.saveFile(
extension = "txt",
bytes = "Hello, World!".encodeToByteArray()
)
Get file information in common code:
val filePath = file?.path
val fileName = file?.name
val bytes = file?.readBytes()
Compose Multiplatform integration made simple:
// Pick files from Compose
val launcher = rememberFilePickerLauncher(PickerSelectionMode.Multiple) { files ->
// Handle picked files
}
// Use the pickerLauncher
Button(onClick = { launcher.launch() }) {
Text("Pick files")
}
repositories {
mavenCentral()
}
dependencies {
// Enables Picker without Compose dependencies
implementation("io.github.vinceglb:picker-core:0.3.2")
// Enables Picker with Composable utilities
implementation("io.github.vinceglb:picker-compose:0.3.2")
}
Using Picker Core on Android requires an initialization. To be able to use the ActivityResultContract
under the hood, you need to initialize Picker in your ComponentActivity
.
// MainActivity.kt
class MyApplication : ComponentActivity() {
override fun onCreate() {
super.onCreate()
Picker.init(this)
}
}
In every other case, Picker is ready to use without any initialization.
You can pick different types of files with PickerSelectionType
:
Image
: Pick an image file.Video
: Pick a video file.ImageAndVideo
: Pick an image or a video file.File
: Pick any file. It is the default type. It's possible to specify a list of extensions.
val imageType = PickerSelectionType.Image
val videoType = PickerSelectionType.Video
val imageAndVideoType = PickerSelectionType.ImageAndVideo
val fileType = PickerSelectionType.File(extensions = listOf("pdf", "docx"))
You can pick files in different modes with PickerSelectionMode
. The mode will change the output type. Single
is the default mode.
val singleMode = PickerSelectionMode.Single
val multipleMode = PickerSelectionMode.Multiple
You can launch the picker with Picker.pickFile
or rememberFilePickerLauncher
:
// Picker Core
val file = Picker.pickFile(
type = PickerSelectionType.Image,
mode = PickerSelectionMode.Single,
title = "Pick an image",
initialDirectory = "/custom/initial/path"
)
// Picker Compose
val launcher = rememberFilePickerLauncher(
type = PickerSelectionType.ImageAndVideo,
mode = PickerSelectionMode.Multiple,
title = "Pick a media",
initialDirectory = "/custom/initial/path"
) { files ->
// Handle the picked files
}
launcher.launch()
You can pick a directory with Picker.pickDirectory
or rememberDirectoryPickerLauncher
:
// Picker Core
val directory = Picker.pickDirectory(
title = "Pick a directory",
initialDirectory = "/custom/initial/path"
)
// Picker Compose
val launcher = rememberDirectoryPickerLauncher(
title = "Pick a directory",
initialDirectory = "/custom/initial/path"
) { directory ->
// Handle the picked directory
}
launcher.launch()
The directory picker is available on all platforms, expect for WASM / JS. To check if the directory picker is available from the common code, you can use Picker.isDirectoryPickerSupported()
.
val directoryModeSupported = Picker.isDirectoryPickerSupported()
You can save a file with Picker.saveFile
or rememberSaveFilePickerLauncher
:
// Picker Core
val file = Picker.saveFile(
baseName = "myTextFile",
extension = "txt",
initialDirectory = "/custom/initial/path",
bytes = "Hello, World!".encodeToByteArray()
)
// Picker Compose
val launcher = rememberFileSaverLauncher() { file ->
// Handle the saved file
}
launcher.launch(
baseName = "myTextFile",
extension = "txt",
initialDirectory = "/custom/initial/path",
bytes = "Hello, World!".encodeToByteArray()
)
The PlatformFile
and PlatformDirectory
classes are wrappers around the platform file system. It allows you to get the file name, path and read the file content in common code.
val platformFile: PlatformFile = ...
val filePath: String? = platformFile.path
val fileName: String = platformFile.name // Base name with extension
val baseName: String = platformFile.baseName
val extension: String = platformFile.extension
val bytes: ByteArray = platformFile.readBytes() // suspend function
val platformDirectory: PlatformDirectory = ...
val directoryPath: String? = platformDirectory.path
On each platform, you can get the original platform file:
// Android
val uri: Uri = platformFile.uri
val uri: Uri = platformDirectory.uri
// iOS / macOS
val nsUrl: NSURL = platformFile.nsUrl
val nsUrl: NSURL = platformDirectory.nsUrl
// JVM
val file: java.io.File = platformFile.file
val file: java.io.File = platformDirectory.file
// WASM / JS
val file: org.w3c.files.File = platformFile.file
val file: org.w3c.files.File = // PlatformDirectory not supported on WASM / JS
You can find 2 sample projects in the samples
directory:
sample-core
: A Kotlin Multiplatform project using Picker in a shared viewModel targeting Android, JVM, WASM, JS, iOS Swift, macOS Swift and iOS Compose.sample-compose
: A Compose Multiplatform project using Picker in a Composable targeting Android, iOS, JVM, WASM,
Picker Kotlin uses the native file picker API on each platform:
- On Android, it uses
PickVisualMedia
,OpenDocument
andOpenDocumentTree
contracts. - On iOS, it uses both
UIDocumentPickerViewController
andPHPickerViewController
APIs. - On macOS, it uses the
NSOpenPanel
API. - On JVM, it uses JNA to access the file system on Windows and macOS and Awt FileDialog on Linux.
- On WASM / JS, it uses the
input
element with thefile
type.
Also, Picker Kotlin uses the bear minimum of dependencies to be as lightweight as possible.
Picker Core uses the following libraries:
- KotlinX Coroutines
- Only Android: AndroidX Activity KTX
- Only JVM: Java Native Access - JNA
Picker Compose uses the following libraries:
- Jetbrains Compose Runtime
- Only Android: AndroidX Activity Compose
Picker Kotlin is inspired by the following libraries:
- compose-multiplatform-file-picker
- peekaboo
- Calf
- jnafilechooser
- swing-jnafilechooser
- IntelliJ Community Foundation
Made with β€οΈ by Vince