Android Getting Started
Install the Android SDK, hook it up to your project, and validate the flow.
1. Prerequisites
Development Environment
- Android Studio Giraffe or newer
- Gradle 8+
- Min SDK 21+
ULink Account Setup
- ULink account and project (create one here)
- API key generated from Dashboard → Settings → API Keys → Generate API Key
- Domain configured in your project (Domains → Add Domain)
2. Add the dependency
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}
dependencies {
implementation("ly.ulink:sdk:1.0.0")
}
3. Configure Deep Links in AndroidManifest.xml
Before initializing the SDK, you need to configure your app to handle incoming links. Android supports two types of deep links:
- Android App Links (e.g.,
https://yourdomain.com) - HTTPS links verified by Android that open your app directly - Custom URL Schemes (e.g.,
myapp://) - Custom schemes that always open your app (no verification required)
Step 3.1: Add Required Permissions
First, add the necessary permissions to your AndroidManifest.xml file:
- Open
app/src/main/AndroidManifest.xmlin your project - Add these permissions inside the
<manifest>tag, before the<application>tag:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
These permissions go at the top level of your manifest, not inside the <application> tag.
Step 3.2: Configure Android App Links (Recommended)
Android App Links are the recommended approach because they work seamlessly and don't show a disambiguation dialog.
- Open
app/src/main/AndroidManifest.xml - Find your main activity (usually
MainActivity) - Add an intent filter with
android:autoVerify="true"inside the activity:
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop">
<!-- Existing launcher intent filter -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Android App Link intent filter -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="links.shared.ly" />
</intent-filter>
</activity>
- Replace
links.shared.lywith the domain you configured in the ULink dashboard - If using a custom domain, use that domain (e.g.,
android:host="yourdomain.com") - The host must match exactly with the domain in your ULink dashboard
- The
android:autoVerify="true"attribute tells Android to verify the domain association
Using android:launchMode="singleTop" ensures that if your app is already running, it reuses the existing activity instance instead of creating a new one. This is important for handling deep links properly.
Step 3.3: Configure Custom URL Scheme (Optional)
If you want to support custom URL schemes (e.g., myapp://path), add an additional intent filter:
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop">
<!-- ... existing intent filters ... -->
<!-- Custom URL scheme intent filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" />
</intent-filter>
</activity>
- Use lowercase letters and numbers only
- Keep it short and memorable (e.g.,
myapp,shop,news) - Avoid special characters or spaces
- If you add a custom scheme, also add it to your ULink dashboard configuration
Step 3.4: Create Application Class and Initialize SDK
Create a custom Application class to initialize the ULink SDK when your app starts:
- Create a new Kotlin file:
app/src/main/java/com/yourapp/MyApp.kt(replacecom.yourappwith your package name) - Add the following code:
package com.yourapp // Replace with your actual package name
import android.app.Application
import ly.ulink.sdk.ULink
import ly.ulink.sdk.models.ULinkConfig
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
ULink.initialize(
context = this,
config = ULinkConfig(
apiKey = "ULINK_API_KEY", // Replace with your API key
baseUrl = "https://api.ulink.ly",
debug = true // Set to false in production
)
)
}
}
- Register your Application class in
AndroidManifest.xml:
<application
android:name=".MyApp"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
...>
<!-- ... rest of your manifest ... -->
</application>
Make sure to add android:name=".MyApp" to your <application> tag in the manifest. Replace MyApp with the actual name of your Application class if different.
Step 3.5: Handle Deep Links in Your Activity (Optional)
If you're using automatic deep link integration (enabled by default), the SDK handles intents automatically. However, if you need manual control or want to handle the initial intent, add this to your MainActivity:
class MainActivity : AppCompatActivity() {
private lateinit var ulink: ULink
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Get the ULink instance (already initialized in Application class)
ulink = ULink.getInstance()
// Handle initial intent if app was opened via deep link
handleIntent(intent)
// Listen to deep link streams
observeDeepLinks()
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent) // Update the activity's intent
handleIntent(intent)
}
private fun handleIntent(intent: Intent?) {
intent?.data?.let { uri ->
ulink.handleDeepLink(uri)
}
}
private fun observeDeepLinks() {
lifecycleScope.launch {
ulink.dynamicLinkStream.collect { linkData ->
// Handle dynamic link data
handleDeepLinkData(linkData)
}
}
lifecycleScope.launch {
ulink.unifiedLinkStream.collect { linkData ->
// Handle unified link data
handleDeepLinkData(linkData)
}
}
}
private fun handleDeepLinkData(data: ULinkResolvedData) {
// Navigate based on link data
// See Receive Links guide for examples
}
}
With enableDeepLinkIntegration = true (the default), the SDK automatically handles deep links. You only need to listen to the streams. The manual handling above is optional and mainly useful for debugging or special cases.
4. Configure Dashboard Settings
Now that your app is configured, you need to match those settings in the ULink dashboard.
- Open your ULink project in the dashboard
- Navigate to Configuration → General
- Enter your app's Package Name (found in your
build.gradle.ktsfile, or inAndroidManifest.xmlas thepackageattribute) - If you configured a custom URL scheme (step 3.3), enter your URL Scheme (e.g.,
myapp- without the://) - Navigate to Domains section
- If you haven't already, add your domain:
- For shared domains: Click Add Domain → Select Shared Domain (.shared.ly) → Enter your subdomain
- For custom domains: Click Add Domain → Enter your custom domain → Complete DNS verification
- Ensure the domain matches exactly what you used in your intent filter's
android:hostattribute (step 3.2)
- The Package Name in the dashboard must match your app's package name exactly
- The Domain in the dashboard must match the
android:hostvalue in your intent filter - If you added a custom URL scheme, the URL Scheme in the dashboard must match the
android:schemevalue
Your package name is typically found in:
app/build.gradle.ktsasnamespace = "com.yourapp"AndroidManifest.xmlaspackage="com.yourapp"(in the<manifest>tag)
5. Create a verification link
- Links → Create Link
- Choose Unified (store) or Dynamic (deep link parameters).
- Provide:
- Slug (e.g.
android-test) - Android fallback (Play Store link)
- Optional metadata or custom parameters
- Slug (e.g.
- Save and copy the short URL.
6. Test via ADB or device share
-
Install a build that contains the SDK.
-
Start the app once so it initializes ULink.
-
Trigger the link:
adb shell am start \
-a android.intent.action.VIEW \
-d "https://links.shared.ly/android-test" -
Watch Logcat for
ULink/ULinkBridgemessages and ensure your app receives the resolved data. See Receive Links → Android for handling code.
7. Confirm analytics
- In Links, check that click counts increment.
- Click the Analytics button for that specific link to open its analytics page and ensure the platform is
Androidand geo data populates.
If nothing appears, review your intent filter host/scheme and consult Troubleshoot & Test Deep Links.