Connect IQ Mobile SDK: Keine Nachrichten von der Garmin-App – registerAppToUseBinderService abmelden
Meine Android-App sollte Nachrichten mit einer Connect-IQ-App auf einem Edge 1050 austauschen. Mit dem neuen Binder-Weg des Mobile SDK kam gar nichts an: keine Nachrichten, keine Status-Callbacks, kein Fehler. Einmal abmelden, das SDK neu initialisieren und bei den klassischen Broadcasts bleiben hat es gelöst.
$ git log --graph Der Weg zur Lösung
-
Problem
Keine Nachrichten
Die Edge-App sendet, die Android-App empfängt nichts und bekommt auch keine Callbacks.
-
Versuch
Binder-Weg
Mit registerAppToUseBinderService blieb es still, ohne jede Fehlermeldung.
-
Erkenntnis
Registrierung ist das Problem
Solange die Binder-Registrierung besteht, kommt bei Garmin Connect 5.30.1 nichts durch.
-
Lösung
Einmal abmelden
unregisterAppFromUsingBinderService, SDK neu initialisieren, klassische Broadcasts: Die Nachrichten laufen.
Umgebung: Android-Begleit-App in Kotlin mit dem Connect IQ Mobile SDK (ciq-companion-app-sdk 2.4.0), Garmin Connect Mobile 5.30.1 auf einem Pixel, Gegenstelle eine Connect-IQ-App bzw. ein Datenfeld auf einem Edge 1050. Die Garmin-Seite schickt per Communications.transmit, das Handy antwortet mit sendMessage.
Das Problem
Das SDK bietet neben den klassischen Broadcasts einen neueren Weg über einen gebundenen Dienst (registerAppToUseBinderService). Solange meine App dafür registriert war, kam nichts an: registerForAppEvents lieferte keine Nachrichten, sendMessage keine Rückmeldung, Status-Callbacks blieben aus. Es gab keine Exception und keine Logzeile, nur Stille. Das ist schwer zu finden, weil auf beiden Seiten alles korrekt aussieht.
Die Lösung
Den Binder-Weg einmalig abmelden. Das setzt das SDK zurück, deshalb muss man es danach neu initialisieren und erst dann die Listener registrieren:
private fun registerGarmin() {
val c = ciq ?: return
if (!prefs.getBoolean("binderRemoved", false)) {
// Einmalig abmelden; das setzt das SDK zurueck -> danach neu initialisieren
try { c.unregisterAppFromUsingBinderService(APP_ID, ctx) } catch (e: Exception) { note("Binder abmelden: ${e.message}") }
prefs.edit().putBoolean("binderRemoved", true).apply()
note("Binder-Weg abgemeldet, starte Garmin neu")
sdkReady = false
main.postDelayed({ initGarmin() }, 1000)
return
}
try { c.registerForAppEvents(appListener) } catch (e: Exception) { note("App-Events: ${e.message}") }
// ... registerForDeviceEvents fuer knownDevices usw.
}
Danach liefen Nachrichten in beide Richtungen über die klassischen Broadcasts zuverlässig, auch mit zwei Datenfeldern gleichzeitig.
Warum das funktioniert
Abschließend geklärt habe ich das nicht. Mit der getesteten Kombination aus SDK 2.4.0 und Garmin Connect 5.30.1 kam über den Binder-Weg nichts an. Die Abmeldung räumt diese Registrierung auf, danach nutzt das SDK wieder die Broadcasts. Ob das bei anderen Versionen genauso ist, weiß ich nicht.
Stolperfallen
- Nach
unregisterAppFromUsingBinderServiceist das SDK-Objekt zurückgesetzt. Ohne neuesinitializepassiert wieder nichts. - Scheitert das Senden an ein Datenfeld mit
FAILURE_DURING_TRANSFER, läuft das Datenfeld meist einfach nicht, etwa weil kein Aktivitätsprofil offen ist. Im Log nur den Wechsel melden, nicht jeden Versuch. - Datenfelder auf dem Edge 1050 dürfen selbst senden und empfangen (
Communications.transmit,registerForPhoneAppMessages, BerechtigungCommunications). Bei mir schickt das Feld alle 30 s ein Lebenszeichen, und das Handy pusht danach alle 5 s. So weiß die App, welche Felder aktiv sind. - Meldet das SDK
NOT_CONNECTED, obwohl Bluetooth verbunden ist, hilft es, Garmin Connect zu beenden und neu zu öffnen.