feat: android webview app + APK build script + CI artifact
Android app (WebView wrapper): - Wraps the public household sharing URL in a native Android app - Swipe-to-refresh, error handling, back navigation, settings dialog - User enters their household's public URL on first launch - Material Design with toolbar, progress indicator Build tooling: - build-apk.sh: one-command APK build (auto-installs Java, SDK, Gradle) - .gitignore updated for Android build artifacts CI (.gitea/workflows/ci.yml): - New 'build-android' job (needs test-and-package) - Installs Android SDK + Java 17, builds debug APK - Uploads APK as 'meal-tracker-apk' artifact
This commit is contained in:
Executable
+171
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ── build-apk.sh ──────────────────────────────────────────────────────────────
|
||||
# Builds the Meal Tracker Android APK from the android/ directory.
|
||||
#
|
||||
# Usage:
|
||||
# ./build-apk.sh # Build debug APK (default)
|
||||
# ./build-apk.sh release # Build release APK (unsigned)
|
||||
#
|
||||
# Prerequisites (auto-installed if missing):
|
||||
# - Java 17+ (OpenJDK)
|
||||
# - Android SDK command-line tools
|
||||
# - Gradle (via wrapper)
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ANDROID_DIR="$SCRIPT_DIR/android"
|
||||
OUTPUT_DIR="$ANDROID_DIR/app/build/outputs/apk"
|
||||
SDK_ROOT="${ANDROID_SDK_ROOT:-$HOME/android-sdk}"
|
||||
CMDLINE_URL="https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip"
|
||||
BUILD_TOOLS_VER="34.0.0"
|
||||
PLATFORM_VER="34"
|
||||
GRADLE_VER="8.7"
|
||||
GRADLE_URL="https://services.gradle.org/distributions/gradle-${GRADLE_VER}-bin.zip"
|
||||
|
||||
BUILD_TYPE="${1:-debug}"
|
||||
|
||||
# ── Colors ──
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
||||
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
err() { echo -e "${RED}[ERR]${NC} $*"; }
|
||||
|
||||
# ── Detect package manager ──
|
||||
if command -v apt-get &>/dev/null; then
|
||||
PM="apt"
|
||||
elif command -v yum &>/dev/null; then
|
||||
PM="yum"
|
||||
elif command -v dnf &>/dev/null; then
|
||||
PM="dnf"
|
||||
else
|
||||
PM=""
|
||||
fi
|
||||
|
||||
# ── Install Java if needed ──
|
||||
install_java() {
|
||||
info "Installing Java 17..."
|
||||
case "$PM" in
|
||||
apt)
|
||||
apt-get update -qq && apt-get install -y -qq openjdk-21-jdk-headless ;;
|
||||
yum)
|
||||
yum install -y java-17-openjdk-headless ;;
|
||||
dnf)
|
||||
dnf install -y java-17-openjdk-headless ;;
|
||||
*)
|
||||
err "Cannot install Java automatically. Please install Java 17+ manually."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
if [ "$PM" != "" ]; then
|
||||
install_java
|
||||
else
|
||||
err "Java is required but not found. Install Java 17+ (OpenJDK)."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
JAVA_VER=$(java -version 2>&1 | head -1 | grep -oP '\d+' | head -1 || echo "0")
|
||||
if [ "$JAVA_VER" -lt 17 ] 2>/dev/null; then
|
||||
warn "Java $JAVA_VER detected. Java 17+ is recommended."
|
||||
fi
|
||||
info "Java: $(java -version 2>&1 | head -1)"
|
||||
|
||||
# ── Install Android SDK if needed ──
|
||||
install_sdk() {
|
||||
info "Installing Android SDK command-line tools to $SDK_ROOT..."
|
||||
mkdir -p "$SDK_ROOT"
|
||||
tmp_zip="/tmp/cmdline-tools.zip"
|
||||
tmp_dir="/tmp/cmdline-tools-tmp"
|
||||
|
||||
if command -v wget &>/dev/null; then
|
||||
wget -q --show-progress "$CMDLINE_URL" -O "$tmp_zip"
|
||||
elif command -v curl &>/dev/null; then
|
||||
curl -L --progress-bar "$CMDLINE_URL" -o "$tmp_zip"
|
||||
else
|
||||
err "Need wget or curl to download Android SDK."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf "$tmp_dir"
|
||||
mkdir -p "$tmp_dir"
|
||||
unzip -qo "$tmp_zip" -d "$tmp_dir"
|
||||
mkdir -p "$SDK_ROOT/cmdline-tools"
|
||||
rm -rf "$SDK_ROOT/cmdline-tools/latest"
|
||||
mv "$tmp_dir/cmdline-tools" "$SDK_ROOT/cmdline-tools/latest"
|
||||
rm -f "$tmp_zip"
|
||||
rm -rf "$tmp_dir"
|
||||
info "Android SDK command-line tools installed."
|
||||
}
|
||||
|
||||
if [ ! -f "$SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" ]; then
|
||||
install_sdk
|
||||
fi
|
||||
|
||||
export ANDROID_SDK_ROOT="$SDK_ROOT"
|
||||
|
||||
# Accept SDK licenses
|
||||
yes | "$SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses > /dev/null 2>&1 || true
|
||||
|
||||
# ── Install required SDK packages ──
|
||||
info "Checking Android SDK packages..."
|
||||
"$SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" \
|
||||
"platform-tools" \
|
||||
"build-tools;${BUILD_TOOLS_VER}" \
|
||||
"platforms;android-${PLATFORM_VER}" \
|
||||
> /dev/null 2>&1 || true
|
||||
|
||||
# Create local.properties
|
||||
cat > "$ANDROID_DIR/local.properties" <<EOF
|
||||
sdk.dir=$SDK_ROOT
|
||||
EOF
|
||||
|
||||
# ── Download Gradle if needed ──
|
||||
GRADLE_DIR="$ANDROID_DIR/.gradle-home"
|
||||
GRADLE_BIN="$GRADLE_DIR/gradle-${GRADLE_VER}/bin/gradle"
|
||||
if [ ! -f "$GRADLE_BIN" ]; then
|
||||
info "Downloading Gradle ${GRADLE_VER}..."
|
||||
gradle_zip="/tmp/gradle-${GRADLE_VER}.zip"
|
||||
if command -v wget &>/dev/null; then
|
||||
wget -q --show-progress "$GRADLE_URL" -O "$gradle_zip"
|
||||
else
|
||||
curl -L --progress-bar "$GRADLE_URL" -o "$gradle_zip"
|
||||
fi
|
||||
rm -rf "$GRADLE_DIR"
|
||||
mkdir -p "$GRADLE_DIR"
|
||||
unzip -qo "$gradle_zip" -d "$GRADLE_DIR"
|
||||
rm -f "$gradle_zip"
|
||||
info "Gradle ${GRADLE_VER} ready."
|
||||
fi
|
||||
|
||||
# Generate wrapper in the android dir so gradlew works
|
||||
if [ ! -f "$ANDROID_DIR/gradlew" ]; then
|
||||
info "Generating Gradle wrapper..."
|
||||
cd "$ANDROID_DIR"
|
||||
"$GRADLE_BIN" wrapper --gradle-version "$GRADLE_VER" --no-daemon 2>&1 | tail -3
|
||||
cd "$SCRIPT_DIR"
|
||||
fi
|
||||
|
||||
# ── Build ──
|
||||
info "Building $BUILD_TYPE APK..."
|
||||
cd "$ANDROID_DIR"
|
||||
./gradlew "assemble${BUILD_TYPE^}" --no-daemon --warning-mode=all
|
||||
|
||||
# ── Report ──
|
||||
APK_FILE=$(find "$OUTPUT_DIR" -name "*.apk" -type f | head -1)
|
||||
if [ -f "$APK_FILE" ]; then
|
||||
APK_SIZE=$(du -h "$APK_FILE" | cut -f1)
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo -e " ${GREEN}✓ BUILD SUCCESSFUL${NC}"
|
||||
echo " APK: $APK_FILE"
|
||||
echo " Size: $APK_SIZE"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
else
|
||||
err "APK not found in $OUTPUT_DIR"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user