#!/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 (avoid SIGPIPE under -o pipefail) { yes 2>/dev/null || true; } | "$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" </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 cp "$APK_FILE" "$SCRIPT_DIR/meal-tracker.apk" APK_SIZE=$(du -h "$APK_FILE" | cut -f1) echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo -e " ${GREEN}✓ BUILD SUCCESSFUL${NC}" echo " APK: $SCRIPT_DIR/meal-tracker.apk" echo " Size: $APK_SIZE" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" else err "APK not found in $OUTPUT_DIR" exit 1 fi