Skip to main content
The Uplink Android SDK embeds a worker inside your Android app, making the device controllable from server-side code written with the JavaScript SDK. Use it when you want Uplink automation to run inside your own branded app.
Key concepts:
  • Device: A physical Android device or emulator running your app
  • Worker: A worker created by the Uplink SDK inside your app (one app can create multiple workers)
  • Session: An authenticated connection that pairs your worker with a JavaScript SDK client

Requirements

  • Android API 21 (Android 5.0) or later
  • Kotlin 2.1 or later
  • Java 11 or later

Installation

The Android SDK is distributed as a Maven artifact.
A fully public Maven distribution is coming soon. In the meantime, reach out to Uplink for access credentials and use the repository configuration below.
1

Add the Maven repository

In your root settings.gradle.kts (or build.gradle.kts):
dependencyResolutionManagement {
  repositories {
    mavenCentral()
    maven {
      url = uri("https://maven.pkg.github.com/uplink-code/uplink")
      credentials {
        username = System.getenv("GITHUB_ACTOR")
        password = System.getenv("GITHUB_TOKEN")
      }
    }
  }
}
2

Add the dependency

In your app module’s build.gradle.kts:
dependencies {
  implementation("build.uplink:core:0.0.0-alpha10")
}
3

Declare the internet permission

In AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />

Quick example

import android.view.ViewGroup
import androidx.activity.ComponentActivity
import androidx.lifecycle.lifecycleScope
import build.uplink.worker
import kotlinx.coroutines.launch

suspend fun startUplink(activity: ComponentActivity, container: ViewGroup, sessionUrl: String) {
  val worker = worker(activity, container)

  worker.connect(sessionUrl)

  activity.lifecycleScope.launch {
    worker.accept()
  }
}

Initialization

worker(context, group)

Creates a new Worker and mounts the SDK’s WebView into the provided ViewGroup.
fun worker(context: Context, group: ViewGroup): Worker
Parameters:
  • context: An Android Context — typically your Activity
  • group: The ViewGroup that will host the SDK’s web view
Returns: A new Worker ready to connect to a session
val worker = worker(activity, container)
The ViewGroup you pass in must remain in the view hierarchy for the lifetime of the worker. Tearing down the containing Activity or Fragment will close the worker.

Obtaining a session

Your backend creates a session using the JavaScript SDK’s uplink.session() and delivers the resulting session URL to the app. How you deliver it — a backend API response, an app link, a QR code — is up to you.
val sessionUrl: String = // from your backend, deep link, or QR code
See Sessions for how sessions are created on the server side.

Connecting and accepting

worker.connect(session)

Connects the worker to an Uplink session.
suspend fun connect(session: String)
Parameters:
  • session: The session URL provided by your backend
worker.connect(sessionUrl)

worker.accept()

Begins accepting commands from the JavaScript SDK client. accept() suspends until the worker closes, so launch it in a coroutine scope that matches your app’s lifecycle.
suspend fun accept()
lifecycleScope.launch {
  worker.accept()
}

Cleanup

worker.close()

Closes the worker and releases its resources.
suspend fun close()
worker.close()
Closing a worker ends its session. Any browsers the JavaScript SDK has launched on the worker will be terminated.

Complete example

A minimal Activity that starts an Uplink worker and tears it down on destroy:
import android.os.Bundle
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.activity.ComponentActivity
import androidx.lifecycle.lifecycleScope
import build.uplink.worker
import build.uplink.worker.Worker
import kotlinx.coroutines.launch

class UplinkActivity : ComponentActivity() {
  private var worker: Worker? = null

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val container = FrameLayout(this)
    setContentView(container, ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT))

    val sessionUrl = intent.getStringExtra("sessionUrl") ?: return
    val worker = worker(this, container).also { this.worker = it }

    lifecycleScope.launch {
      try {
        worker.connect(sessionUrl)
        worker.accept()
      } catch (e: Exception) {
        println("Uplink worker ended: $e")
      }
    }
  }

  override fun onDestroy() {
    super.onDestroy()
    lifecycleScope.launch {
      worker?.close()
    }
  }

  companion object {
    private const val MATCH_PARENT = ViewGroup.LayoutParams.MATCH_PARENT
  }
}

iOS SDK

Integrate Uplink into your iOS app

JavaScript SDK

Control your worker from server-side code

Sessions

How sessions are created and secured

Core concepts

Architecture overview