This commit is contained in:
team3
2026-09-19 23:50:36 +02:00
parent e0c615c73a
commit a62b587340
26 changed files with 1654 additions and 1 deletions

6
android/dev/env.sh Normal file
View File

@@ -0,0 +1,6 @@
# source android/dev/env.sh – JDK, SDK, Emulator und Gradle aus ~/Android in den PATH
export ANDROID_ROOT=${ANDROID_ROOT:-$HOME/Android}
export JAVA_HOME="$ANDROID_ROOT/jdk17"
export ANDROID_HOME="$ANDROID_ROOT/Sdk"
export ANDROID_SDK_ROOT="$ANDROID_HOME"
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator:$ANDROID_ROOT/gradle/bin:$PATH"

43
android/dev/setup.sh Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/bash
# Android-Werkzeuge ohne Root nach ~/Android: JDK 17, SDK, Emulator, Gradle.
# Danach: android/dev/env.sh einbinden (source), dann gradle und adb im PATH.
set -e
ROOT=${ANDROID_ROOT:-$HOME/Android}
mkdir -p "$ROOT" && cd "$ROOT"
if [ ! -x jdk17/bin/java ]; then
echo "== JDK 17"
curl -sL -o jdk.tar.gz "https://api.adoptium.net/v3/binary/latest/17/ga/linux/x64/jdk/hotspot/normal/eclipse?project=jdk"
tar xzf jdk.tar.gz && rm jdk.tar.gz
mv jdk-17* jdk17
fi
export JAVA_HOME="$ROOT/jdk17"
export ANDROID_HOME="$ROOT/Sdk"
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator:$ROOT/gradle/bin:$PATH"
if [ ! -x "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" ]; then
echo "== Android Kommandozeilen-Tools"
curl -sL -o cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
mkdir -p "$ANDROID_HOME/cmdline-tools"
unzip -q cmdline-tools.zip -d "$ANDROID_HOME/cmdline-tools" && rm cmdline-tools.zip
mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest"
fi
echo "== SDK-Pakete"
yes | sdkmanager --licenses >/dev/null 2>&1 || true
sdkmanager --install "platform-tools" "platforms;android-34" "build-tools;34.0.0" "emulator" \
"system-images;android-34;google_apis;x86_64" > /dev/null
if ! avdmanager list avd 2>/dev/null | grep -q "Name: test"; then
echo "== Emulator-Gerät"
echo no | avdmanager create avd -n test -k "system-images;android-34;google_apis;x86_64" -d pixel_6 > /dev/null
fi
if [ ! -x gradle/bin/gradle ]; then
echo "== Gradle"
curl -sL -o gradle.zip https://services.gradle.org/distributions/gradle-8.9-bin.zip
unzip -q gradle.zip && rm gradle.zip
mv gradle-8.9 gradle
fi
echo "fertig: $(java -version 2>&1 | head -1); gradle $(gradle --version 2>/dev/null | grep -m1 Gradle | awk '{print $2}')"

78
android/dev/ui.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
# Bedienung des Emulators über adb, für Tests und Screenshots:
# dev/ui.sh boot wartet, bis der Emulator hochgefahren ist
# dev/ui.sh install baut nicht, installiert app/build/outputs/apk/debug/app-debug.apk und startet die App
# dev/ui.sh start App (neu) starten
# dev/ui.sh tap "Text" tippt auf das erste Element mit diesem Text (oder Beschreibung)
# dev/ui.sh longtap "Text" langes Drücken
# dev/ui.sh tapxy X Y tippt auf Koordinaten
# dev/ui.sh type "Text" tippt Text ins fokussierte Feld
# dev/ui.sh key KEYCODE z.B. BACK, ENTER
# dev/ui.sh has "Text" gibt true/false aus, ob der Text auf dem Bildschirm steht
# dev/ui.sh texts alle Texte auf dem Bildschirm
# dev/ui.sh shot name Screenshot nach /tmp/desktop-app-android/name.png
# dev/ui.sh dump Oberfläche als XML
DIR=$(cd "$(dirname "$0")" && pwd)
source "$DIR/env.sh"
OUT=/tmp/desktop-app-android
mkdir -p "$OUT"
APP=de.marha.planer
# Tests laufen im Emulator, auch wenn ein Handy per USB hängt
export ANDROID_SERIAL=${ANDROID_SERIAL:-emulator-5554}
dump() {
adb shell uiautomator dump /sdcard/ui.xml >/dev/null 2>&1
adb shell cat /sdcard/ui.xml
}
# Mittelpunkt des ersten Knotens mit Text oder content-desc
center() {
dump | python3 -c '
import re, sys
wanted = sys.argv[1]
xml = sys.stdin.read()
hits = []
for node in re.finditer(r"<node [^>]*>", xml):
n = node.group(0)
text = re.search(r" text=\"([^\"]*)\"", n).group(1)
desc = re.search(r" content-desc=\"([^\"]*)\"", n).group(1)
if text == wanted or desc == wanted:
hits.append(n)
# Bei mehreren Treffern (Dialogtitel und Button) den letzten nehmen, Buttons stehen unten
if not hits:
sys.exit(1)
x1, y1, x2, y2 = map(int, re.search(r"bounds=\"\[(\d+),(\d+)\]\[(\d+),(\d+)\]\"", hits[-1]).groups())
print((x1 + x2) // 2, (y1 + y2) // 2)
' "$1"
}
case "$1" in
boot)
adb wait-for-device
until [ "$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r')" = "1" ]; do sleep 2; done
adb shell settings put global window_animation_scale 0 >/dev/null
adb shell settings put global transition_animation_scale 0 >/dev/null
adb shell settings put global animator_duration_scale 0 >/dev/null
echo "bereit" ;;
install)
adb install -r "$DIR/../app/build/outputs/apk/debug/app-debug.apk" | tail -1
"$0" start ;;
start)
adb shell am force-stop $APP
adb shell am start -n $APP/.MainActivity >/dev/null
sleep 2 ;;
tap)
XY=$(center "$2") || { echo "nicht gefunden: $2"; exit 1; }
adb shell input tap $XY; sleep 0.8 ;;
longtap)
XY=$(center "$2") || { echo "nicht gefunden: $2"; exit 1; }
adb shell input swipe $XY $XY 900; sleep 0.8 ;;
tapxy) adb shell input tap "$2" "$3"; sleep 0.8 ;;
type) adb shell input text "$(printf '%s' "$2" | sed 's/ /%s/g')"; sleep 0.5 ;;
key) adb shell input keyevent "$2"; sleep 0.8 ;;
has) dump | grep -q "text=\"$2\"\|content-desc=\"$2\"" && echo true || echo false ;;
texts) dump | grep -o 'text="[^"]*"' | grep -v 'text=""' | sed 's/text=//' | tr '\n' ' '; echo ;;
shot) adb exec-out screencap -p > "$OUT/$2.png"; echo "$OUT/$2.png" ;;
dump) dump ;;
*) echo "unbekannt: $1"; exit 1 ;;
esac