Building Gneisswork as an Android APK

Gneisswork can be packaged as a standalone Android APK using Buildozer and Python for Android.

How It Works

The APK bundles:

  • Python 3 runtime
  • Flask web server
  • Kivy UI framework
  • All Gneisswork dependencies
  • SQLite database

When launched, the app:

  1. Starts a local Flask server on 127.0.0.1:5000
  2. Opens a WebView displaying the Flask UI
  3. Runs completely offline on the device

Automated Builds (GitHub Actions)

The repository includes a GitHub Action workflow (.github/workflows/build-apk.yml) that automatically builds APKs:

Triggers

  • Push to main/master: Builds a debug APK
  • Pull requests: Builds for testing
  • Version tags (v*): Builds and creates a GitHub release
  • Manual dispatch: Build on-demand from Actions tab

Artifacts

  • Debug APKs are uploaded as workflow artifacts (30-day retention)
  • Release APKs are attached to GitHub releases for tagged versions

Build Time

First build: ~30-45 minutes (downloads Android SDK/NDK) Subsequent builds: ~10-15 minutes (with caching)

Local Build (Linux/macOS)

Prerequisites

# Install system dependencies (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install -y \
  python3-pip build-essential git \
  libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev \
  libportmidi-dev libswscale-dev libavformat-dev libavcodec-dev \
  zlib1g-dev autoconf automake libtool pkg-config cmake \
  openjdk-17-jdk

# Install Buildozer
pip install buildozer cython==0.29.36

Build Commands

# Debug APK (includes debugging symbols, unsigned)
buildozer android debug

# Release APK (optimized, requires signing)
buildozer android release

# Clean build cache (if issues arise)
buildozer android clean

Output APK location: bin/gneisswork-*.apk

Configuration

All build settings are in buildozer.spec:

  • App metadata: Name, version, icon
  • Requirements: Python packages to include
  • Permissions: Android permissions (currently: INTERNET, storage)
  • Architecture: Builds for ARM64 and ARMv7 by default
  • API levels: Targets Android 12 (API 31), minimum Android 5.0 (API 21)

Installation

From GitHub Actions

  1. Go to Actions → Build Android APK workflow
  2. Download the gneisswork-debug-apk artifact
  3. Extract the .apk file
  4. Transfer to Android device
  5. Enable “Install from Unknown Sources” in Android settings
  6. Install the APK

From Release

  1. Go to Releases page
  2. Download the APK from the latest release
  3. Install on device

Troubleshooting

Build Fails with “Command failed”

  • Check system dependencies are installed
  • Try buildozer android clean and rebuild
  • Check buildozer.spec for typos

APK Crashes on Launch

  • Check logs: adb logcat | grep python
  • Verify all requirements are listed in buildozer.spec
  • Check file permissions in source.include_patterns

Large APK Size

  • Expected size: 50-80 MB (includes Python runtime)
  • To reduce: exclude unused packages from requirements
  • Use buildozer android release for optimized builds

Database Issues

  • The SQLite database is created in private app storage
  • Data persists between app restarts
  • To reset: clear app data in Android settings

Development Workflow

  1. Develop and test using python run.py (desktop Flask)
  2. Commit changes to repository
  3. Push to trigger automatic APK build
  4. Download and test APK on device
  5. Tag release (git tag v1.0.0) to create public release

Notes

  • First build downloads ~2GB of Android SDK/NDK components
  • Build cache is stored in .buildozer/ (git-ignored)
  • The main.py file is the Android entry point (uses Kivy + Flask)
  • The regular run.py is still used for desktop development
  • WebView requires Android 5.0+ (API 21)