{"platform":{"slug":"android","platform":"Android","documentationVersion":"v2.0.2","officialDocumentationUrl":"https://developer.mappls.com/documentation/sdk/android/","repositoryGuideSlugs":["mappls-android-sdk","mappls-android-compose-demo"],"supportedComponents":["Map SDK 9.0.3","Place Search Widget 3.0.2","Direction Widget 3.0.1","Nearby UI Widget 2.0.1","GeoFence Widget 2.0.0","Feedback UI 4.0.0"],"lifecycleOwner":"One Activity, Fragment, or Compose wrapper owns launch, callback registration, saved state, and disposal.","returnBoundary":"Translate the documented Activity/Fragment result into a small application selection before persisting it.","cancellationBoundary":"Back, close, process recreation, denied configuration, and an unavailable Activity are distinct outcomes.","credentialBoundary":"Use the updated post-August-2025 Android configuration files restricted to package and signing identity; never put a server credential in the APK.","productionChecks":["BoM/component versions resolve together","Debug and release signing identities are separately approved","Rotation and process death do not duplicate a commit","Fragment/Activity listeners are removed with their owner"],"scaffold":{"language":"kotlin","label":"Kotlin host contract","code":"data class PlaceSelection(val mapplsPin: String, val label: String)\n\ninterface MapplsPlaceWidget {\n    suspend fun selectPlace(): PlaceSelection? // null means deliberate cancellation\n}\n\nclass AddressDraft(private val widget: MapplsPlaceWidget) {\n    suspend fun choose(): PlaceSelection? = widget.selectPlace()?.also { selected ->\n        require(Regex(\"^[A-Za-z0-9]{6}$\").matches(selected.mapplsPin))\n        // Persist through the application repository, not a Fragment reference.\n    }\n}"},"verifiedAt":"2026-08-17"},"capability":{"slug":"directions","title":"Directions UI","stateModel":"session","durableIdentity":"Application route request/revision identity; provider UI is not a navigation session","platforms":{"android":{"availability":"published","component":"Direction Widget","version":"3.0.1","documentationUrl":"https://developer.mappls.com/documentation/sdk/android/"},"ios":{"availability":"published","component":"MapplsDirectionUI","version":"2.0.0","documentationUrl":"https://developer.mappls.com/documentation/sdk/ios-sdk/"},"flutter":{"availability":"published","component":"Direction Widget","version":"2.0.0","documentationUrl":"https://developer.mappls.com/documentation/sdk/flutter-sdk/"},"react-native":{"availability":"published","component":"Direction Widget","version":"2.0.1","documentationUrl":"https://developer.mappls.com/documentation/sdk/react-native-sdk/"}}},"implementation":{"availability":"published","component":"Direction Widget","version":"3.0.1","documentationUrl":"https://developer.mappls.com/documentation/sdk/android/"},"readiness":"source-ready","lifecycle":[{"state":"idle","owner":"Application screen","evidence":"No provider controller, route, Promise, delegate, or listener is active."},{"state":"launching","owner":"Platform adapter","evidence":"One generation ID binds configuration, owner, and launch time."},{"state":"active","owner":"Provider widget under host lifecycle","evidence":"Background, recreation, close, and duplicate-launch behavior are observable."},{"state":"returned / cancelled / failed","owner":"Platform adapter","evidence":"Exactly one typed terminal result wins; late results are ignored."},{"state":"candidate","owner":"Application domain","evidence":"Validate and normalize application route request/revision identity; provider ui is not a navigation session before committing."},{"state":"committed","owner":"Application repository","evidence":"Persist the normalized selection/draft with version, actor, source, and audit event."}],"stateOwnership":["One Activity, Fragment, or Compose wrapper owns launch, callback registration, saved state, and disposal.","Translate the documented Activity/Fragment result into a small application selection before persisting it.","Back, close, process recreation, denied configuration, and an unavailable Activity are distinct outcomes.","The durable record is application route request/revision identity; provider ui is not a navigation session; never retain a provider view/controller or opaque bridge result."],"acceptanceTests":["BoM/component versions resolve together","Debug and release signing identities are separately approved","Rotation and process death do not duplicate a commit","Fragment/Activity listeners are removed with their owner","Permission/configuration denied","Offline and slow provider response","Cancel before and after a candidate appears","Host edit invalidates a stale selection","Duplicate callback/Promise result commits once","Accessibility, focus return, and a non-widget fallback"],"samples":[{"language":"kotlin","label":"Kotlin host contract","code":"data class PlaceSelection(val mapplsPin: String, val label: String)\n\ninterface MapplsPlaceWidget {\n    suspend fun selectPlace(): PlaceSelection? // null means deliberate cancellation\n}\n\nclass AddressDraft(private val widget: MapplsPlaceWidget) {\n    suspend fun choose(): PlaceSelection? = widget.selectPlace()?.also { selected ->\n        require(Regex(\"^[A-Za-z0-9]{6}$\").matches(selected.mapplsPin))\n        // Persist through the application repository, not a Fragment reference.\n    }\n}"}],"evidenceBoundary":"The current Android overview lists Direction Widget 3.0.1 under documentation v2.0.2. Confirm the exact package, configuration, callback schema, and entitlement in the selected guide before binding the adapter.","websiteUrl":"/tools/widgets/native?platform=android&capability=directions"}