Android Quick Start
Get MovableInk deeplinking working in your Android app in under 5 minutes.
Prerequisites
Before you begin, ensure you have:
- [x] Your MovableInk subdomain (e.g.,
mi.yourcompany.com) - [x] Digital Asset Links file configured by MovableInk at
https://mi.yourcompany.com/.well-known/assetlinks.json - [x] Android 7.0 (API 24) or later as your minimum SDK version
- [x] Android Studio Arctic Fox or later
Need Help?
If you don't have these prerequisites, see the Getting Started guide or contact your Movable Ink client experience team.
Step 1: Install the SDK (1 minute)
Add the MovableInk SDK to your app's build.gradle file:
Then sync your project.
Step 2: Configure App Links (2 minutes)
Update AndroidManifest.xml
Add intent filters to your main activity in AndroidManifest.xml:
<activity
android:name=".MainActivity"
android:exported="true">
<!-- Existing intent filters -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Add these intent filters for MovableInk App Links -->
<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="mi.yourcompany.com"
android:pathPrefix="/p/cpm" />
</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="https"
android:host="mi.yourcompany.com"
android:pathPrefix="/p/rpm" />
</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="https"
android:host="mi.yourcompany.com"
android:pathPrefix="/p/gom" />
</intent-filter>
</activity>
Note
Replace mi.yourcompany.com with your actual MovableInk subdomain.
Step 3: Handle Incoming Links (2 minutes)
In your main Activity (Kotlin):
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.movableink.sdk.MIClient
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Handle intent
handleIntent(intent)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
handleIntent(intent)
}
private fun handleIntent(intent: Intent?) {
val action = intent?.action
val data: Uri? = intent?.data
if (action == Intent.ACTION_VIEW && data != null) {
// This is a deeplink
resolveMovableInkLink(data)
}
}
private fun resolveMovableInkLink(url: Uri) {
MIClient.resolveURL(url.toString()) { result ->
result.onSuccess { resolvedUrl ->
// Navigate to the resolved URL in your app
println("Deeplink resolved to: $resolvedUrl")
// TODO: Navigate to appropriate screen
navigateToContent(resolvedUrl)
}.onFailure { error ->
println("Failed to resolve link: ${error.message}")
}
}
}
private fun navigateToContent(url: String) {
// TODO: Parse the URL and navigate to the appropriate screen
// Example:
// if (url.contains("/products/")) {
// // Navigate to product detail
// } else if (url.contains("/categories/")) {
// // Navigate to category
// }
}
}
Or in Java:
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.movableink.sdk.MIClient;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handleIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
String action = intent.getAction();
Uri data = intent.getData();
if (Intent.ACTION_VIEW.equals(action) && data != null) {
resolveMovableInkLink(data);
}
}
private void resolveMovableInkLink(Uri url) {
MIClient.resolveURL(url.toString(), result -> {
result.onSuccess(resolvedUrl -> {
System.out.println("Deeplink resolved to: " + resolvedUrl);
// TODO: Navigate to appropriate screen
navigateToContent(resolvedUrl);
return null;
}).onFailure(error -> {
System.out.println("Failed to resolve link: " + error.getMessage());
return null;
});
});
}
private void navigateToContent(String url) {
// TODO: Parse the URL and navigate to the appropriate screen
}
}
Step 4: Verify It Works
Build and Run
- Build and run your app on a device or emulator (API 24+)
- Make sure your app is in the background or closed
Test with a Sample Link
Ask your MovableInk team for a test deeplink, or use this format:
What to Look For
- Open the test link in Chrome or another browser on your device/emulator
- Your app should open automatically
- Check Logcat for the resolved URL:
Test with ADB (Alternative)
You can also test using ADB:
adb shell am start -a android.intent.action.VIEW \
-d "https://mi.yourcompany.com/p/rp/test" \
com.yourcompany.yourapp
Replace com.yourcompany.yourapp with your app's package name.
It Works!
If you see the resolved URL in Logcat, congratulations! Your basic deeplinking integration is working.
Troubleshooting
If your app doesn't open:
- Verify your Digital Asset Links file is accessible at
https://mi.yourcompany.com/.well-known/assetlinks.json - Check that your package name and SHA-256 fingerprint match what's in the assetlinks.json file
- Ensure
android:autoVerify="true"is set on at least one intent filter - Verify you're testing on Android 7.0 (API 24) or later
- Check intent filters match the URL pattern exactly
- Try clearing app data and reinstalling
Next Steps
Now that you have basic deeplinking working, you can:
Implement Navigation
Update the navigateToContent() method to actually navigate to the appropriate screen based on the resolved URL:
private fun navigateToContent(url: String) {
val uri = Uri.parse(url)
when {
uri.path?.contains("/products/") == true -> {
// Extract product ID and navigate to product detail
val productId = uri.lastPathSegment
// Navigate to ProductDetailActivity
}
uri.path?.contains("/categories/") == true -> {
// Navigate to category screen
}
else -> {
// Handle other URLs or fallback to home
}
}
}
Add Behavior Events
Capture user interactions to power personalized marketing:
Explore Advanced Features
- Deferred Deeplinking - Handle links for new app installs
- In-App Messages - Display HTML content in your app
- Advanced Features - Custom link handling and more