Link creation
Generate smart links programmatically in your Android app.
Create smart links from your app with generateLink, using a callback or coroutines.
Generating a link
Using a callback
Grovs.generateLink(
title = "Check out this product",
subtitle = "Limited time offer",
imageURL = "https://example.com/image.jpg",
data = mapOf("productId" to "12345", "screen" to "product_detail"),
tags = listOf("promotion", "share"),
tracking = TrackingParams(
utmCampaign = "spring_sale",
utmSource = "in_app",
utmMedium = "share_button"
),
lifecycleOwner = this,
listener = { link, error ->
link?.let { Log.d("Grovs", "Generated: $it") }
error?.let { Log.e("Grovs", "Error: $it") }
}
)The listener runs on the main thread. Pass a lifecycleOwner to drop the callback if the Activity or Fragment is destroyed first.
Using coroutines
lifecycleScope.launch {
try {
val link = Grovs.generateLink(
title = "Check out this product",
subtitle = "Limited time offer",
imageURL = "https://example.com/image.jpg",
data = mapOf("productId" to "12345"),
tags = listOf("promotion"),
tracking = TrackingParams(
utmCampaign = "spring_sale",
utmSource = "in_app",
utmMedium = "share_button"
)
)
Log.d("Grovs", "Generated: $link")
} catch (e: GrovsException) {
Log.e("Grovs", "Error: ${e.message}")
}
}The SDK must be configured and authenticated. Until then the callback reports a GrovsException and the coroutine form throws one.
Parameters
| Parameter | Type | Description |
|---|---|---|
title | String? | Link preview title |
subtitle | String? | Link preview subtitle |
imageURL | String? | Link preview image URL |
data | Map<String, Serializable>? | Custom payload delivered on deep link open |
tags | List<String>? | Tags for filtering and analytics |
customRedirects | CustomRedirects? | Override the default redirect per platform. See Custom redirects |
showPreviewIos | Boolean? | Show the link preview page on iOS. null uses the project default |
showPreviewAndroid | Boolean? | Show the link preview page on Android. null uses the project default |
copyToClipboardIos | Boolean? | Copy the link to the clipboard from the preview page on iOS, for clipboard-assisted deferred deep linking. null inherits the project setting |
copyToClipboardAndroid | Boolean? | Same, for Android. null inherits the project setting |
tracking | TrackingParams? | UTM campaign, source and medium |
lifecycleOwner | LifecycleOwner? | Callback form only. Scopes the callback to a lifecycle |
listener | GrovsLinkGenerationListener | Callback form only. Receives the link or a GrovsException |
copyToClipboardIos and copyToClipboardAndroid apply only when that platform shows the preview page. Passing false is an explicit override, unlike omitting the parameter.
Custom redirects
Override where a link sends users per platform:
val redirects = CustomRedirects(
ios = CustomLinkRedirect(link = "https://example.com/ios-promo"),
android = CustomLinkRedirect(link = "https://example.com/android-promo"),
desktop = CustomLinkRedirect(link = "https://example.com/desktop-promo", openAppIfInstalled = false)
)
Grovs.generateLink(
title = "Special offer",
data = mapOf("promoId" to "summer25"),
customRedirects = redirects,
lifecycleOwner = this,
listener = { link, error ->
link?.let { Log.d("Grovs", "Generated: $it") }
}
)With openAppIfInstalled true (default), the app opens if installed, otherwise the redirect URL is used. With false, the redirect URL is always used.
Sharing the link
Launch a share intent once the link is ready:
Grovs.generateLink(
title = "Share this",
data = mapOf("itemId" to "abc"),
lifecycleOwner = this,
listener = { link, _ ->
link?.let {
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, it)
type = "text/plain"
}
startActivity(Intent.createChooser(sendIntent, "Share via"))
}
}
)