Classroom digital signage

Author:

Zhenyu Yang <yangzhenyu@sust.edu.cn>

Last updated:

Feb 4, 2026

Overview

The signage/ directory contains an Android “kiosk” app for classroom digital signage. The app runs in landscape mode, hides the system UI, and renders the signage UI using an embedded Android WebView.

At the moment, the UI is provided by a local HTML file packaged into the APK:

  • signage/app/src/main/assets/index.html (loaded via file:///android_asset/index.html)

There is also a more advanced UI mockup for reference/design work:

  • signage/signage_ui_example.html

Repository layout

The signage app is a standalone Gradle project under signage/:

  • signage/app/: Android application module

  • signage/app/src/main/java/com/example/signage/MainActivity.kt: kiosk activity hosting the WebView

  • signage/app/src/main/assets/index.html: the shipped signage page (currently a static prototype)

  • signage/signage_ui_example.html: UI mockup (not used by the app at runtime)

How it works

On startup, MainActivity:

  1. Enables immersive full-screen mode (hides status/navigation bars).

  2. Initializes a WebView with JavaScript and DOM storage enabled.

  3. Loads the packaged HTML UI from Android assets.

Note

  • The app declares android.permission.INTERNET (so the HTML/JS can call remote APIs if needed), but the default configuration loads a local page.

  • The activity is locked to landscape mode via AndroidManifest.xml.

  • onDestroy explicitly destroys the WebView to reduce the risk of memory leaks on low-memory devices.

Backend API

Public endpoints for the kiosk UI:

  • GET /api/v1/signage/classrooms/{id} returns classroom signage fields.

  • GET /api/v1/signage/classrooms/{id}/schedule?start_date=YYYY-MM-DD&end_date=YYYY-MM-DD returns course occurrences for the date range.

The schedule endpoint is currently public (no authentication). Device authentication can be added later.

Signage device fields (stored in a standalone signage table):

  • signage_enabled

  • signage_title

  • signage_subtitle

  • signage_config

Building and running

Prerequisites

  • Android Studio (recommended) or the Android SDK + command-line tools

  • A JDK compatible with your Android Gradle Plugin (AGP) version

This project uses a Gradle Version Catalog (see signage/gradle/libs.versions.toml).

Build (Windows)

From the repo root:

cd signage
.\\gradlew.bat :app:assembleDebug

Build (Linux)

From the repo root:

cd signage
./gradlew :app:assembleDebug

Note

If you get a “Permission denied” error, run chmod +x ./gradlew first.

The debug APK is typically generated under:

signage/app/build/outputs/apk/debug/

Install on a device

If you have adb available:

adb install -r signage\\app\\build\\outputs\\apk\\debug\\app-debug.apk

Customizing the signage UI

The runtime page is the asset signage/app/src/main/assets/index.html. You can:

  • Replace it with your own HTML/CSS/JS (keep the filename the same), or

  • Change the URL loaded in MainActivity to point to an https:// endpoint.

The current index.html is a static prototype (Chinese labels) and includes a “Check-in” button that calls a JavaScript object named CameraBridge if it exists:

if (typeof CameraBridge !== 'undefined') {
  CameraBridge.startCapture();
}

In this repository snapshot, a corresponding Android JavaScript bridge is not yet implemented. If you plan to support check-in or camera capture, you will need to:

  • Provide a Java/Kotlin object annotated with @JavascriptInterface and register it via WebView.addJavascriptInterface(...), and

  • Request and handle runtime camera permission and camera capture.