-
Notifications
You must be signed in to change notification settings - Fork 2
intent launcher README
Type-safe Android Intent launcher with graceful onUnsupported fallback for all other KMP targets.
cmp-intent-launcher wraps Android's ActivityResultLauncher pattern in a coroutine-friendly,
Compose-ready IntentLauncher class. Build intents via a Kotlin DSL, await the result, and
handle the typed IntentResult — no callbacks, no onActivityResult. Picker contracts
(PickImage, PickMultipleImages, PickDocument, PickContact) are wired to native UIKit pickers
on iOS (PHPickerViewController, UIDocumentPickerViewController, CNContactPickerViewController);
unsupported actions on any platform route to the caller's onUnsupported lambda.
Experimental API: annotated with
@ExperimentalIntentLauncherApi. Opt in with@OptIn(ExperimentalIntentLauncherApi::class)or the compiler flag below.
| Platform | Real impl | onUnsupported |
Notes |
|---|---|---|---|
| Android | ✅ | — | ActivityResultLauncher + coroutine bridge |
| iOS | ✅ pickers | ✅ | PHPicker (image) + UIDocumentPicker (file) + CNContactPicker (contact); arbitrary actions → onUnsupported
|
| macOS | ⚠ onUnsupported | ✅ | NSOpenPanel planned for v0.2 |
| JVM | 🟡 partial | — | java.awt.Desktop file/URI open; no result callback |
| JS | ⚠ onUnsupported | ✅ | v1 TS9 out-of-scope |
| wasmJs | ⚠ onUnsupported | ✅ | v1 TS9 out-of-scope |
| tvOS | ⛔ out-of-scope | — | v1 TS9 explicitly excluded |
| watchOS | ⛔ out-of-scope | — | v1 TS9 explicitly excluded |
| Linux | ⛔ out-of-scope | — | v1 TS9 explicitly excluded |
| mingw | ⛔ out-of-scope | — | v1 TS9 explicitly excluded |
| wasmWasi | ⛔ out-of-scope | — | v1 TS9 explicitly excluded |
Tier-3 targets (tvOS, watchOS, Linux, mingw, wasmWasi) are explicitly out-of-scope for v1 per Phase 0 spike TS9.
@OptIn(ExperimentalIntentLauncherApi::class)
@Composable
fun PickFileScreen() {
val launcher = rememberIntentLauncher()
Button(onClick = {
scope.launch {
val result = launcher.launch {
action = Intent.ACTION_GET_CONTENT
type = "*/*"
}
when (result) {
is IntentResult.Ok -> handleData(result.data)
is IntentResult.Cancelled -> { /* user dismissed */ }
is IntentResult.Failed -> logError(result.cause)
}
}
}) {
Text("Pick File")
}
}@ExperimentalIntentLauncherApi
expect class IntentLauncher {
suspend fun launch(block: IntentBuilder.() -> Unit): IntentResult
}@Composable
fun rememberIntentLauncher(): IntentLauncherclass IntentBuilder {
var action: String?
var type: String?
fun data(uri: String)
fun extra(key: String, value: Any)
var flags: Int
fun targetPackage(packageName: String) // Android only — targeted launch
}sealed class IntentResult {
data class Ok(val data: IntentData?) : IntentResult()
object Cancelled : IntentResult()
data class Failed(val cause: IntentError) : IntentResult()
}sealed class IntentError {
object UnsupportedPlatform : IntentError()
object NoHandler : IntentError()
object UserGestureMissing : IntentError()
data class Unknown(val message: String) : IntentError()
}object ResultContracts {
val PICK: String // ACTION_PICK
val GET_CONTENT: String // ACTION_GET_CONTENT
val OPEN_DOCUMENT: String // ACTION_OPEN_DOCUMENT
val CREATE_DOCUMENT: String
val SEND: String // ACTION_SEND
}-
rememberIntentLauncher()must be called at Compose composition time — not inside aLaunchedEffectoronClicklambda. It registers theActivityResultLauncherduring composition. -
JVM partial:
Desktop.open()/Desktop.browse()runs but returnsIntentResult.Ok(null)— no result data is propagated back. - On non-Android targets,
onUnsupportedsurfaces asIntentResult.Failed(IntentError.UnsupportedPlatform).
- SETUP.md — Integration steps (includes Android Activity wiring)
-
CLAUDE_AI_SETUP.md — AI-assisted setup with
/sync-intent-launcher
** Partials**
App Intents
Bubble
Clipboard
Cookbook
- Clipboard Copy Text
- Clipboard Read Text
- Consumer Anon Key Setup
- Crashlytics Attribution Per Library
- Ifonline Block
- Index
- Index
- Index
- Index
- Open Url Compose
- Pick And Share Image
- React To Offline
- Register Firebase Hooks
- Share Pdf Android
- Share Text
- Wifi Vs Cellular
Firebase Analytics
In App Update
Intent Launcher
Inter App Comms
Modules
- Cmp App Intents
- Cmp App Intents Compose
- Cmp Bubble
- Cmp Clipboard
- Cmp Deep Link
- Cmp Firebase Analytics
- Cmp In App Update
- Cmp Intent Launcher
- Cmp Intent Launcher Compose
- Cmp Library
- Cmp Network Monitor
- Cmp Network Monitor Compose
- Cmp Observe
- Cmp Observe Koin
- Cmp Open Url
- Cmp Pdf Generator
- Cmp Product Tickets
- Cmp Remote Config
- Cmp Share
- Cmp Share Compose
- Cmp Toast
Network Monitor
Open Url
Pdf Generator
Remote Config
Share
Toast
User Tickets
General