Simple offline activation / licensing method for App Inventor apps (device-based, no internet)

I asked ChatGPT for you
ChatGPT was a bit haluzinating again... there is no such extension TaifunDeviceTools or TaifunCryptography available... but there are other extensions available, just search the extensions directory App Inventor Extensions | Pura Vida Apps

Taifun


Excellent — this is a classic “offline activation” flow, and it can be implemented cleanly in App Inventor (or any derivative such as Kodular, Niotron, etc.) even with targetSdkVersion 35, though you’ll need to design around Android’s new privacy limits.

Let’s break it down in a developer-oriented way:


:gear: Step 1. Choose your “device ID”

Because of Android’s restrictions, you cannot reliably read the hardware serial (Build.SERIAL) or IMEI anymore (it returns unknown on modern Android versions).
For offline activation, use one of the following:

  • :white_check_mark: Android ID (Settings.Secure.ANDROID_ID) — available without permissions; stable per device/user.
  • Or create your own persistent random UUID stored in TinyDB on first run.

:backhand_index_pointing_right: For simplicity:
Use the Device Tools extension (e.g. TaifunDeviceTools) → AndroidId block.


:gear: Step 2. Show it to the user

The activation screen has:

  • Label showing “Your Device ID”
  • Button “Copy ID” or “Send to Developer”
  • TextBox for entering activation code
  • “Activate” button

When pressed:

LabelDeviceID.Text ← DeviceTools.AndroidId

:gear: Step 3. Generate the activation code (developer side)

You want a reproducible function that:

  1. Takes the DeviceID as input
  2. Generates a short activation code (that can be validated offline inside the app)

You can do this via a simple hash-based scheme:

:1234: Option A: Hash + Secret key

Use a small program (in Python, Java, etc.) with a private secret key known only to you:

import hashlib

def make_activation(device_id):
    secret = "MyPrivateSecretKey2025"
    data = (device_id + secret).encode()
    code = hashlib.sha256(data).hexdigest().upper()
    # Shorten for convenience:
    return code[:10]  # e.g., first 10 chars

So if a user sends ANDROID_ID = a1b2c3d4e5f6g7h8,
you generate and send back DF83A72C5E.


:gear: Step 4. Validate in the App

Inside App Inventor, you replicate the same logic (using the same secret key),
then compare the computed code with what the user entered.

App Inventor has a SHA256 block in the Cryptography extension
(e.g. TaifunCryptography):

expected ← SHA256(DeviceID + "MyPrivateSecretKey2025")
expected ← UPPERCASE expected
expected ← segment text expected from 1 to 10

Then:

if enteredCode = expected
   then set TinyDB tag "Activated" to true
        open main screen
else
   show message "Invalid code"

:gear: Step 5. Remember activation

On app start:

if TinyDB.GetValue("Activated") = true
   then open main screen
else
   open ActivationScreen

That’s all.


:white_check_mark: Summary of the activation logic

Step User Side (App) Developer Side
1 Show AndroidId Receives it
2 — Run SHA256(AndroidId + secret)
3 User enters activation code App repeats same formula
4 If match → save flag —

:light_bulb: Security Notes

  • Keep your secret key private — if someone extracts the .aia they could read it.
    To make reverse-engineering harder, obfuscate it (e.g. split into parts, encode).
  • Android ID may reset after factory reset or on new user profile, so user may need reactivation in that case.
1 Like