Skip to main content

Android SDK

The Inhouse Android SDK provides comprehensive tracking and analytics capabilities for your native Android applications, including shortlink tracking, install attribution, and deep linking support.

Installation

Gradle Dependencies

Add the SDK to your app/build.gradle:
dependencies {
    implementation 'co.tryinhouse:android-sdk:1.0.0'
}

Maven

Add the SDK to your pom.xml:
<dependency>
    <groupId>co.tryinhouse</groupId>
    <artifactId>android-sdk</artifactId>
    <version>1.0.0</version>
</dependency>

Manual Installation

Download the AAR file and add it to your project:
  1. Download the latest client-sdk-distribution.zip
  2. Unzip it in your app/libs/ directory
  3. Add the following to your app/build.gradle:
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.aar'])
    implementation 'com.squareup.okhttp3:okhttp:4.12.0'
    implementation 'com.google.code.gson:gson:2.10.1'
    implementation 'com.android.installreferrer:installreferrer:2.2'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
    implementation 'com.github.thumbmarkjs:thumbmark-android:1.0.+'
}

Quick Start

Basic Setup

Initialize the SDK in your application:
import co.tryinhouse.android.TrackingSDK

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // Initialize the SDK
        TrackingSDK.getInstance().initialize(
            context = this,
            projectToken = "YOUR_PROJECT_TOKEN",
            tokenId = "YOUR_TOKEN_ID",
            shortLinkDomain = "yourdomain.com",
            serverUrl = "https://api.tryinhouse.co", // Optional
            enableDebugLogging = false, // Optional
            callback = { callbackType, jsonData ->
                // Handle SDK callbacks
                when (callbackType) {
                    "shortlink_click" -> handleShortlinkClick(jsonData)
                    "app_install_from_shortlink" -> handleAppInstall(jsonData)
                    "session_start_from_shortlink" -> handleSessionStart(jsonData)
                }
            }
        )
    }

    private fun handleShortlinkClick(jsonData: String) {
        // Handle shortlink click response
        Log.d("MyApp", "Shortlink clicked: $jsonData")
    }

    private fun handleAppInstall(jsonData: String) {
        // Handle app install attribution
        Log.d("MyApp", "App installed from shortlink: $jsonData")
    }

    private fun handleSessionStart(jsonData: String) {
        // Handle session start from shortlink
        Log.d("MyApp", "Session started from shortlink: $jsonData")
    }
}

Activity Integration

For proper deep link handling, extend BaseTrackingActivity or manually set the current activity:
import co.tryinhouse.android.BaseTrackingActivity
import co.tryinhouse.android.TrackingSDK

// Option 1: Extend BaseTrackingActivity (recommended)
class MainActivity : BaseTrackingActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // BaseTrackingActivity automatically handles deep links
    }
}

// Option 2: Manual activity tracking
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Set current activity for SDK
        TrackingSDK.getInstance().setCurrentActivity(this)
    }

    override fun onResume() {
        super.onResume()
        TrackingSDK.getInstance().onAppResume()
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        TrackingSDK.getInstance().onNewIntent(intent)
    }
}

Event Tracking

App Open Tracking

Track when users open your app:
import co.tryinhouse.android.TrackingSDK

// Track regular app open
TrackingSDK.getInstance().trackAppOpen { responseJson ->
    Log.d("MyApp", "App open tracked: $responseJson")
}

// Track app open from shortlink (automatically called by SDK)
TrackingSDK.getInstance().trackAppOpenFromShortLink("https://yourdomain.com/abc123") { responseJson ->
    Log.d("MyApp", "App open from shortlink tracked: $responseJson")
}

Session Tracking

Track user sessions:
// Track session start
TrackingSDK.getInstance().trackSessionStart { responseJson ->
    Log.d("MyApp", "Session started: $responseJson")
}

// Track session start from shortlink (automatically called by SDK)
TrackingSDK.getInstance().trackSessionStartFromShortLink("https://yourdomain.com/abc123") { responseJson ->
    Log.d("MyApp", "Session from shortlink started: $responseJson")
}
Track shortlink interactions:
// Track shortlink click
val shortLink = "https://yourdomain.com/abc123"
val deepLink = "yourapp://product?id=123"

TrackingSDK.getInstance().trackShortLinkClick(shortLink, deepLink) { responseJson ->
    Log.d("MyApp", "Shortlink click tracked: $responseJson")
}

Custom Event Tracking

Track custom business events:
// Track custom event without shortlink
TrackingSDK.getInstance().trackCustomEvent(
    eventType = "product_view",
    shortLink = null,
    additionalData = mapOf(
        "product_id" to "123",
        "category" to "electronics",
        "price" to "299.99"
    )
) { responseJson ->
    Log.d("MyApp", "Custom event tracked: $responseJson")
}

// Track custom event with shortlink
TrackingSDK.getInstance().trackCustomEvent(
    eventType = "purchase_completed",
    shortLink = "https://yourdomain.com/promo123",
    additionalData = mapOf(
        "order_id" to "order_456",
        "total" to "599.99",
        "currency" to "USD"
    )
) { responseJson ->
    Log.d("MyApp", "Purchase event tracked: $responseJson")
}

Install Attribution

Install Referrer Tracking

The SDK automatically handles install attribution through Play Store referrers:
// Get stored install referrer
val installReferrer = TrackingSDK.getInstance().getInstallReferrer()
if (installReferrer != null) {
    Log.d("MyApp", "Install referrer: $installReferrer")
}

// Fetch install referrer asynchronously
TrackingSDK.getInstance().fetchInstallReferrer { referrer ->
    if (referrer != null) {
        Log.d("MyApp", "Fetched install referrer: $referrer")
    } else {
        Log.d("MyApp", "No install referrer available")
    }
}
Track app installs attributed to shortlinks:
val shortLink = "https://yourdomain.com/install123"
val referrer = "utm_source=facebook&utm_campaign=summer_sale"

TrackingSDK.getInstance().trackAppInstallFromShortLink(shortLink, referrer) { responseJson ->
    Log.d("MyApp", "Install from shortlink tracked: $responseJson")
}

Deep Linking

Configure app links in your Android manifest:
<!-- Add to android/app/src/main/AndroidManifest.xml -->
<application>
    <!-- Your main activity -->
    <activity android:name=".MainActivity">
        <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="yourdomain.com" />
        </intent-filter>
    </activity>

    <!-- Deep link activity for handling shortlinks -->
    <activity android:name="co.tryinhouse.android.DeepLinkActivity"
              android:exported="true"
              android:theme="@android:style/Theme.NoDisplay">
        <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="yourdomain.com" />
        </intent-filter>
    </activity>
</application>

Custom URL Schemes

Handle custom URL schemes:
<!-- Custom scheme configuration -->
<activity android:name=".MainActivity">
    <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="yourapp" />
    </intent-filter>
</activity>
The SDK automatically handles deep links when using BaseTrackingActivity:
import co.tryinhouse.android.BaseTrackingActivity

class MainActivity : BaseTrackingActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Deep links are automatically handled by BaseTrackingActivity
        // The SDK will track shortlink clicks and extract attribution data
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // BaseTrackingActivity handles new intents automatically

        // You can add custom deep link routing here
        handleCustomDeepLink(intent)
    }

    private fun handleCustomDeepLink(intent: Intent?) {
        val data = intent?.data
        if (data != null) {
            when (data.path) {
                "/product" -> {
                    val productId = data.getQueryParameter("id")
                    navigateToProduct(productId)
                }
                "/category" -> {
                    val categoryId = data.getQueryParameter("id")
                    navigateToCategory(categoryId)
                }
                else -> {
                    navigateToHome()
                }
            }
        }
    }
}

SDK Information

Device and Session Information

Access SDK-generated identifiers:
// Get device ID
val deviceId = TrackingSDK.getInstance().getDeviceId()
Log.d("MyApp", "Device ID: $deviceId")

// Get session ID
val sessionId = TrackingSDK.getInstance().getSessionId()
Log.d("MyApp", "Session ID: $sessionId")

Debug and Testing

For development and testing:
// Reset first install flag for testing
TrackingSDK.getInstance().resetFirstInstall()

// Debug first install state
TrackingSDK.getInstance().debugFirstInstallState()

// Enable debug logging during initialization
TrackingSDK.getInstance().initialize(
    context = this,
    projectToken = "YOUR_PROJECT_TOKEN",
    tokenId = "YOUR_TOKEN_ID",
    shortLinkDomain = "yourdomain.com",
    enableDebugLogging = true // Enable for development
)

Privacy and Compliance

Data Collection

The SDK collects the following data automatically:
  • Device Information: Device ID (generated), user agent, IP address
  • Event Data: Timestamps, event types, shortlink URLs
  • Install Attribution: Install referrer data from Play Store
  • Session Data: Session IDs, app open/close events
Implement user consent before initializing the SDK:
class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // Check user consent before initializing
        if (hasUserConsent()) {
            initializeTrackingSDK()
        } else {
            // Show consent dialog or skip tracking
            showConsentDialog { granted ->
                if (granted) {
                    initializeTrackingSDK()
                }
            }
        }
    }

    private fun hasUserConsent(): Boolean {
        // Check your app's consent mechanism
        return getSharedPreferences("privacy", MODE_PRIVATE)
            .getBoolean("analytics_consent", false)
    }

    private fun initializeTrackingSDK() {
        TrackingSDK.getInstance().initialize(
            context = this,
            projectToken = "YOUR_PROJECT_TOKEN",
            tokenId = "YOUR_TOKEN_ID",
            shortLinkDomain = "yourdomain.com"
        )
    }
}

Advanced Features

Network Configuration

The SDK uses OkHttp for network requests with the following defaults:
  • Timeout: 30 seconds connection timeout
  • Retry: Up to 3 retry attempts
  • HTTPS: All data transmitted over HTTPS

Error Handling

Handle SDK errors in your callback:
TrackingSDK.getInstance().trackCustomEvent(
    eventType = "user_action",
    shortLink = null,
    additionalData = mapOf("action" to "button_click")
) { responseJson ->
    try {
        // Parse response
        val response = JSONObject(responseJson)
        if (response.has("error")) {
            Log.e("MyApp", "SDK Error: ${response.getString("error")}")
        } else {
            Log.d("MyApp", "Event tracked successfully")
        }
    } catch (e: Exception) {
        Log.e("MyApp", "Failed to parse SDK response", e)
    }
}

Integration Examples

E-commerce Integration

class ProductActivity : BaseTrackingActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_product)

        // Track product view
        trackProductView()
    }

    private fun trackProductView() {
        val productId = intent.getStringExtra("product_id") ?: return

        TrackingSDK.getInstance().trackCustomEvent(
            eventType = "product_view",
            shortLink = null,
            additionalData = mapOf(
                "product_id" to productId,
                "category" to "electronics",
                "price" to "299.99",
                "currency" to "USD"
            )
        ) { responseJson ->
            Log.d("ProductActivity", "Product view tracked: $responseJson")
        }
    }

    private fun handleAddToCart() {
        TrackingSDK.getInstance().trackCustomEvent(
            eventType = "add_to_cart",
            shortLink = null,
            additionalData = mapOf(
                "product_id" to "123",
                "quantity" to "1",
                "total_value" to "299.99"
            )
        ) { responseJson ->
            Log.d("ProductActivity", "Add to cart tracked: $responseJson")
        }
    }
}

Marketing Campaign Tracking

class CampaignTracker {

    fun trackCampaignConversion(campaignId: String, shortLink: String?) {
        TrackingSDK.getInstance().trackCustomEvent(
            eventType = "campaign_conversion",
            shortLink = shortLink,
            additionalData = mapOf(
                "campaign_id" to campaignId,
                "conversion_type" to "signup",
                "timestamp" to System.currentTimeMillis().toString()
            )
        ) { responseJson ->
            Log.d("CampaignTracker", "Campaign conversion tracked: $responseJson")
        }
    }

    fun trackReferralEvent(referrerUserId: String) {
        TrackingSDK.getInstance().trackCustomEvent(
            eventType = "referral_signup",
            shortLink = null,
            additionalData = mapOf(
                "referrer_user_id" to referrerUserId,
                "referral_type" to "friend_invite"
            )
        ) { responseJson ->
            Log.d("CampaignTracker", "Referral tracked: $responseJson")
        }
    }
}

Best Practices

Event Naming

  1. Use Descriptive Names: Use clear, descriptive event names like product_view, add_to_cart
  2. Consistent Naming: Use snake_case for event names consistently
  3. Meaningful Categories: Group related events with prefixes (user_action, ecommerce_event)

Data Management

  1. Minimal Data: Only include necessary data in additional properties
  2. Consistent Properties: Use consistent property names across events
  3. Valid Data Types: Ensure property values are strings, numbers, or booleans

Performance Optimization

  1. Async Tracking: All SDK methods are asynchronous by default
  2. Batch Processing: SDK automatically batches events for efficiency
  3. Network Optimization: SDK handles network retries and timeouts

Privacy and Security

  1. User Consent: Always respect user privacy preferences
  2. Data Minimization: Only collect data necessary for your use case
  3. Secure Transmission: SDK uses HTTPS for all data transmission

Troubleshooting

Common Issues

Events Not Sending
  • Verify project token and token ID are correct
  • Check network connectivity
  • Enable debug logging to see detailed logs
  • Verify server URL configuration
Deep Links Not Working
  • Check Android manifest configuration
  • Verify app link domain verification
  • Test deep links using ADB: adb shell am start -W -a android.intent.action.VIEW -d "https://yourdomain.com/test"
Missing Attribution Data
  • Ensure install referrer is properly configured
  • Check Play Store install referrer setup
  • Verify first install detection logic

Debug Commands

// Enable detailed logging
TrackingSDK.getInstance().initialize(
    // ... other params
    enableDebugLogging = true
)

// Check SDK state
Log.d("Debug", "Device ID: ${TrackingSDK.getInstance().getDeviceId()}")
Log.d("Debug", "Session ID: ${TrackingSDK.getInstance().getSessionId()}")
Log.d("Debug", "Install Referrer: ${TrackingSDK.getInstance().getInstallReferrer()}")

// Reset for testing
TrackingSDK.getInstance().resetFirstInstall()
TrackingSDK.getInstance().debugFirstInstallState()

Next Steps

iOS SDK

Integrate with native iOS apps.

API Reference

Use the REST API for advanced integration.

Deep Linking

Set up deep linking for seamless navigation.

Analytics

Understand your analytics data.
Need help with the Android SDK? Check our API documentation or contact [email protected].