Page 1 of 1

Richtige Verwendung der Google API (Navigation) in einer sauberen Android-Architektur

Posted: 12 Jan 2025, 14:49
by Guest
Ich habe eine Frage zur Verwendung von Google APIs (in meinem Fall NavigationAPI) in einer sauberen Architektur.
Um die Google-Navigation verwenden zu können, ist ein Navigator-Objekt von NavigationApi erforderlich. getNavigator-API.
Anfangs dachte ich, dass es in Ordnung ist, alle notwendigen Implementierungen in der DATA-Schicht unterzubringen, diese Schicht soll jedoch nur Daten (lokal, remote) enthalten und den Zugriff darauf ermöglichen. Dann ist Navigator jedoch stark von SupportNavigationFragment abhängig, das sich in der Präsentationsebene befindet. Wie wir wissen, sollten niedrigere Schichten nicht von höheren Schichten abhängen.
Als nächstes dachte ich, dass alle erwähnten Implementierungen in Fragment verschoben werden sollten, aber ich bin nicht 100 % sicher, ob das richtig ist auch wenn es vernünftig klingt. Hat jemand Erfahrung mit Google API in Clean Arch?
Funktionalität, die ich benötige:

Code: Select all

private var navigator: Navigator? = null

override fun initializeNavigator(activity: FragmentActivity) {
NavigationApi.getNavigator(activity, object : NavigationApi.NavigatorListener {
override fun onNavigatorReady(navigator: Navigator?) {
navigator = navigator
addListeners()
}

override fun onError(errorCode: Int) {
handleError(errorCode)
}
})
}

override fun startNavigation() {
navigator?.setAudioGuidance(Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE)
navigator?.startGuidance()
}

override fun stopNavigation() {
navigator?.stopGuidance()
navigator?.clearDestinations()
}

override fun getRouteSummary(waypoint: Waypoint, options: RoutingOptions) = callbackFlow {
navigator?.let { navigator ->
val pendingRoute = navigator.setDestination(waypoint, options)
pendingRoute.setOnResultListener { code ->
_navigationStateFlow.value = NavigationState.SUMMARY
val result = trySend(
NavigationSummary(
response = code,
meters = navigator.currentTimeAndDistance.meters,
seconds = navigator.currentTimeAndDistance.seconds
)
)
}

awaitClose {
…
}
}
}

private fun addListeners() {
val arrivalListener = Navigator.ArrivalListener {
navigator?.clearDestinations()
}
navigator?.addArrivalListener(arrivalListener)

val routeChangedListener = Navigator.RouteChangedListener {
…
}
navigator?.addRouteChangedListener(routeChangedListener)
}

private fun handleError(errorCode: Int) {
when (errorCode) {
NavigationApi.ErrorCode.NOT_AUTHORIZED -> {
…
}

NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED -> {
...
}

NavigationApi.ErrorCode.NETWORK_ERROR -> {
…
}

NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING -> {
…
}

else -> {
...
}
}
}