fix: Umbenennen greift nicht — Android lieferte den Intent nicht aus

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>
This commit is contained in:
2026-09-30 02:16:21 +02:00
co-authored by Claude Opus 4.8
parent 44aef71813
commit ff6d474f29
3 changed files with 20 additions and 3 deletions
@@ -38,6 +38,7 @@
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:launchMode="singleTop"
android:label="@string/app_name"> android:label="@string/app_name">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -214,7 +214,9 @@ class MainActivity : AppCompatActivity() {
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent) super.onNewIntent(intent)
if (intent != null && applyProvisioning(intent)) return if (intent == null) return
setIntent(intent)
applyProvisioning(intent)
} }
/** /**
+16 -2
View File
@@ -1306,9 +1306,15 @@ def _do_adb_provision(params: dict) -> dict:
# ("Wohnzimmer Fire TV") wuerden dabei abgeschnitten -> jeden Wert quoten. # ("Wohnzimmer Fire TV") wuerden dabei abgeschnitten -> jeden Wert quoten.
import shlex import shlex
q = shlex.quote q = shlex.quote
# Der Intent MUSS eindeutig sein: Android vergleicht beim Start Komponente,
# Action und Daten — NICHT die Extras. Ohne eigene Daten-URI gilt ein zweites
# Provisioning als "gleicher Intent", die Activity wird nur nach vorn geholt
# und onCreate/onNewIntent laufen nie -> der alte Name bliebe stehen.
stamp = str(int(time.time() * 1000))
args = ["-s", target, "shell", "am", "start", args = ["-s", target, "shell", "am", "start",
"-n", f"{package}/.MainActivity", "-n", f"{package}/.MainActivity",
"-a", f"{package}.PROVISION", "-a", f"{package}.PROVISION",
"-d", q(f"aria://provision/{stamp}"),
"-e", "host", q(rvs_host), "-e", "host", q(rvs_host),
"-e", "token", q(rvs_token), "-e", "token", q(rvs_token),
"--ei", "port", str(int(params.get("rvs_port") or 443)), "--ei", "port", str(int(params.get("rvs_port") or 443)),
@@ -1320,8 +1326,16 @@ def _do_adb_provision(params: dict) -> dict:
args += ["-e", "reply_mode", q(str(params["reply_mode"]))] args += ["-e", "reply_mode", q(str(params["reply_mode"]))]
rc, out, err = _adb_run(args, timeout=60) rc, out, err = _adb_run(args, timeout=60)
if rc != 0 or "Error" in f"{out} {err}": txt = f"{out} {err}".strip()
return {"ok": False, "error": (f"{out} {err}".strip() or f"exit {rc}")[:400]} if rc != 0 or "Error" in txt:
return {"ok": False, "error": (txt or f"exit {rc}")[:400]}
# Android meldet das, wenn es den Intent als "schon offen" abtut und die
# Activity nur nach vorn holt — dann kaeme die neue Konfiguration NICHT an.
if "brought to the front" in txt.lower() or "not started" in txt.lower():
return {"ok": False, "error":
"Android hat den Einrichtungs-Intent nicht ausgeliefert (Activity "
"war schon offen). Auf dem Geraet die Agent-App einmal schliessen "
"und erneut 'Nur einrichten' druecken. Details: " + txt[:200]}
return {"ok": True, "result": { return {"ok": True, "result": {
"target": target, "package": package, "target": target, "package": package,
"message": f"Agent eingerichtet (RVS {rvs_host}) und gestartet"}} "message": f"Agent eingerichtet (RVS {rvs_host}) und gestartet"}}