Der Agent meldete 'gesprochen', es kam aber kein Ton: Fire TV Sticks haben in
der Regel keine (deutsche) TTS-Engine, und wir haben weder setLanguage noch den
Rueckgabewert von speak() geprueft -> stiller Fehlschlag.
- speak/notify fordern jetzt ARIAs ECHTE Stimme ueber den bestehenden Serverpfad
an: tts_request -> Bridge -> F5/XTTS -> audio_pcm, das der Agent abspielt.
Keine Server-Aenderung noetig (beide Typen stehen in der RVS-Allow-List).
VoiceSession merkt sich die angeforderte messageId und spielt genau dieses
Audio ab — die Turn-Ownership bleibt sonst unveraendert (Handy redet nicht mit).
- Geraete-TTS nur noch auf ausdrueckliche Anforderung (engine='device') und nun
ehrlich: fehlende Engine, fehlende deutsche Sprachdaten und ein abgelehntes
speak() werden als Fehler gemeldet statt als Erfolg.
Android-Version 0.0.1.6.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bisher stand im Namensfeld die technische Kennung aus der Netz-Erkennung
(F8FCE10B4E6C@AS-AFTKA[AirPlay]) — auch wenn das Geraet laengst 'Fire-TV
Schlafzimmer' heisst. Jetzt in dieser Reihenfolge:
1. Name, den der Agent auf DIESEM Geraet traegt — Zuordnung ueber die IP, die
der Agent neu in host_hello mitmeldet (localIp()); Server reicht sie durch.
2. zuletzt hier eingegebener Name (localStorage je Satellit+IP).
3. Name aus der Erkennung, aber nur wenn menschenlesbar — Seriennummern, IPs
und Kennungen mit @/[]/: werden verworfen (Feld bleibt leer).
Android-Version 0.0.1.5.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bisher wurde KEIN Audio-Fokus angefordert: Android mischt dann beide Tonspuren,
d.h. Netflix/Jellyfin/Spotify liefen in voller Lautstaerke weiter und ARIA war
kaum zu verstehen — und beim Zuhoeren nahm das Mikrofon den Filmton mit auf.
AudioFocusHelper mit drei Modi:
- speak/notify: AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK ('duck', Standard) -> Medien
werden leiser und danach automatisch wieder lauter. Per focus-Param auch
'pause' (Medien anhalten) oder 'none'.
- listen: AUDIOFOCUS_GAIN_TRANSIENT ('pause') -> Medien halten an, solange das
Mikrofon offen ist; danach laufen sie weiter.
- Fokus wird in allen Pfaden zurueckgegeben (Completion, Fehler, stop, shutdown),
sonst blieben die Medien dauerhaft leise.
Brain: focus-Parameter in host_notify/host_speak. Android-Version 0.0.1.4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die BERECHTIGUNGEN bleiben dauerhaft (pm grant / appops in appops.xml), die
MediaProjection-SITZUNG aber nicht — Android laesst sie nicht speichern. Nach
Reboot/App-Neustart war der Agent also verbunden, konnte aber keinen Screenshot
machen, bis jemand am Fernseher 'Bildschirm-Zugriff erlauben' drueckt.
- CaptureActivity: unsichtbarer Helfer (Theme.Translucent, noHistory,
excludeFromRecents), fordert die Projektion an und reicht das Ergebnis an den
Dienst. Mit gesetztem AppOp PROJECT_MEDIA laeuft das OHNE Dialog durch.
- AgentService startet sie beim Dienststart automatisch nach (2,5s Verzoegerung),
aber nur wenn captureEnabled gesetzt ist — wer die Aufnahme nie wollte, bekommt
auch keinen Dialog.
- AgentConfig.captureEnabled: wird gesetzt, sobald die Aufnahme einmal lief, und
kann beim Fern-Einrichten mitgegeben werden (nur wenn der Satellit PROJECT_MEDIA
wirklich erteilen konnte).
Android-Version 0.0.1.3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Android vergleicht beim Activity-Start Komponente/Action/Daten, aber NICHT die
Extras. Ein zweites Provisioning galt damit als 'derselbe Intent': die Activity
wurde nur nach vorn geholt, onCreate/onNewIntent liefen nie — der alte Name blieb
stehen (und kam nach dem Loeschen aus der Liste sofort wieder).
- Satellit: eindeutige Daten-URI (aria://provision/<ms>) je Aufruf -> der Intent
ist nie 'gleich'. Zusaetzlich wird die am-start-Ausgabe auf 'brought to the
front'/'not started' geprueft und als Fehler gemeldet statt als Erfolg.
- Android: MainActivity launchMode=singleTop -> erneutes Provisioning landet
zuverlaessig in onNewIntent (statt neuer Instanz); setIntent() ergaenzt.
Android-Version 0.0.1.2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Am Fire TV gibt es keine Kamera (kein QR) und Host/Token mit der Fernbedienung
einzugeben ist eine Qual. Der Satellit hat aber ohnehin schon eine ADB-Verbindung
— darueber bekommt der Agent seine Zugangsdaten direkt.
- Android: MainActivity.applyProvisioning() liest Intent-Extras (host/port/tls/
token/name/control/reply_mode), speichert sie, startet den Dienst und zeigt
'Von ARIA eingerichtet' (Transparenz). Auch via onNewIntent.
- Satellit: adb.provision (am start mit Extras) und adb.status (installiert?
laeuft? welche Version?). adb.install richtet direkt mit ein, wenn rvs_host/
rvs_token mitkommen -> ein Klick = installieren + einrichten + online.
- Diagnostic: Checkbox 'Gleich einrichten' (default an) + 'Status pruefen'-Button.
Der RVS-Zugang wird SERVERSEITIG ergaenzt (params.provision) — das Token steht
nie im Browser-Formular.
- Allowlists (Code + .env.example) und README ergaenzt, inkl. Sicherheitshinweis.
Android-Version 0.0.1.1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Stick wird vom gesteuerten Geraet zum Gespraechspartner:
- VoiceSession: Mikro -> stt_stream_start/stt_audio_chunk(pcm,16k mono s16le,
6400B)/stt_stream_end (exakt das App-Protokoll, keine Server-Aenderung noetig);
Antwort via chat(sender=aria) + audio_pcm(base64, 24k) in AudioTrack. AEC/NS an.
TURN-OWNERSHIP: der RVS broadcastet an alle — es wird nur ausgegeben, was aus der
EIGENEN Frage entstand (audioRequestId -> messageId), sonst reden Handy und Stick
gleichzeitig.
- OverlayView: TYPE_APPLICATION_OVERLAY, Einblendung ueber dem laufenden Bild
(Text + optional Bild), nicht fokussierbar (Fernbedienung bleibt frei).
- Speaker: ARIAs echte Stimme (fertiges Audio) bevorzugt, Geraete-TTS als Fallback,
Lautstaerke-Steuerung.
- Neue Aktionen: notify (Einblendung/Sprache, mode ueberschreibbar), speak, volume,
listen/listen_stop.
- Einstellung replyMode (overlay|speech) in der App, pro Anfrage ueberschreibbar.
- Sprech-Taste in der UI (Fire TV: OK-Taste) + Mikro-/Overlay-Berechtigungen.
Version 0.0.1.0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Kein zweiter Agent: dieselbe APK laeuft auf Fire TV, Fähigkeiten capability-gated
(wie beim Desktop-Agent).
- Manifest: touchscreen/faketouch/leanback als required=false (sonst gilt die App
als Touch-Pflicht bzw. laeuft nicht mehr aufs Handy), LEANBACK_LAUNCHER (ohne
das fehlt die App im Fire-TV-Menue), TV-Banner (Launcher zeigt Banner statt Icon).
- RvsClient: isTv-Erkennung (leanback/television/UiModeManager) -> caps bekommen
'tv', os meldet 'Fire TV / Android TV'.
- AriaAccessibilityService.globalKey: D-Pad (up/down/left/right/ok) via Fokus-
Navigation, Medientasten via dispatchMediaKeyEvent, Lautstaerke/Mute via
AudioManager — deutsche Aliase (hoch/runter/lauter/stumm).
- MainActivity/Layout: auf TV QR-Scan ausgeblendet (keine Kamera), erster Fokus
gesetzt, Buttons fokussierbar (Fernbedienung).
Version 0.0.0.8.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Erkenntnis aus dem Live-Test: bei gesperrtem Bildschirm greifen Gesten/Tasten
nicht (Android-Sicherheit), der Agent meldete aber still 'ok' -> Verwirrung
(home,home,home, Screenshot zeigt trotzdem alte App). Fix: KeyguardManager.
isKeyguardLocked() gate fuer Steuer-Aktionen (ui_tap/text/swipe/key/app_launch)
-> klare Meldung 'Geraet ist gesperrt - bitte entsperren'. Sehen (screenshot/
ui_dump/info) bleibt auch gesperrt erlaubt. README-Hinweis ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Geraet (Android 12) meldete beim Projizieren:
'Media projections require a foreground service ...
FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION'. Der Dienst lief als reiner dataSync.
Fix: foregroundServiceType=dataSync|mediaProjection + Permissions
FOREGROUND_SERVICE_MEDIA_PROJECTION/-DATA_SYNC; beim Projektions-Start
startForeground(..., MEDIA_PROJECTION|DATA_SYNC) VOR getMediaProjection().
Normale Starts nutzen explizit nur dataSync (Android-14-konform). Version 0.0.0.5.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Timeout hiess: kein host_result kam zurueck. Ursachen adressiert:
1) handle() umschliesst JEDE Aktion mit try/catch(Throwable) -> auch OOM/Exception
liefert jetzt ein host_result mit Fehlertext statt Stille (kein Timeout mehr).
2) ScreenCapturer nimmt direkt in gekappter Aufloesung auf (max 1280 lange Seite,
MediaProjection skaliert) statt Vollbild-Bitmap + Nachskalieren -> viel weniger
Speicher/Zeit (kein 10-MB-ARGB-Bitmap -> kein OOM), Frame-Warten bis ~3s.
lastError fliesst in die Screenshot-Fehlermeldung. Version 0.0.0.4/code 4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Jeder Build signierte bisher mit einem zufaelligen Auto-Debug-Key -> neue APK =
andere Signatur -> Android verweigert Update ('Konflikt mit bestehendem Paket').
Fester signingConfig (rootProject/aria-agent.keystore) fuer debug+release, per
Datei-Existenz-Guard. Keystore liegt nur lokal (gitignored, NICHT im public Repo
— Backup!). Verifiziert: Signer-DN CN=ARIA Host-Agent. Version 0.0.0.3/code 3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Projection-Consent kommt per startForegroundService, obwohl der Dienst schon
laeuft. Android verlangt danach binnen ~5s ein startForeground() -> fehlte im
Projection-Zweig -> ForegroundServiceDidNotStartInTimeException -> Prozess-Crash
(Diagnostic zeigt den Host bis zum Ping-Timeout noch gruen). Fix: onStartCommand
ruft IMMER zuerst startForeground(). Zusaetzlich ScreenCapturer.start in try/catch
mit lastError, das in der Screenshot-Fehlermeldung und der Notification erscheint.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
Nativer Kotlin-Agent (host-agent/android/): Gradle-Projekt, AndroidManifest,
RVS-WebSocket-Client (OkHttp) mit host_hello/host_ping/host_command->host_result,
Foreground-Service (Weg A, Auto-Reconnect, BootReceiver), Connect-UI (QR-Scan via
ZXing ODER manuell: host/port/token/name/TLS/Steuerung-Schalter). QR-Format =
{host,port,token,tls} wie die ARIA-App -> derselbe QR nutzbar.
M1-Aktion: info (Modell/Android/Akku). screenshot/ui_* liefern 'kommt in M2/M3'.
Gate: CONTROL_ENABLED-Schalter in der App. Build: Docker (Android-SDK+Gradle) ->
dist/aria-android-agent.apk (Debug, auto-signiert). Kein Google.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>