Screenshot via MediaProjection (ScreenCapturer, gleicher {format,bytes,base64}-
Vertrag wie der Desktop-Agent -> host_screenshot, inkl. Vision). UI-Baum via
AriaAccessibilityService (nur lesend) -> neues Brain-Tool host_ui_dump. Freigabe
einmalig in der App: 'Bildschirm-Zugriff erlauben' + 'Bedienungshilfe oeffnen'.
caps = [info, screenshot, ui_dump]. targetSdk 33 -> keine mediaProjection-FGS-
Typpflicht.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ARIA Android-Agent
Ein nativer Android-Agent (eigene APK), der ARIA erlaubt, ein Smartphone
fernzusteuern — inkl. Bedienen fremder App-UIs (z.B. „ARIA, richte auf dem
Handy ein E-Mail-Konto ein"). Gegenstück zum Desktop-host-agent (Linux/macOS/
Windows), aber Android ist kein Unix-Shell-System — deshalb ein anderes
Action-Set (UI-Automation statt beliebiger Shell-Kommandos).
Verbindet sich wie die ARIA-App ausgehend zum RVS (gleicher Token/Raum),
Verbindungs-Setup per QR-Scan oder manueller Eingabe. Taucht in der
Diagnostic unter Satelliten → Host-Agenten 💻 auf (host_hello mit
os="Android …" + Android-Caps).
Warum nativ (Kotlin), nicht Termux/RN
- UI-Automation (fremde Apps bedienen) geht auf Android nur über einen AccessibilityService — den kann nur eine native App bereitstellen.
- Screenshots einer laufenden Session: MediaProjection (native).
- Dauerbetrieb: Foreground-Service mit Notification (native).
- Termux gäbe nur Shell +
termux-api(SMS/Anruf/Standort …), kein Bedienen anderer App-UIs. Für „E-Mail-Konto durchklicken" reicht das nicht.
Tech: Kotlin, OkHttp-WebSocket (RVS-Client), CameraX/ML-Kit (QR), AccessibilityService (Input), MediaProjection (Screenshot). Build via Docker (Android-SDK + Gradle) → APK. Nur Linux baut APKs (Docker), Deploy manuell.
Action-Set (host_command → host_result)
Android-spezifisch (statt exec/read/write des Desktop-Agents):
| Action | Was |
|---|---|
screenshot |
Bildschirmfoto (MediaProjection) — ARIA sieht den Schirm |
ui_dump |
Sichtbare UI als Baum (Texte, Buttons, Felder + Koordinaten) — ARIAs „Augen" für gezieltes Tippen |
ui_tap |
Tippen (x,y ODER auf ein Element aus ui_dump) |
ui_text |
Text in das fokussierte/angegebene Feld schreiben |
ui_swipe |
Wischen/Scrollen |
ui_key |
Systemtasten (BACK, HOME, ENTER …) |
app_launch |
App per Paketname starten (z.B. E-Mail-App) |
app_list |
installierte Apps auflisten |
info |
Gerät: Modell, Android-Version, Akku, Netz, IP |
notify |
Benachrichtigung anzeigen |
| (später) | sms_send, call, location, clipboard (je nach Bedarf + Berechtigung) |
ARIA-Flow „E-Mail einrichten": app_launch (Mail-App) → screenshot/ui_dump
(sehen, was da ist) → ui_tap/ui_text (durchklicken) → wieder ui_dump prüfen,
bis fertig. Genau das agentische Muster wie beim Endian-Fix, nur mit Handy-UI.
Dauerbetrieb — Foreground-Service vs. Push (FCM)
Der Agent muss immer erreichbar sein, obwohl Android Hintergrundprozesse aggressiv killt (Doze, App-Standby, OEM-Batterie-Manager wie Xiaomi/Huawei). Zwei Wege, deine WhatsApp-Intuition trifft ins Schwarze:
A) Foreground-Service (persistente WebSocket) — der einfache Start:
- Dauerhafte RVS-Verbindung + Foreground-Notification („Agent aktiv").
- Braucht:
FOREGROUND_SERVICE, Akku-Optimierung ausnehmen (REQUEST_IGNORE_BATTERY_OPTIMIZATIONS— User whitelistet die App),RECEIVE_BOOT_COMPLETED+ BootReceiver (Neustart nach Reboot), Auto-Reconnect (haben wir im Protokoll schon). - Reutzt unser bestehendes
host_hello/host_command/host_result1:1. - Nachteil: etwas Akku; manche OEMs killen trotzdem → „Autostart" manuell erlauben.
B) Self-hosted Push (KEIN Google!) — genau wie WhatsApp, aber auf eigenem Server:
- UnifiedPush + self-hosted ntfy: Auf dem ARIA-Server läuft ntfy (freier, self-hostbarer Push-Server). Der Agent nutzt UnifiedPush (offener Standard, de-Google-Welt/F-Droid) mit dem ntfy-Distributor auf dem Handy. Will ARIA etwas, POSTet die Bridge/RVS an ntfy → weckt die App → sie holt den Befehl vom RVS, arbeitet, antwortet. Läuft auch auf Custom-ROMs OHNE Google Play Services.
- Akkuschonend wie FCM, aber ohne jede Google-Abhängigkeit. Nur ein Dienst mehr (ntfy) im Stack + der Push-Auslöser serverseitig.
C) FCM (Google) — optional: Wer ein Stock-Android mit Play Services hat und Googles Push-Kanal will, kann FCM statt ntfy nehmen (bester Akku auf GMS-Geräten). Braucht Firebase-Projekt + Play Services. Nur eine Option, keine Pflicht.
Custom-ROM ohne Google: → Weg A (eigener Socket) oder B (self-hosted ntfy). Beide brauchen KEIN Google. Für Stefans dediziertes Ziel-Handy ist A sogar oft die einfachste Dauerlösung (unser eigener „Push" über den RVS-Socket).
Hybrid (ideal, End-Ausbau): Im Leerlauf nur Push (max. Akku). Ein Push weckt die App → sie öffnet die RVS-Verbindung, hält sich per Wakelock für die Interaktion wach (mehrere Befehle flüssig, z.B. E-Mail-Setup durchklicken) → schläft nach ein paar Sekunden Ruhe wieder ein. So WhatsApp-Akku UND schnelle Multi-Befehl-Sessions. Der Push kommt dabei von B (self-hosted ntfy) oder C (FCM) — freie Wahl. Erste Push-Latenz aus tiefem Doze ~1–3 s; danach bleibt der Socket die Session offen.
Empfehlung: Meilenstein 1–3 mit A (Foreground-Service) — läuft sofort und nutzt alles Vorhandene, damit wir schnell einen funktionierenden Agenten haben, ganz ohne externe Dienste. Dann Push-Hybrid mit self-hosted ntfy (B) als Akku-Ausbau — KEIN Google. FCM (C) nur optional für Stock-Android. Action-Set/Protokoll bleiben identisch, nur der Wecker ändert sich.
Sicherheit
- Reagiert nur auf den eigenen RVS-Raum (Token); Setup per QR/manuell.
- CONTROL_ENABLED-Schalter in der App (Default AUS) — erst wenn Stefan es bewusst aktiviert, führt der Agent Aktionen aus.
- AccessibilityService + MediaProjection müssen vom User explizit in den Android-Einstellungen freigegeben werden (kein stiller Zugriff möglich).
- Alle Aktionen werden protokolliert (In-App-Log + optional an ARIA).
- Voller Gerätezugriff — nur auf eigenen/anvertrauten Geräten nutzen.
Meilensteine
- ✅ Verbinden + sichtbar — Gradle-Projekt, AndroidManifest, RVS-WS-Client,
Foreground-Service, Connect-UI (QR-Scan + manuell),
host_hello/host_ping. → Agent erscheint in der Diagnostic.infofunktioniert. - ✅ Sehen — MediaProjection-Screenshot (
ScreenCapturer, gleicher{format,bytes,base64}-Vertrag wie der Desktop-Agent →host_screenshot) +ui_dump(AriaAccessibilityService, nur lesend → Brain-Toolhost_ui_dump). Freigabe einmalig in der App: „Bildschirm-Zugriff erlauben" + „Bedienungshilfe öffnen". → ARIA sieht den Schirm und liest die UI-Elemente mit Koordinaten. - Steuern —
ui_tap/ui_text/ui_swipe/ui_key/app_launchüber den AccessibilityService. → ARIA bedient Apps (E-Mail-Setup). - Feinschliff —
info/app_list/notify, Build-Härtung,release.sh(Version-Param → Gitea-Release-Asset, wie die App).
Build & Release (geplant)
cd host-agent/android
./build.sh # Docker (Android-SDK+Gradle) -> aria-android-agent.apk
./release.sh 0.1.0 # baut, taggt, laedt APK als Gitea-Release-Asset hoch
APK wird manuell aufs Zielgerät kopiert + installiert (unbekannte Quellen erlauben). Gitea-Release macht den Download einfach (wie die Haupt-App).
Status: M1 + M2 fertig (verbinden,
info,screenshot,ui_dump). Als Nächstes Meilenstein 3 (Steuern).