How to add licence keys and a kill switch to an Android app
Protect an Android app with licence keys, customer accounts and a remote kill switch in five steps, with one Kotlin file from the SDK generator and a complete demo app on GitHub
Selling an Android app means that sooner or later a key gets shared, or someone keeps using the app after a refund. PWF Auth gives your app licence keys, customer accounts and a kill switch, from the same panel as your desktop programs. This guide follows the video above, step by step
How it works
- One key, one phone: every phone gets its own device id, made from Android's
ANDROID_IDand your app's package. A key locked to one phone won't open on another, and the id stays the same after a reinstall - A check-in every 30 seconds: while your app runs it sends a heartbeat. Ban, pause or expire a key in the panel and the next check-in closes the app and tells the user why
- Encrypted and signed: every request is sealed with your app secret (AES-256 and HMAC-SHA256), so nobody can fake an answer from the server
Step 1: create the application
Sign in to your panel, open Applications and press New application. Give it a name: the app secret is made for you
Step 2: get the Android file
Open the SDK generator, pick your app and the Android tab. It writes one Kotlin file, PWFLicense.kt, with your server address and your app already inside
Step 3: add it to your project
Copy the file into your app module, next to your activities, and add the internet permission to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />It runs on Android 8.0 (API 26) or newer. Nothing to add in Gradle: it uses Android's own HttpURLConnection and org.json
Step 4: sign in and start the heartbeat
Call login off the main thread. When it works, start the heartbeat on its own thread, and close your screens when it says the session ended
val client = PWFLicense(context)
lifecycleScope.launch {
val result = withContext(Dispatchers.IO) { client.login(key) }
if (!result.optBoolean("success")) {
showError(result.optString("message"))
return@launch
}
openApp()
Thread {
client.runHeartbeat { code, message ->
runOnUiThread { closeApp(message) } // BANNED, PAUSED, EXPIRED, NETWORK_LOST…
}
}.start()
}Prefer usernames? client.loginAccount(username, password) signs in with a customer account instead: same session, same kill switch
Step 5: make keys and run it
Back in the panel, open Licences and generate a few keys for your customers. Run the app, type a key and you're in. Sessions shows the phone live, with its device and its location, and banning the key closes the app on its next check-in
The complete project
The demo app from the video is on GitHub: Kotlin and Jetpack Compose, with key and account sign-in, the live session screen and the kill switch. Clone it, put your app secret in local.properties and run it
git clone https://github.com/pwfauth/pwfauth-android
local.propertiesstays out of Git, so your secret never lands in a public repository. It still ends up inside the APK, as in every client: turn on code shrinking (R8) for your release build

