This repository has been archived! The Android app has been moved to the Kolibri monorepo
Android application for Kolibri Learning Platform using Chaquopy for Python integration.
This project packages Kolibri as an Android application using:
- Chaquopy - Runs Python code directly on Android
- HTTP Server + Service Worker - Python runs an HTTP server, WebView loads content, Service Worker handles caching
- WorkManager - Handles background tasks in a separate process
- Modern Android Architecture - Clean package structure, lifecycle-aware components
# 1. Ensure JDK 21 is installed
java -version
# 2. Setup Python environment (recommended)
uv sync --extra build
uv pip install -r requirements.txt
source .venv/bin/activate
# 3. Setup Android SDK and emulator
make setup
# 4. Download Kolibri tar file
make get-tar tar=https://github.com/learningequality/kolibri/releases/download/v0.17.0/kolibri-0.17.0.tar.gz
# 5. Build!
make kolibri.apk.unsignedOutput: dist/kolibri-*.apk
-
Java Development Kit (JDK) 21
- Fedora/RHEL:
sudo dnf install java-21-openjdk-devel - Ubuntu/Debian:
sudo apt install openjdk-21-jdk - macOS / atomic Fedora (Silverblue, Kinoite):
brew install openjdk@21
- Fedora/RHEL:
-
Python 3.10+ - For build scripts and Chaquopy
-
Clone the repository
git clone https://github.com/learningequality/kolibri-installer-android.git cd kolibri-installer-android -
Set up Python virtual environment
uv venv source .venv/bin/activate uv pip install ".[build]" -r requirements.txt
-
Set up Android SDK (automatically downloads SDK, NDK, emulator)
make setup
-
Get Kolibri tar file
make get-tar tar=<URL_TO_KOLIBRI_TAR>
-
Build the APK
make kolibri.apk.unsigned
The app runs Kolibri as an HTTP server in Python, with a WebView displaying the UI:
┌─────────────────────────────────────────────────────────────┐
│ Main Process │
│ ┌────────────────┐ ┌──────────────────┐ │
│ │ WebViewActivity│ │ KolibriServer │ │
│ │ │ │ Service │ │
│ │ ┌──────────┐ │ │ ┌────────────┐ │ │
│ │ │ WebView │──┼─ HTTP ──┼─▶│ Python │ │ │
│ │ │ │ │ │ │ HTTP │ │ │
│ │ │ Service │ │ │ │ Server │ │ │
│ │ │ Worker │ │ │ │ (Kolibri) │ │ │
│ │ └──────────┘ │ │ └────────────┘ │ │
│ └────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ :task_worker Process │
│ ┌────────────────┐ ┌──────────────────┐ │
│ │ WorkController │────────▶│ WorkManager │ │
│ │ Service │ │ Workers │ │
│ └────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────┘
- KolibriServerService - Starts Python HTTP server in background
- WebViewActivity - Displays Kolibri UI, requests notification permission
- WorkManager - Runs background tasks (imports, syncs) in separate process
- Task Reconciler - Syncs WorkManager state with Kolibri's job database
app/src/main/
├── java/org/learningequality/Kolibri/
│ ├── App.java # Application entry point
│ ├── WebViewActivity.java # Main activity with WebView
│ ├── KolibriServerService.java # HTTP server service
│ ├── KolibriServerViewModel.java # Server state management
│ ├── KolibriEnvironmentManager.java # Environment init coordination
│ ├── KolibriEnvironmentInitializer.java # Environment configuration
│ ├── WorkController.java # Task scheduling
│ ├── WorkControllerService.java # Worker process IPC
│ ├── notification/ # Notification system
│ ├── task/ # Task worker interfaces
│ │ ├── Task.java # WorkManager wrapper
│ │ └── TaskWorkerImpl.java # Observer pattern for progress
│ ├── workers/ # WorkManager workers
│ │ ├── BaseTaskWorker.java # Base class with notifications
│ │ ├── ForegroundWorker.java # Long-running tasks
│ │ └── BackgroundWorker.java # Short tasks
│ └── util/ # Utility classes
└── python/
├── main.py # HTTP server entry point
├── android_utils.py # Android-specific utilities
├── taskworker.py # Task execution
├── task_reconciler.py # Task state reconciliation
├── task_status.py # Task status updates
└── android_app_plugin/ # Kolibri plugin for Android
└── kolibri_plugin.py # StorageHook for task scheduling
make kolibri.apk.unsignedOutput: dist/kolibri-*.apk
export RELEASE_KEYSTORE=/path/to/keystore.jks
export RELEASE_KEYALIAS=key-alias
export RELEASE_KEYSTORE_PASSWD=keystore-password
export RELEASE_KEYALIAS_PASSWD=key-password
make kolibri.apkmake help # Show all available targets
make setup # Setup SDK, NDK, and emulator
make kolibri.apk.unsigned # Build debug APK
make kolibri.apk # Build release APK (requires signing keys)
make kolibri.aab # Build release AAB for Play Store
make install # Install to connected device/emulator
make test # Run unit tests
make lint # Run Android linter
make emulator # Start the emulator
make logcat # View Kolibri-specific logs
make clean # Clean build artifacts# Run unit tests
make test
# Start emulator and install
make emulator
make install
# View logs
make logcat# Kolibri logs
adb logcat -s Kolibri*:V
# Python logs
adb logcat -v brief python:D *:F
# Task worker process
adb logcat --pid=$(adb shell pidof -s org.learningequality.Kolibri:task_worker)
# WebView debugging: Chrome → chrome://inspectBuild fails: Run make setup to ensure SDK is configured correctly
make clean && make setupNo notifications: Grant notification permission in Android settings (required on Android 13+)
Tasks not running: Check WorkManager state
adb logcat -s BaseTaskWorker:V WorkController:VEmulator won't start: Check available AVDs and recreate if needed
make list-avds
make avd # Recreate AVD- Create feature branch
- Make changes
- Run linting:
prek run --all-files - Run tests:
make test - Submit pull request
See LICENSE file.
- Issues: https://github.com/learningequality/kolibri-installer-android/issues
- Kolibri Docs: https://kolibri.readthedocs.io/
- Chaquopy Docs: https://chaquo.com/chaquopy/doc/current/