feat(waiter): Capacitor 8 Android project, native build mode, signed APK tooling
- capacitor.config.json: appId gr.bonamin.xenia, webDir dist-native, androidScheme http (origin http://localhost - no mixed-content block when calling venue servers over plain HTTP on the LAN) - vite: `--mode native` builds to dist-native with the PWA plugin disabled (no service worker inside the app) - Android: minSdk 24 / target 36; CAMERA permission for QR pairing; cleartext allowed via network_security_config (LAN IPs can't be listed per-domain); allowBackup=false so backups never carry login tokens - Release signing reads ~/.xenia/keystore.properties (override with XENIA_KEYSTORE_PROPS) - the key never enters the repo; versionName 1.0.0 / versionCode 1 with a bump-both rule for sideloaded updates - npm scripts build:native, apk:debug, apk:release (scripts/build-apk.mjs); APKs land in releases/ (gitignored); release APK is also copied to public/downloads/ so venue servers serve it at /downloads/xenia-waiter.apk - waiter nginx: /downloads/ served as application/vnd.android.package-archive, real 404 when missing (never falls through to index.html) - launcher icons + splash generated from the app icon (assets/ is the source) - .gitattributes: gradlew LF, *.bat CRLF Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
// Release signing key lives OUTSIDE the repo (never commit it):
|
||||
// %USERPROFILE%\.xenia\keystore.properties (storeFile, storePassword, keyAlias, keyPassword)
|
||||
// Override the location with the XENIA_KEYSTORE_PROPS env var. Every APK handed to
|
||||
// a venue must be signed with this same key, or phones refuse to install updates.
|
||||
def keystorePropsFile = file(System.getenv('XENIA_KEYSTORE_PROPS') ?: "${System.getProperty('user.home')}/.xenia/keystore.properties")
|
||||
def keystoreProps = new Properties()
|
||||
if (keystorePropsFile.exists()) {
|
||||
keystorePropsFile.withInputStream { keystoreProps.load(it) }
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "gr.bonamin.xenia"
|
||||
compileSdk = rootProject.ext.compileSdkVersion
|
||||
defaultConfig {
|
||||
applicationId "gr.bonamin.xenia"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
// Bump BOTH for every APK handed out: Android only installs an update over
|
||||
// an existing install when versionCode is higher.
|
||||
versionCode 1
|
||||
versionName "1.0.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
// Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
|
||||
ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
release {
|
||||
if (keystoreProps['storeFile']) {
|
||||
storeFile file(keystoreProps['storeFile'])
|
||||
storePassword keystoreProps['storePassword']
|
||||
keyAlias keystoreProps['keyAlias']
|
||||
keyPassword keystoreProps['keyPassword']
|
||||
}
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
if (keystoreProps['storeFile']) {
|
||||
signingConfig signingConfigs.release
|
||||
} else {
|
||||
logger.warn("Xenia: no keystore at ${keystorePropsFile} - release APK will be UNSIGNED")
|
||||
}
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
flatDir{
|
||||
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
|
||||
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
|
||||
implementation project(':capacitor-android')
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
||||
implementation project(':capacitor-cordova-android-plugins')
|
||||
}
|
||||
|
||||
apply from: 'capacitor.build.gradle'
|
||||
|
||||
try {
|
||||
def servicesJSON = file('google-services.json')
|
||||
if (servicesJSON.text) {
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
||||
} catch(Exception e) {
|
||||
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
|
||||
}
|
||||
Reference in New Issue
Block a user