Das hier ist der wertvollste Teil des Repos: Dinge, die nirgends dokumentiert sind und die jeweils Stunden gekostet haben. Wenn du an einer Galaxy Watch ohne Google-Konto arbeitest, spart dir diese Seite den größten Teil davon.
Symptom: Jede App-Installation hängt oder bricht ab — bei Aurora Store genauso wie bei einem eigenen Laden. Der Bestätigungsdialog erscheint gar nicht.
Im Log:
SecurityException: Can't install packages while in secure FRP
Ursache: Die Uhr steckt im Werksschutz-Modus (Factory Reset Protection), obwohl die Einrichtung abgeschlossen ist — vermutlich, weil sie ohne Google-Konto eingerichtet wurde. In diesem Zustand blockiert der PackageManager alles.
Lösung:
adb shell settings put global secure_frp_mode 0
adb shell settings put secure secure_frp_mode 0
Danach läuft die Installation normal. Der Wert bleibt gesetzt; nach einem
Systemupdate lohnt eine erneute Prüfung. Markt setzt ihn beim Start selbst
zurück (braucht dafür WRITE_SECURE_SETTINGS, per adb pm grant).
Merke: Bei „Installation hängt” immer zuerst
secure_frp_modeprüfen — nicht den eigenen Installer verdächtigen.
Ein Vordergrunddienst muss eine Benachrichtigung zeigen. Auf One UI Watch half nichts davon:
IMPORTANCE_MINVISIBILITY_SECRETCATEGORY_SERVICEFOREGROUND_SERVICE_DEFERREDWas funktioniert: Die Benachrichtigung auf einen gesperrten Kanal legen
(IMPORTANCE_NONE). Dann ist sie zwar technisch vorhanden, taucht aber in der
Liste nicht auf.
nm.createNotificationChannel(new NotificationChannel(
"app_stumm", "Dienst (stumm)", NotificationManager.IMPORTANCE_NONE));
Ein bestehender Kanal lässt sich nicht nachträglich leiser stellen — bei Bedarf löschen und mit neuer ID anlegen.
Prüfen, ob wirklich nichts angezeigt wird (verlässlicher als jede Geste):
adb shell cmd notification list # taucht das eigene Paket auf?
Symptom: Das eigene iPhone zeigt die werbende Uhr, ein anderes iPhone zeigt gar nichts — obwohl es nie mit der Uhr verbunden war.
Zwei Ursachen, beide wichtig:
a) Der Name fehlte im Werbepaket. Ein BLE-Werbepaket fasst 31 Byte. Die 128-Bit-ANCS-Solicitation belegt 18, Flags 3 — es bleiben rund 8 Zeichen für den Namen. „Galaxy Watch6 Classic (A5TR)” passt nicht, also landete der Name in der Scan-Antwort. Ein Telefon, das das Gerät schon kennt, zeigt es trotzdem (es hat den Namen im Zwischenspeicher) — ein fremdes listet Geräte ohne Namen im Werbepaket nicht.
Lösung: kurzen Bluetooth-Namen setzen, dann passt er mit hinein:
if (adapter.getName().length() > 8) adapter.setName("Herold");
new AdvertiseData.Builder()
.setIncludeDeviceName(true)
.addServiceSolicitationUuid(new ParcelUuid(ANCS_SERVICE))
.build();
Wird das Paket doch zu groß, meldet onStartFailure Code 1 — dann ohne
Namen erneut versuchen (macht Herold automatisch).
b) Die Uhr war nie klassisch sichtbar.
ScanMode: SCAN_MODE_CONNECTABLE # <- nicht auffindbar
iOS listet in den Bluetooth-Einstellungen praktisch nur klassisch sichtbare Geräte. Reine BLE-Werbung reicht einem unbekannten Telefon nicht:
adb shell am start -a android.bluetooth.adapter.action.REQUEST_DISCOVERABLE \
--ei android.bluetooth.adapter.extra.DISCOVERABLE_DURATION 300
Und: Ein verbundenes Gerät stoppt die Werbung. Beim Koppeln mit Telefon B also Bluetooth an Telefon A ausschalten.
adb shell am broadcast -a com.google.android.wearable.app.DEBUG_SURFACE \
--es operation set-watchface \
--ecn component <paket>/<klasse>
Antwort Favorite Id=[..] Runtime=[..] = gesetzt.
--ecn, nicht --es component. Mit --es antwortet die Uhr stur
„Either component name or watchface id are required.” — der Extra muss ein
ComponentName sein.
AppNotSupported (code=2) — auch ältere, technisch passende Versionen.adb shell content query --uri content://com.google.android.gsf.gservices \
--where "name='android_id'"
Kommt nichts zurück, hat die Uhr keine Google-Geräte-ID. Dann erreichen Push-Nachrichten die Uhr nie — Apps, die Inhalte „ans Gerät senden” (Ziffernblätter, Cloud-Sync), funktionieren nicht, egal wie oft man drückt. Ohne Konto lässt sich das nicht nachholen.
Das ist die härteste Grenze des ganzen Projekts. Wer solche Dienste braucht, kommt um ein Google-Konto nicht herum.
restriction, compatibility und ein erfolgreicher Auslieferungstest
unterscheiden nicht zwischen Handy- und Uhr-App — Play liefert auch
WhatsApp an die Uhr aus./store/apps/category/ANDROID_WEAR und /store/apps/category/WATCH_FACE,
über die Web-Helfer abgerufen.BatteryManager.isCharging() meldet beim drahtlosen Laden „nein”. Richtig
ist der klebrige Batterie-Intent:
Intent i = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int plugged = i.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
int status = i.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean laedt = plugged != 0
|| status == BatteryManager.BATTERY_STATUS_CHARGING
|| status == BatteryManager.BATTERY_STATUS_FULL;
-3 = Uhr wird nicht getragen. Messung sofort abbrechen.ERROR = lockere Uhr oder Bewegung. Zeigt der Puls lange
„–”, liegt es fast immer daran — nicht am Code. Die App sagt es dem Nutzer.AMBIENT-Temperatur ist die Gehäusetemperatur des Sensorchips, nicht
die Raumluft. Wärmefluss-Modelle für die Körperkerntemperatur scheitern daran.
Ehrlicher Weg: Abweichung vom persönlichen Grundwert aus mehreren Nächten.Eine naive Analyse („schwankt stark → unregelmäßig”) meldet bei jungen, gesunden Menschen Fehlalarm: Beim Atmen schwankt der Puls stark, aber rhythmisch.
Der Unterschied liegt im Muster: Nachbarvorhersage über mehrere Abstände und spektrale Bandleistung. Ist die Schwankung vorhersagbar, ist es Atmung. Ist sie chaotisch und ohne Muster, ist sie unregelmäßig. Dazwischen gehört ein ehrliches „unsicher”.
Schwellen nicht raten — an vielen nachgebildeten Messreihen ablesen und gegen
echte Aufzeichnungen prüfen (herold/test/).
uhr.sh --daemon verbindet endlos neu, ringt mit jedem
anderen adb-Zugriff und löst auf der Uhr ein Benachrichtigungs-Gewitter aus.
Bei Verbindungsproblemen zuerst den eigenen Rechner prüfen:
pgrep -fl uhr.sh.KEYCODE_WAKEUP, sonst sind sie schwarz.
svc power stayon wirkt nur am Ladekabel.am force-stop tötet den Benachrichtigungsdienst. Danach kommt er erst
durch Öffnen der App oder einen Neustart zurück — nie so liegen lassen.zip … classes*.dex, nicht classes.dex.--target-sdk-version 29.