Moments
Mobile
Android Integration Guide (Kotlin)
25min
overview this guide explains how to integrate the momentscience sdk into your android app using kotlin and jetpack compose the sdk supports two integration modes, each designed to improve the user experience at checkout by preloading relevant offers integration modes sdk prefetch mode in this mode, the sdk handles offer fetching internally a hidden 0Γ0 webview is initialized in advance, allowing offers to be cached before checkout begins this results in an instant display of offers during checkout, without additional network calls simplest integration path, minimal setup required no need to manage https requests manually api prefetch mode this mode gives your app full control over when and how offers are fetched you initiate a native http request using your own logic and pass the response into the sdk at checkout time greater control over timing and payload enables server side optimizations and logging in both modes, offers are rendered in a webview at the checkout screen because offers are preloaded before checkout, the user experience remains fast and frictionless, even when no offers are found if no offers are returned, you can choose to skip showing the offer display screen altogether requirements to integrate the momentscience sdk into your android app, ensure the following prerequisites are met momentscience sdk id learn more about getting your sdk id environment kotlin version 1 6 0 or higher minimum android sdk version 26 target android sdk version 35 ui framework jetpack compose setup instructions step 1 add dependencies to enable the momentscience sdk, you need to add the required dependencies and network permissions add html assets add the required html templates to your project these files are used by the sdk to render the offer experience in a webview required files adpx template html https //github com/adspostx/examples/blob/main/android native/momentscienceapiwebdemoapp android native/app/src/main/assets/templates/adpx template html checkout template html you can place them in assets/templates folder in the momentscience android demo app, these files are placed in \<your app package>/templates/ add and install dependencies in your app level build gradle kts , add the following dependencies build gradle kts dependencies { // enables webview support for rendering the sdk implementation("androidx webkit\ webkit 1 6 0") // used for native api requests in api prefetch mode implementation("com squareup okhttp3\ okhttp 4 10 0") // used for parsing json offer payloads implementation("com google code gson\ gson 2 10") } what these do webview is required to embed and render the momentscience sdk okhttp is used to perform http requests in api prefetch mode gson is used to deserialize json responses into kotlin data classes add internet permission add the following permission in your androidmanifest xml file it must be placed inside the \<manifest> tag but outside the \<application> block androidmanifest xml \<uses permission android\ name="android permission internet" /> this permission is required for the sdk to connect to momentscience services in both sdk prefetch mode and api prefetch mode step 2 prefetch offers (sdk or api) momentscience offers two modes for prefetching offers before rendering them on your ui sdk prefetch uses a hidden 0Γ0 webview to silently fetch and cache offers before checkout api prefetch uses a native api call to fetch offers, which are then injected into the sdk display template in both modes, you can skip showing the checkout screen if no offers are found option 1 sdk prefetch in this method, a hidden webview preloads the sdk when offers are available, the sdk triggers an ads found callback event itβs the lightest touch integration, ideal when you want minimal native logic step 1 load the web sdk in a 0Γ0 webview to prefetch offers insert a 0x0 webview on a screen that runs before the offer screen make sure to enable java script, dom storage for webview π example offersview\ kt add a javascript interface to enable communication from the webview to your native code, // callback type typealias adpxcallbackhandler = (event string, payload string) > unit // javascript interface to receive sdk events like `ads found` class adpxjavascriptinterface( private val callbackhandler adpxcallbackhandler? = null ) { @javascriptinterface fun adpxcallback(event string, payload string) { log d("adpxjsinterface", "event $event, payload $payload") // avoid in prod callbackhandler? invoke(event, payload) } } // attach to webview webview\ addjavascriptinterface( adpxjavascriptinterface { event, payload > viewmodel handleadpxcallback(event, payload) }, "android" ) π₯ why is this needed? this callback allows your app to know if offers are available (ads found), helping you decide whether to show the offer screen π example offersviewmodel kt load the webview using a pre filled html template var localsdkid by remember { mutablestateof("\<your sdk id here>") } try { webview\ loaddatawithbaseurl( viewmodel getbaseurl(), viewmodel gethtmlcontent(localsdkid, context), "text/html", "utf 8", null ) } catch (e exception) { viewmodel seterror("failed to load html template ${e message}") } payload example you can create payload with key,value pair of map\<string, string> type, eg like below createpayload() function private val payload = mutablestateflow\<map\<string, string>?>(null) val payload stateflow\<map\<string, string>?> = payload asstateflow() private fun createpayload() map\<string, string> { return mapof( "pub user id" to getuniqueid(), "placement" to "checkout", "themeid" to "standard theme" //replace with your theme id ) } viewmodel gethtmlcontent injects the sdk id, payload, adpxuser into adpx template html , which loads the sdk in prefetch mode example offersviewmodel kt step 2 show offers using fullscreen webview once the ads found event confirms offers are available, render the offers on your checkout screen using a full screen webview, pass required parameters as below checkoutview( sdkid = sdkid, jsonresponse = jsonresponse, isfromapiprefetch = isfromapiprefetch, offercount = offercount, payload = payload, onbackpressed = { navcontroller popbackstack() } // handle back navigation ) the full screen webview loads the offer experience using the checkout template html template this html file dynamically injects your configuration and prefetch result make sure to enable java script, dom storage for webview val htmlcontent by viewmodel htmlcontent collectasstate() if (!contentloaded && htmlcontent isnotempty()) { webview\ loaddatawithbaseurl( viewmodel getbaseurl(), htmlcontent, "text/html", "utf 8", null ) } private val htmlcontent = mutablestateflow("") val htmlcontent stateflow\<string> = htmlcontent asstateflow() val html = checkouthtmltemplate generate( sdkid = sdkid, offerscount = count, // optional jsonresponse = null, // not needed in websdk mode isfromapiprefetch = false, context = context, payload = payload ) htmlcontent value = html the checkouthtmltemplate generate() function populates checkout template html with your sdk id and payload option 2 prefetch with api in this method, your app fetches offers from the momentscience offers api ahead of time and passes them into the web sdk at render time step 1 fetch offers via momentscience offers api send a post request to post https //api adspostx com/native/v4/offers json π example networkserviceimpl kt private val jsonresponse = mutablestateflow\<jsonelement?>(null) val jsonresponse stateflow\<jsonelement?> = jsonresponse asstateflow() val response = networkservice fetchoffers( sdkid = sdkid, ua = useragent, placement = "your placement id", ip = userip, pubuserid = getuniqueid(), payload = payload ) jsonresponse value = response πrefer to offersviewmodel kt for offer parsing logic πlearn more about the moments api in our documentation step 2 show offers in fullscreen webview once offers are confirmed, render them inside a full webview by passing the prefetched data into your offer display/checkout screen checkoutview( sdkid = sdkid, jsonresponse = jsonresponse, isfromapiprefetch = isfromapiprefetch, offercount = offercount, payload = payload, onbackpressed = { navcontroller popbackstack() } // handle back navigation ) add a full screen webview make sure to enable java script, dom storage for webview π example checkoutview\ kt load the web sdk to display the offers private val htmlcontent = mutablestateflow("") val htmlcontent stateflow\<string> = htmlcontent asstateflow() val html = checkouthtmltemplate generate( sdkid = sdkid, offerscount = count, jsonresponse = jsonresponse, isfromapiprefetch = true, context = context, payload = payload ) htmlcontent value = html the checkouthtmltemplate generate() https //github com/adspostx/examples/blob/main/android native/momentscienceapiwebdemoapp android native/app/src/main/java/com/momentscience/apiwebdemoapp/templates/checkouthtmltemplate kt function reads from checkout template html https //github com/adspostx/examples/blob/main/android native/momentscienceapiwebdemoapp android native/app/src/main/assets/templates/checkout template html and replaces values accordingly step 3 open clicks in an external browser when users interact with offer links inside the web sdk, it's often best to open those links in the device's default external browser, rather than inside the in app webview this ensures a smoother user experience and prevents users from getting stuck inside a webview implementation steps in the screen where offers are rendered (e g , checkoutview ), override the shouldoverrideurlloading method inside your webviewclient override fun shouldoverrideurlloading(view webview?, url string?) boolean { url? let { val intent = intent(intent action view, uri parse(it)) context startactivity(intent) return true // you've handled the url } return false // fall back to webview if url is null } implement this override inside your webviewclient class used in the offer display screen notes this override ensures all offer clickouts open outside your app using the system browser always validate or sanitize urls if you're handling sensitive or custom redirect flows \| π for a working example, see the implementation in checkoutview\ kt check out the momentscience android demo on github to see the complete implementation, including offer fetching, webview rendering, event handling, and external link support conclusion youβve now successfully integrated the momentscience sdk into your android app using kotlin and jetpack compose whether youβre using web sdk prefetch mode or api prefetch mode, your app is now equipped to deliver personalized offers that enhance the user experience and drive conversions π’ if you're running into any issues while going through the integration process, feel free to contact us at help\@m omentscience com