Aesthetic Computer - Android App#
Native Android wrapper for aesthetic.computer.
Build Flavors#
This project has two build flavors:
| Flavor | App ID | Purpose |
|---|---|---|
| consumer | computer.aesthetic |
Play Store distribution |
| kiosk | computer.aesthetic.kiosk |
Dedicated device installations |
Consumer Flavor#
Simple WebView app that loads https://aesthetic.computer. For Google Play Store distribution.
Features:
- Clean WebView wrapper
- Camera/microphone permissions for pieces that need them
- Deep linking for
aesthetic.computer/*URLs - Splash screen with purple branding
Kiosk Flavor#
Device owner mode app for dedicated installations (art exhibits, kiosks, etc).
Features:
- Local HTTPS server with self-signed SSL
- Device admin/owner mode for lock task
- Boot receiver for auto-start
- Blocks back/home buttons
- Hides system UI
Building#
GitHub Actions (Recommended)#
The easiest way to build is via GitHub Actions:
- Automatic builds: Push changes to
android/onmainbranch - Manual builds: Go to Actions → "Android Build" → Run workflow
- Choose
debugorrelease - Choose
consumer,kiosk, orall
- Choose
- Download APKs: From the workflow run artifacts
APKs are available as downloadable artifacts for 30 days (debug) or 90 days (release).
Local Build Prerequisites#
- Java 17+ (
brew install openjdk@17on Mac) - Android SDK (via Android Studio or standalone)
- Set
ANDROID_HOMEenvironment variable - Note: Building in the devcontainer won't work (ARM64 can't run x86_64 Android SDK tools)
Build Commands#
cd android
# Consumer (Play Store)
./gradlew assembleConsumerDebug # Debug APK
./gradlew assembleConsumerRelease # Release APK (needs signing)
# Kiosk (Device installations)
./gradlew assembleKioskDebug
./gradlew assembleKioskRelease
# Build both
./gradlew assembleDebug
./gradlew assembleRelease
Output Locations#
app/build/outputs/apk/consumer/debug/app-consumer-debug.apk
app/build/outputs/apk/consumer/release/app-consumer-release.apk
app/build/outputs/apk/kiosk/debug/app-kiosk-debug.apk
app/build/outputs/apk/kiosk/release/app-kiosk-release.apk
Testing on Device#
Via USB (Mac → Android device)#
-
Enable Developer Mode on Android device:
- Settings → About Phone → Tap "Build Number" 7 times
-
Enable USB Debugging:
- Settings → Developer Options → USB Debugging → On
-
Connect device and accept the debugging prompt
-
Install APK:
# Install consumer debug build
adb install app/build/outputs/apk/consumer/debug/app-consumer-debug.apk
# Or force reinstall
adb install -r app/build/outputs/apk/consumer/debug/app-consumer-debug.apk
Via Wireless ADB (from devcontainer)#
If your Mac host and Android device are on the same network:
- On device: Settings → Developer Options → Wireless Debugging → Enable
- Get pairing code from device
- From Mac terminal:
adb pair <device-ip>:<pairing-port> # Enter pairing code
adb connect <device-ip>:<debug-port>
adb install path/to/app.apk
Project Structure#
android/
├── app/
│ ├── build.gradle.kts # Build config with product flavors
│ └── src/
│ ├── main/ # Shared code (theme, resources)
│ │ ├── AndroidManifest.xml
│ │ ├── java/computer/aesthetic/ui/theme/
│ │ └── res/ # Icons, colors, strings
│ │
│ ├── consumer/ # Play Store version
│ │ ├── AndroidManifest.xml
│ │ └── java/computer/aesthetic/
│ │ └── MainActivity.kt
│ │
│ └── kiosk/ # Device installation version
│ ├── AndroidManifest.xml
│ ├── java/computer/aesthetic/
│ │ ├── MainActivity.kt
│ │ ├── LocalHttpServer.kt
│ │ ├── BootReceiver.kt
│ │ └── MyDeviceAdminReceiver.kt
│ └── res/
│ ├── raw/keystore.bks
│ └── xml/device_admin.xml
│
├── gradle/ # Gradle wrapper & version catalog
└── build.gradle.kts # Root build config
Play Store Release#
1. Generate Upload Keystore#
keytool -genkey -v -keystore aesthetic-upload.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
2. Configure Signing#
Add to app/build.gradle.kts:
signingConfigs {
create("release") {
storeFile = file("../aesthetic-upload.jks")
storePassword = System.getenv("KEYSTORE_PASSWORD")
keyAlias = "upload"
keyPassword = System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
// ...
}
}
3. Build Release Bundle#
./gradlew bundleConsumerRelease
# Output: app/build/outputs/bundle/consumerRelease/app-consumer-release.aab
4. Upload to Play Console#
- Create app in Google Play Console
- Upload
.aabfile to Internal Testing track - Fill out store listing, content rating, privacy policy
- Promote to Production when ready
Kiosk Setup (Device Owner Mode)#
For dedicated devices that boot directly into the app:
1. Factory Reset Device#
Start with a fresh device.
2. Set Device Owner via ADB#
adb shell dpm set-device-owner computer.aesthetic.kiosk/.MyDeviceAdminReceiver
3. Install Kiosk APK#
adb install app-kiosk-release.apk
The device will now boot directly into Aesthetic Computer.
Dependencies#
- Kotlin 2.0.21
- Jetpack Compose (BOM 2024.12.01)
- AndroidX Core KTX 1.15.0
- AndroidX Splashscreen 1.0.1
- NanoHTTPD 2.3.1 (kiosk only)
Version History#
- 1.1.0 - Build flavor support (consumer vs kiosk)
- 1.0.0 - Initial kiosk-only release