phase 0: add Android build/test scripts and fix lint menu attrs -
This commit is contained in:
@@ -124,6 +124,43 @@ Release bundle (for Play):
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🔧 Local Build/Test Scripts
|
||||
|
||||
Validate host environment:
|
||||
|
||||
./scripts/check-android-env.sh all
|
||||
|
||||
Install SDK components (requires sdkmanager):
|
||||
|
||||
./scripts/bootstrap-android.sh
|
||||
|
||||
Build + lint + unit tests:
|
||||
|
||||
./scripts/build-debug.sh
|
||||
|
||||
Connected/device tests:
|
||||
|
||||
./scripts/test-connected.sh
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
# 📦 Play Store Ready
|
||||
|
||||
Release build includes:
|
||||
|
||||
- Resource shrinking
|
||||
- Code minification
|
||||
- Material 3 theming
|
||||
- Clean package namespace
|
||||
|
||||
Before Play upload:
|
||||
|
||||
- Configure signing keystore
|
||||
- Increment versionCode
|
||||
- Generate .aab
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
# 🏠 Home Assistant Integration
|
||||
|
||||
RelayTV integrates directly with Home Assistant via:
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_servers"
|
||||
android:title="@string/servers"
|
||||
android:icon="@android:drawable/ic_menu_manage"
|
||||
android:showAsAction="ifRoom" />
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_reload"
|
||||
android:title="Reload"
|
||||
android:title="@string/reload"
|
||||
android:icon="@android:drawable/ic_popup_sync"
|
||||
android:showAsAction="ifRoom" />
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
||||
|
||||
@@ -8,4 +8,5 @@
|
||||
<string name="select_server">Select RelayTV server</string>
|
||||
<string name="server_name">Name</string>
|
||||
<string name="server_url">Base URL</string>
|
||||
<string name="reload">Reload</string>
|
||||
</resources>
|
||||
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
|
||||
INSTALL_EMULATOR="${INSTALL_EMULATOR:-0}"
|
||||
ANDROID_PLATFORM="${ANDROID_PLATFORM:-android-34}"
|
||||
ANDROID_BUILD_TOOLS="${ANDROID_BUILD_TOOLS:-34.0.0}"
|
||||
ANDROID_SYSTEM_IMAGE="${ANDROID_SYSTEM_IMAGE:-system-images;android-34;google_apis;x86_64}"
|
||||
|
||||
say() { printf '%s\n' "$*"; }
|
||||
|
||||
find_sdkmanager() {
|
||||
if command -v sdkmanager >/dev/null 2>&1; then
|
||||
command -v sdkmanager
|
||||
return 0
|
||||
fi
|
||||
|
||||
local sdk="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-}}"
|
||||
if [[ -n "${sdk}" ]]; then
|
||||
local candidate="${sdk}/cmdline-tools/latest/bin/sdkmanager"
|
||||
if [[ -x "${candidate}" ]]; then
|
||||
printf '%s\n' "${candidate}"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
ensure_sdk_root() {
|
||||
if [[ -n "${ANDROID_SDK_ROOT:-}" ]]; then
|
||||
mkdir -p "${ANDROID_SDK_ROOT}"
|
||||
return
|
||||
fi
|
||||
if [[ -n "${ANDROID_HOME:-}" ]]; then
|
||||
export ANDROID_SDK_ROOT="${ANDROID_HOME}"
|
||||
mkdir -p "${ANDROID_SDK_ROOT}"
|
||||
return
|
||||
fi
|
||||
export ANDROID_SDK_ROOT="${HOME}/Android/Sdk"
|
||||
mkdir -p "${ANDROID_SDK_ROOT}"
|
||||
}
|
||||
|
||||
ensure_gradlew_executable() {
|
||||
if [[ ! -x "${REPO_ROOT}/gradlew" ]]; then
|
||||
chmod +x "${REPO_ROOT}/gradlew"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_sdk_root
|
||||
ensure_gradlew_executable
|
||||
|
||||
SDKMANAGER_BIN="$(find_sdkmanager || true)"
|
||||
if [[ -z "${SDKMANAGER_BIN}" ]]; then
|
||||
say "sdkmanager not found."
|
||||
say "Install Android cmdline-tools and add sdkmanager to PATH, then rerun."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PACKAGES=(
|
||||
"platform-tools"
|
||||
"platforms;${ANDROID_PLATFORM}"
|
||||
"build-tools;${ANDROID_BUILD_TOOLS}"
|
||||
"cmdline-tools;latest"
|
||||
)
|
||||
|
||||
if [[ "${INSTALL_EMULATOR}" == "1" ]]; then
|
||||
PACKAGES+=("emulator" "${ANDROID_SYSTEM_IMAGE}")
|
||||
fi
|
||||
|
||||
say "Using Android SDK root: ${ANDROID_SDK_ROOT}"
|
||||
say "Installing packages:"
|
||||
printf ' - %s\n' "${PACKAGES[@]}"
|
||||
|
||||
"${SDKMANAGER_BIN}" --sdk_root="${ANDROID_SDK_ROOT}" "${PACKAGES[@]}"
|
||||
"${SDKMANAGER_BIN}" --sdk_root="${ANDROID_SDK_ROOT}" --licenses < <(yes)
|
||||
|
||||
say
|
||||
say "Bootstrap complete."
|
||||
say "Tip: run ./scripts/check-android-env.sh all"
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
|
||||
cd "${REPO_ROOT}"
|
||||
|
||||
if [[ ! -x "./scripts/check-android-env.sh" ]]; then
|
||||
chmod +x "./scripts/check-android-env.sh"
|
||||
fi
|
||||
./scripts/check-android-env.sh build
|
||||
|
||||
if [[ ! -x "./gradlew" ]]; then
|
||||
chmod +x ./gradlew
|
||||
fi
|
||||
|
||||
if [[ "$#" -gt 0 ]]; then
|
||||
TASKS=("$@")
|
||||
else
|
||||
TASKS=("clean" "assembleDebug" "lint" "testDebugUnitTest")
|
||||
fi
|
||||
|
||||
echo "Running Gradle tasks: ${TASKS[*]}"
|
||||
./gradlew --no-daemon "${TASKS[@]}"
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
MODE="${1:-all}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
|
||||
failures=0
|
||||
warnings=0
|
||||
|
||||
say() { printf '%s\n' "$*"; }
|
||||
ok() { say "[ok] $*"; }
|
||||
warn() { say "[warn] $*"; warnings=$((warnings + 1)); }
|
||||
fail() { say "[fail] $*"; failures=$((failures + 1)); }
|
||||
|
||||
need_cmd() {
|
||||
local name="$1"
|
||||
if command -v "${name}" >/dev/null 2>&1; then
|
||||
ok "Found command: ${name}"
|
||||
else
|
||||
fail "Missing command: ${name}"
|
||||
fi
|
||||
}
|
||||
|
||||
sdk_dir_from_local_properties() {
|
||||
local lp="${REPO_ROOT}/local.properties"
|
||||
[[ -f "${lp}" ]] || return 1
|
||||
local raw
|
||||
raw="$(grep -E '^sdk\.dir=' "${lp}" | tail -n1 | cut -d'=' -f2- || true)"
|
||||
[[ -n "${raw}" ]] || return 1
|
||||
|
||||
# Gradle escaping uses backslashes. This normalizes common Linux/macOS forms.
|
||||
local unescaped="${raw//\\:/:}"
|
||||
unescaped="${unescaped//\\\\/\\}"
|
||||
printf '%s\n' "${unescaped}"
|
||||
return 0
|
||||
}
|
||||
|
||||
detect_sdk_root() {
|
||||
if [[ -n "${ANDROID_SDK_ROOT:-}" ]]; then
|
||||
printf '%s\n' "${ANDROID_SDK_ROOT}"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${ANDROID_HOME:-}" ]]; then
|
||||
printf '%s\n' "${ANDROID_HOME}"
|
||||
return 0
|
||||
fi
|
||||
if sdk_dir_from_local_properties >/dev/null 2>&1; then
|
||||
sdk_dir_from_local_properties
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
validate_mode() {
|
||||
case "${MODE}" in
|
||||
build|connected|all) ;;
|
||||
*)
|
||||
say "Usage: $0 [build|connected|all]"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_base_tools() {
|
||||
need_cmd java
|
||||
need_cmd javac
|
||||
}
|
||||
|
||||
check_connected_tools() {
|
||||
need_cmd adb
|
||||
}
|
||||
|
||||
check_sdk() {
|
||||
local sdk_root=""
|
||||
if sdk_root="$(detect_sdk_root)"; then
|
||||
if [[ -d "${sdk_root}" ]]; then
|
||||
ok "Android SDK root: ${sdk_root}"
|
||||
else
|
||||
fail "Android SDK path does not exist: ${sdk_root}"
|
||||
fi
|
||||
else
|
||||
fail "Android SDK root not found. Set ANDROID_SDK_ROOT (or ANDROID_HOME)."
|
||||
fi
|
||||
|
||||
if command -v sdkmanager >/dev/null 2>&1; then
|
||||
ok "Found command: sdkmanager"
|
||||
else
|
||||
warn "sdkmanager not in PATH. bootstrap script can still work if cmdline-tools path is set manually."
|
||||
fi
|
||||
}
|
||||
|
||||
check_gradle_wrapper() {
|
||||
if [[ -f "${REPO_ROOT}/gradlew" ]]; then
|
||||
ok "Found gradle wrapper"
|
||||
else
|
||||
fail "Missing gradlew in repo root"
|
||||
fi
|
||||
}
|
||||
|
||||
validate_mode
|
||||
|
||||
say "Checking Android environment (${MODE}) for ${REPO_ROOT}"
|
||||
check_base_tools
|
||||
check_gradle_wrapper
|
||||
check_sdk
|
||||
|
||||
if [[ "${MODE}" == "connected" || "${MODE}" == "all" ]]; then
|
||||
check_connected_tools
|
||||
fi
|
||||
|
||||
if [[ "${failures}" -gt 0 ]]; then
|
||||
say
|
||||
fail "Environment check failed with ${failures} issue(s) and ${warnings} warning(s)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
say
|
||||
ok "Environment check passed with ${warnings} warning(s)."
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
|
||||
cd "${REPO_ROOT}"
|
||||
|
||||
if [[ ! -x "./scripts/check-android-env.sh" ]]; then
|
||||
chmod +x "./scripts/check-android-env.sh"
|
||||
fi
|
||||
./scripts/check-android-env.sh connected
|
||||
|
||||
if [[ ! -x "./gradlew" ]]; then
|
||||
chmod +x ./gradlew
|
||||
fi
|
||||
|
||||
adb start-server >/dev/null
|
||||
DEVICES="$(adb devices | awk 'NR>1 && $2=="device" {print $1}')"
|
||||
if [[ -z "${DEVICES}" ]]; then
|
||||
echo "No connected Android device/emulator detected."
|
||||
echo "Connect a device (adb devices) or start an emulator, then rerun."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Connected devices:"
|
||||
printf ' - %s\n' ${DEVICES}
|
||||
|
||||
if [[ "$#" -gt 0 ]]; then
|
||||
TASKS=("$@")
|
||||
else
|
||||
TASKS=("connectedDebugAndroidTest")
|
||||
fi
|
||||
|
||||
echo "Running Gradle tasks: ${TASKS[*]}"
|
||||
./gradlew --no-daemon "${TASKS[@]}"
|
||||
Reference in New Issue
Block a user