Add the Android app: a WebView around public_html
A single Activity holding one WebView, in Java rather than Kotlin — for ~120 lines of setup Kotlin would only add its Gradle plugin, its stdlib in the APK and a third version to keep aligned with Gradle and AGP. One dependency: androidx.webkit 1.16.0. The assets are served from https://appassets.androidplatform.net through WebViewAssetLoader rather than file://. That is the part that matters: an https origin is a secure context, and localStorage — which holds every setting and the match in progress — is blocked on file://, so a saved game would silently vanish. Confirmed on device: force-quit mid-match and everything comes back. public_html stays the only copy of the web app. A task syncs it into the assets at build time, so the browser version and the app version cannot drift; the APK's index.html hashes identical to the working tree. sw.js is left out on purpose — it is cache-first, and a service-worker cache outlives an app upgrade, so it would serve a stale index.html with no way to clear it. The APK is the cache now. Three web APIs don't exist in a WebView, so the Activity supplies them: FLAG_KEEP_SCREEN_ON for navigator.wakeLock, native immersive mode for requestFullscreen(), and LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES so the panels' env(safe-area-inset-*) has something to report. textZoom is pinned to 100: the layout is built on clamp() and vw, and a large system font would scale the text inside it. The manifest declares no permissions whatsoever. Wiring note: AGP 9 refuses a Provider in sourceSets.assets.srcDir, since it can't tell generated from static directories. The sync is a task with a DirectoryProperty output, attached via androidComponents.onVariants, which is the supported path and carries the task dependency. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import javax.inject.Inject
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "nl.hansdezwart.bgclock"
|
||||
compileSdk = 36
|
||||
buildToolsVersion = "36.0.0"
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "nl.hansdezwart.bgclock"
|
||||
minSdk = 26
|
||||
targetSdk = 36
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The web app is not copied into the repo — it is read out of public_html at
|
||||
* build time, so the browser version and the app version cannot drift.
|
||||
*
|
||||
* sw.js is left behind on purpose: it is cache-first, and a service-worker cache
|
||||
* outlives an app upgrade, so it would go on serving the old index.html with no
|
||||
* way to clear it. Without the file the registration fails into its own .catch,
|
||||
* and the APK is the cache instead.
|
||||
*/
|
||||
abstract class SyncWebAssets : DefaultTask() {
|
||||
@get:InputDirectory
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
abstract val source: DirectoryProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val outputDir: DirectoryProperty
|
||||
|
||||
@get:Inject
|
||||
abstract val fs: FileSystemOperations
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
fs.sync {
|
||||
from(source) { exclude("sw.js") }
|
||||
into(outputDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val webAssets = tasks.register<SyncWebAssets>("syncWebAssets") {
|
||||
source.fileValue(rootProject.file("../public_html"))
|
||||
}
|
||||
|
||||
// the Variant API, not sourceSets.assets.srcDir: AGP 9 refuses a Provider there
|
||||
// because it can't tell generated from static, and this way the task dependency
|
||||
// is carried automatically
|
||||
androidComponents {
|
||||
onVariants { variant ->
|
||||
variant.sources.assets?.addGeneratedSourceDirectory(webAssets, SyncWebAssets::outputDir)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// the only dependency: WebViewAssetLoader, which serves the assets over a
|
||||
// real https origin so they count as a secure context
|
||||
implementation("androidx.webkit:webkit:1.16.0")
|
||||
}
|
||||
Reference in New Issue
Block a user