⌘ K
    Web
    🌵 Web
    Mobile
    🌵 iOS
    🌵 Android
    🌵 React Native
    🌵 Flutter
    Copyright © 2025 AiACTIV

    AiactivUniversalSDK

    Ads and Analytics Framework

    Prerequisites

    • minSdkVersion of 21 or higher
    • compileSdkVersion of 33 or higher

    Installation

    AiactivUniversalSDK is available through MVN. To install it, add mavenCentral to your repositories if it's not added yet.

    repositories {
    mavenCentral()
    }

    Import AiactivUniversalSDK dependency

    dependencies {
    implementation 'io.aiactiv:universal-sdk:x.x.x'
    }

    Add this code to app manifest, wrapped in <application> tag and replace FILL_YOUR_WRITE_KEY_HERE

    <meta-data android:name="io.aiactiv.sdk.WRITE_KEY" android:value="FILL_YOUR_WRITE_KEY_HERE" />

    By default, we use same WRITE_KEY for both frameworks. If you would like use WRITE_KEY for AdNetwork, please add new one meta-data for it.

    <meta-data android:name="io.aiactiv.sdk.WRITE_KEY_ADNETWORK" android:value="FILL_YOUR_WRITE_KEY_HERE" />

    Usage

    AdNetwork

    Banner Ad

    // Create AdView with size and type is banner
    val adView = AdView(requireContext())
    adView.apply {
    id = View.generateViewId()
    size = AdSize.MEDIUM_RECTANGLE
    unitId = YOUR_INVENTORY_ID
    }
    // Add AdView to your layout
    val parent = binding.root as ConstraintLayout
    parent.addView(adView)
    // Perform loadAd with a request
    val adRequest = AdRequest.Builder().build()
    adView.loadAd(adRequest)

    Predefined sizes:

    AdSizeWidth x Height
    BANNER320x50
    FULL_BANNER468x60
    LARGE_BANNER320x100
    RECTANGLE250x250
    MEDIUM_RECTANGLE300x250
    VIDEO480x360

    Or custom any size in format widthxheight. Example: 640x480, 300x500...

    Adaptive Banner Ad

    Create AdView with size and type is banner programmatically

    val adView = AdView(requireContext())
    adView.apply {
    id = View.generateViewId()
    size = AdSize.MEDIUM_RECTANGLE
    unitId = YOUR_INVENTORY_ID
    }

    Or create in XML, it's layout_width & layout_height must be wrap_content

    <io.aiactiv.sdk.adnetwork.ads.AdView
    android:id="@+id/adBanner"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

    Make AdView full width

    val maxWidth = resources.displayMetrics.widthPixels
    adView.adaptiveSize(maxWidth) // Or any dimension in pixel unit

    Video Ad

    Load Ad VAST Tag Url
    // Create VideoAdLoader with size and type is video
    val videoAdLoader = VideoAdLoader.Builder(
    requireContext(),
    adUnitID = YOUR_INVENTORY_ID,
    adSize = AdSize.VIDEO
    ).build()
    // Set listener to retrieve data later
    videoAdLoader.listener = this
    // Perform loadAd with a request
    val adRequest = AdRequest.Builder().build()
    videoAdLoader.loadAd(adRequest)
    Using Native Player to player Content and Ad

    Please make sure exclude ExoPlayer module in AiactivUniversalSDK and use it from your dependency instead of

    implementation ('io.aiactiv:universal-sdk:x.x.x') {
    exclude group: 'androidx.media3', module: 'media3-exoplayer-ima'
    }

    Define your player in layout

    <com.google.android.exoplayer2.ui.PlayerView
    android:id="@+id/player_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"/>

    Declare Player and AdsLoader

    private lateinit var imaAdsLoader: ImaAdsLoader
    private var player: Player? = null

    Init player

    private fun initializePlayer(vastTagUrl: String) {
    val dataSourceFactory = DefaultDataSource.Factory(requireContext())
    val mediaSourceFactory = DefaultMediaSourceFactory(dataSourceFactory).apply {
    setAdsLoaderProvider { imaAdsLoader }
    setAdViewProvider { binding.playerView }
    }
    player = ExoPlayer.Builder(requireContext()).apply {
    setMediaSourceFactory(mediaSourceFactory)
    }.build()
    binding.playerView.player = player
    imaAdsLoader.setPlayer(player)
    val contentUri = Uri.parse("<<<YOUR CONTENT URL>>>")
    val adTagUri = Uri.parse(vastTagUrl)
    val adsConfiguration = MediaItem.AdsConfiguration.Builder(adTagUri).build()
    val mediaItem = MediaItem.Builder().apply {
    setUri(contentUri)
    setAdsConfiguration(adsConfiguration)
    }.build()
    player?.apply {
    setMediaItem(mediaItem)
    prepare()
    playWhenReady = false
    }
    }

    Listen event video Ad loaded and perform playing

    videoAdLoader.listener = object : VideoAdListener {
    override fun onVideoAdLoaded(adUnitID: Int, bid: Bid, vastTagUrl: String) {
    // Call init with vast tag url
    initializePlayer(vastTagUrl)
    // Play Video Ad
    binding.playerView.onResume()
    }
    override fun onVideoAdFailedToLoad(adUnitID: Int, error: String) {
    Log.d("VideoAdFragment","Video Ad did fail to load with error:: $error")
    }
    }

    Setup listener for events

    playerView.listener = object : IMAPlayerView.PlayerViewListener {
    override fun onImaAdsLoaded(adUnitID: Int, bid: Bid, vastTagUrl: String) {
    Log.d("onImaAdsLoaded","Video Ad Content URL: $vastTagUrl")
    }
    override fun onImaAdsFailedToLoad(adUnitID: Int, error: String) {
    Log.d("onImaAdsFailedToLoad","Video Ad did fail to load with error: $error")
    }
    override fun onAdEvent(adEventName: String?) {
    Log.d("VideoAdFragment","Ad Event: $adEventName")
    }
    override fun onAdErrorEvent(errorTypeName: String?) {
    Log.d("VideoAdFragment","Ad Error Event: $errorTypeName")
    }
    }

    Don't forget release to prevent leak memory when screen is destroyed

    playerView.releasePlayer();

    Native Ad

    Using forNativeAd callback

    NativeAdLoader will fetch nativeAd data and then binding to your views manually

    val nativeAdLoader = NativeAdLoader.Builder(requireContext(), YOUR_INVENTORY_ID)
    .forNativeAd { nativeAd ->
    populateNativeAdView(nativeAd)
    }
    .build()
    // Perform load Ad
    nativeAdLoader.loadAd(AdRequest.Builder().build())
    NativeAd PropertiesType
    titleString
    descriptionString
    iconUrlString
    mainImageUrlString
    mainImageRatioFloat
    ctaDescriptionString
    sponsoredString

    Example

    private fun populateNativeAdView(nativeAd: NativeAd) {
    nativeAd.title?.let { title ->
    tvTitle.text = title
    }
    nativeAd.description?.let { description ->
    tvDescription.text = description
    }
    nativeAd.mainImageUrl?.let { imageUrl ->
    imgMain.load(imageUrl)
    }
    nativeAd.iconUrl?.let { iconUrl ->
    imgIcon.load(iconUrl)
    }
    nativeAd.ctaDescription?.let { ctaDescription ->
    btnCTA.text = ctaDescription
    btnCTA.setOnClickListener {
    // Perform Ad Clicked
    nativeAd.performAdClicked(requireContext()) { uri ->
    return@performAdClicked true // If you'd like handle uri, please return false
    }
    }
    }
    }
    Using bindingIDs method

    NativeAdLoader will fetch nativeAd data and binding to your view automatically. Please make sure your view id is matching NativeAD.ID constants.

    val nativeAdLoader = NativeAdLoader.Builder(requireContext(), YOUR_INVENTORY_ID)
    .bindingIDs(
    mutableMapOf(
    NativeAd.ID_TITLE to R.id.tv_title,
    NativeAd.ID_DESCRIPTION to R.id.tv_body,
    NativeAd.ID_CTA_DESCRIPTION to R.id.btn_cta,
    NativeAd.ID_IMAGE_ICON to R.id.img_icon,
    NativeAd.ID_IMAGE_MAIN to R.id.img_main
    )
    )
    .build()
    // Perform load Ad
    adLoader.loadAd(AdRequest.Builder().build())

    For listening Ad Click event, register AdListener to AdLoader

    Example

    nativeAdLoader.adListener = object : AdListener {
    override fun onAdLoaded(adUnitID: Int) {
    Log.d("AdLoader", "Ad Loaded")
    }
    override fun onAdFailedToLoad(adUnitID: Int, error: String) {
    Log.d("AdLoader", "Ad did fail to load with error: $error")
    }
    override fun callToActionPerformed(uri: Uri?): Boolean {
    Log.d("AdLoader", "callToActionPerformed: $uri")
    return true
    }
    }
    Using Native Ad templates

    AiactivUniversalSDK provides three types of template: DEFAULT, MEDIUM, ARTICLE

    Define NativeAdTemplateView in your layout xml file

    <io.aiactiv.sdk.adnetwork.ads.NativeAdTemplateView
    android:id="@+id/native_ad_view_default"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:template="DEFAULT" />

    In Kotlin code, using NativeAdLoader to fetch NativeAd data then binding withTemplateView method

    val nativeAdView = findViewById<NativeAdTemplateView>(R.id.native_ad_view_default)
    val nativeAdLoader = NativeAdLoader.Builder(requireContext(), YOUR_INVENTORY_ID)
    .withTemplateView(nativeAdView)
    .build()
    nativeAdLoader.loadAd(AdRequest.Builder().build())

    Override Ad Clicked event if needed

    nativeAdView.setOnAdClickListener { _, uri ->
    Log.d("NativeAdView", "Ad Clicked: $uri")
    false
    }

    Using AdRequest

    // Create AdView
    // ...
    // Perform loadAd with a request
    val screenContext = HashMap<String, String>()
    screenContext["keywords"] = arrayOf("talents", "show", "tv-show").joinToString()
    screenContext["title"] = "HomeScreen"
    val adRequest = AdRequest.Builder().apply {
    context = screenContext
    }.build()

    Custom AdSize

    Banner
    val adView = AdView(requireContext())
    adView.apply {
    id = View.generateViewId()
    size = AdSize.forCustomBanner(300, 200)
    unitId = YOUR_INVENTORY_ID
    }
    Video
    // Create PlayerView...
    playerView.requestAd(
    YOUR_INVENTORY_ID,
    adRequest,
    AdSize.forCustomVideo(480, 360),
    );
    // Create VideoAdLoader
    val videoAdLoader = VideoAdLoader.Builder(
    requireContext(),
    adUnitID = YOUR_INVENTORY_ID,
    adSize = AdSize.forCustomVideo(480, 360)
    ).build()

    Interstitial Ad

    private fun loadAd() {
    val inventory = 123
    val interstitialAdView = InterstitialAdView(activity)
    interstitialAdView.apply {
    unitId = inventory
    }
    val adRequest = AdRequest.Builder().build()
    interstitialAdView.loadAd(adRequest)
    interstitialAdView.adListener = object : AdListener {
    override fun onAdLoaded(adUnitID: Int) {
    }
    override fun onAdFailedToLoad(adUnitID: Int, error: String) {
    }
    }
    }

    Listen Ad Events

    For Banner Ad - AdListener
    adView.adListener = object: AdListener {
    override fun onAdLoaded(adUnitID: Int, bid: Bid) {
    Log.d("AdView", "Ad Loaded with bid id: ${bid.id}")
    }
    override fun onAdFailedToLoad(adUnitID: Int, error: String) {
    Log.d("AdView", "Ad did fail to load with error:: $error")
    }
    override fun shouldOverrideOnAdClicked(view: BaseAdView, uri: Uri?): Boolean {
    Log.d("AdView", "Click on Ad")
    return super.shouldOverrideOnAdClicked(view, uri)
    }
    }
    For Video Ad - VideoAdListener
    videoAdLoader.listener = object : VideoAdListener {
    override fun onVideoAdLoaded(adUnitID: Int, bid: Bid, vastTagUrl: String) {
    Log.d("VideoAdFragment","Video Ad Content URL: $vastTagUrl")
    binding.textAdContentUrl.text = vastTagUrl
    }
    override fun onVideoAdFailedToLoad(adUnitID: Int, error: String) {
    Log.d("VideoAdFragment","Video Ad did fail to load with error:: $error")
    }
    override fun onAdEvent(adEventName: String?) {
    Log.d("VideoAdFragment","Ad Event: $adEventName")
    }
    override fun onAdErrorEvent(errorTypeName: String?) {
    Log.d("VideoAdFragment","Ad Error Event: $errorTypeName")
    }
    }

    Remove Ad

    For Banner Ad
    // Remove AdView when loading Ad failed
    binding.root.removeView(adView);

    Analytics

    Analytics will be initialized and collect data and support manually collect event

    Track Events

    Aiactiv.with(context).apply {
    track("Application launched")
    }
    // or
    Aiactiv.track(applicationContext, "Application launched")

    Identify Events

    Aiactiv.with(context).apply {
    // Traits about user like email, phone number, birthday...
    val traits = Traits()
    identify("user id", traist)
    }
    // or
    // Traits about user like email, phone number, birthday...
    val traits = Traits()
    Aiactiv.identify(applicationContext, "user id", traist)

    Screen Events

    Aiactiv.with(context).apply {
    // Properties about screen like content id, title...
    screen("screen name", properties)
    }
    // or
    // Properties about screen like content id, title...
    Aiactiv.identify(applicationContext, "user id", properties)

    Author

    AiACTIV TECH, tech@aiactiv.io

    License

    AiactivUniversalSDK is available under the MIT license. See the LICENSE file for more info.