Skip to main content

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 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

Ensure Maven Central is in your repositories:

settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}

Add the ULink SDK dependency to your app module:

app/build.gradle.kts
dependencies {
implementation("ly.ulink:ulink-sdk:1.0.8")
}

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:

  1. Open app/src/main/AndroidManifest.xml in your project
  2. 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" />
Permission Location

These permissions go at the top level of your manifest, not inside the <application> tag.

Android App Links are the recommended approach because they work seamlessly and don't show a disambiguation dialog.

  1. Open app/src/main/AndroidManifest.xml
  2. Find your main activity (usually MainActivity)
  3. 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>
Host Configuration
  • Replace links.shared.ly with 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
Launch Mode

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>
Custom Scheme Best Practices
  • 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.

  1. Create a new file: app/src/main/java/com/yourapp/MyApp.kt (or .java) — replace com.yourapp with your package name
  2. 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 Application Class

  1. 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>
Application Class Registration

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.

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
}
}
Automatic Integration

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. These settings are required for ULink to generate the Digital Asset Links (assetlinks.json) file that enables Android App Links.

Package Name

Your Package Name uniquely identifies your app on Android and must match exactly between your app and the ULink dashboard.

  1. Find your package name in one of these locations:
    • app/build.gradle.kts as namespace = "com.yourapp"
    • AndroidManifest.xml as package="com.yourapp" (in the <manifest> tag)
  2. In the ULink dashboard, go to Configuration → General → Android
  3. Enter your Package Name in the Package Name field

SHA-256 Certificate Fingerprints

SHA-256 fingerprints are required for Android App Links verification. ULink uses them to generate the Digital Asset Links file that Android uses to verify your app owns the domain.

Get Your Fingerprint

The easiest way is to run this command in your project root:

./gradlew signingReport

Look for the SHA-256 line under your signing configuration. It looks like:

SHA-256: AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99

Alternatively, use keytool directly:

# Debug keystore (for development)
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android | grep SHA-256

# Release keystore (for production)
keytool -list -v -keystore your-release-key.keystore -alias your-alias | grep SHA-256

Add Fingerprints to Dashboard

  1. In the ULink dashboard, go to Configuration → General → Android
  2. Click Add Fingerprint in the SHA-256 Fingerprints section
  3. Paste your SHA-256 fingerprint (with or without colons — ULink normalizes the format automatically)
  4. Click Add to save the fingerprint
  5. Repeat for additional fingerprints if needed
Add All Signing Keys

You should add fingerprints for all signing keys you use:

  • Debug keystore — For development and testing on emulators/devices
  • Release keystore — For production builds you distribute directly
  • Play App Signing — If you use Google Play App Signing, add the App signing key certificate fingerprint from the Play Console (Setup → App signing)

Without the correct fingerprints, App Links won't work and users will see a disambiguation dialog instead of your app opening directly.

URL Scheme (Optional)

If you configured a custom URL scheme (step 3.3), add it to the dashboard:

  1. In the ULink dashboard, go to Configuration → General → Android
  2. Enter your URL Scheme (e.g., myapp — not myapp://)

Domain Configuration

  1. Navigate to the Domains section in your project
  2. 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
  3. Ensure the domain matches exactly what you used in your intent filter's android:host attribute (step 3.2)
Matching Configuration
  • The Package Name in the dashboard must match your app's package name exactly
  • The SHA-256 Fingerprints must match your app's signing certificates
  • The Domain in the dashboard must match the android:host value in your intent filter
  • If you added a custom URL scheme, the URL Scheme in the dashboard must match the android:scheme value

If any of these don't match, App Links won't work and Android will show a disambiguation dialog instead of opening your app directly.

  1. Links → Create Link
  2. Choose Unified (store) or Dynamic (deep link parameters).
  3. Provide:
    • Slug (e.g. android-test)
    • Android fallback (Play Store link)
    • Optional metadata or custom parameters
  4. Save and copy the short URL.

6. Test via ADB or device share

  1. Install a build that contains the SDK.

  2. Start the app once so it initializes ULink.

  3. Trigger the link:

    adb shell am start \
    -a android.intent.action.VIEW \
    -d "https://links.shared.ly/android-test"
  4. Watch Logcat for ULink / ULinkBridge messages and ensure your app receives the resolved data. See Receive Links → Android for handling code.

The ULink CLI provides comprehensive verification of your deep link configuration, checking everything from your manifest to the Asset Links file on your domain.

Install the CLI

curl -fsSL https://ulink.ly/install.sh | bash

Run Verification

# Step 1: Authenticate
ulink login

# Step 2: Link your project directory
cd /path/to/your/android-app
ulink project set

# Step 3: Run verification
ulink verify -v

What the CLI Verifies

The CLI performs a comprehensive check of your Android deep link setup:

CheckDescription
SDK dependencyVerifies ly.ulink:ulink-sdk is in your build.gradle
AndroidManifest.xmlValidates intent filters and android:autoVerify="true"
Asset Links fileFetches and validates /.well-known/assetlinks.json from your domain
Package nameConfirms package name matches between app and dashboard
SHA256 fingerprintVerifies signing key fingerprints are configured correctly
App Links statusChecks Android 12+ App Links verification state

Fixing Issues

The verification report highlights exactly what's misconfigured. Common issues include:

  • Missing or incorrect intent filters — Update your AndroidManifest.xml
  • SHA256 fingerprint mismatches — Add the correct fingerprints in the ULink dashboard
  • Asset Links file problems — Check domain configuration in the dashboard
  • Domain verification failures — Ensure the domain matches between manifest and dashboard
Continuous Verification

Run ulink verify after any changes to your manifest, signing configuration, or dashboard settings to catch issues early.

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 Android and geo data populates.

If nothing appears, review your intent filter host/scheme and consult Troubleshoot & Test Deep Links.