Skip to main content

CloudX Android SDK

Maven Central

Automated Integration with Claude Code

Integrate CloudX SDK in 15 minutes with AI-powered agents: Requires Claude Code.
# Install CloudX agents
bash <(curl -fsSL https://raw.githubusercontent.com/cloudx-io/cloudx-sdk-agents/main/scripts/install.sh)

# In your Android project:
claude "Use @agent-cloudx-android-integrator to integrate CloudX SDK with app key: YOUR_KEY"
  • First-look CloudX with automatic fallback to existing ad setup
  • Privacy compliance validation (GDPR, CCPA)
  • Build verification catches errors early
  • Preserves existing ad setup as backup
Full Setup Guide

Manual Installation

Requires Android API 21+ and Java 8+. Add the CloudX SDK to your app’s build.gradle:
dependencies {
    implementation("io.cloudx:sdk:0.12.0")

    // Adapters for ad networks
    implementation("io.cloudx:adapter-cloudx:0.12.0")
    implementation("io.cloudx:adapter-meta:0.12.0")    // Meta Audience Network 6.17.0
    implementation("io.cloudx:adapter-vungle:0.12.0")  // Vungle SDK 7.6.1
}

Initialization

// Initialize with app key
CloudX.initialize(
    initParams = CloudXInitializationParams(
        appKey = "your-app-key-here",
        testMode = false  // Set true for test ads during development
    ),
    listener = object : CloudXInitializationListener {
        override fun onInitialized() {
            Log.d("CloudX", "CloudX SDK initialized successfully")
        }

        override fun onInitializationFailed(cloudXError: CloudXError) {
            Log.e("CloudX", "Failed to initialize CloudX SDK: ${cloudXError.message}")
        }
    }
)

Ad Integration

class MainActivity : AppCompatActivity(), CloudXAdViewListener {
    private lateinit var bannerAd: CloudXAdView

    private fun createBannerAd() {
        bannerAd = CloudX.createBanner("your-banner-placement-name")
        bannerAd.listener = this

        val layoutParams = LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
        )
        layoutParams.gravity = Gravity.CENTER_HORIZONTAL
        findViewById<LinearLayout>(R.id.banner_container).addView(bannerAd, layoutParams)
    }

    override fun onDestroy() {
        super.onDestroy()
        bannerAd.destroy()
    }

    // CloudXAdViewListener callbacks
    override fun onAdLoaded(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Banner ad loaded from ${cloudXAd.bidderName}")
    }

    override fun onAdLoadFailed(cloudXError: CloudXError) {
        Log.e("CloudX", "Banner ad failed to load: ${cloudXError.message}")
    }

    override fun onAdDisplayed(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Banner ad displayed")
    }

    override fun onAdClicked(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Banner ad clicked")
    }

    override fun onAdHidden(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Banner ad hidden")
    }

    override fun onAdDisplayFailed(cloudXError: CloudXError) {
        Log.e("CloudX", "Banner ad failed to display: ${cloudXError.message}")
    }

    override fun onAdExpanded(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Banner ad expanded")
    }

    override fun onAdCollapsed(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Banner ad collapsed")
    }
}
Banner ads auto-refresh by default. To control refresh manually:
bannerAd.stopAutoRefresh()  // Stop auto-refresh
bannerAd.load()             // Manually load a new ad
bannerAd.startAutoRefresh() // Re-enable auto-refresh

MREC Ads (300x250)

class MainActivity : AppCompatActivity(), CloudXAdViewListener {
    private lateinit var mrecAd: CloudXAdView

    private fun createMrecAd() {
        mrecAd = CloudX.createMREC("your-mrec-placement-name")
        mrecAd.listener = this

        val layoutParams = LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
        )
        layoutParams.gravity = Gravity.CENTER_HORIZONTAL
        findViewById<LinearLayout>(R.id.mrec_container).addView(mrecAd, layoutParams)
    }

    override fun onDestroy() {
        super.onDestroy()
        mrecAd.destroy()
    }

    // CloudXAdViewListener callbacks (same as Banner)
    override fun onAdLoaded(cloudXAd: CloudXAd) {
        Log.d("CloudX", "MREC ad loaded from ${cloudXAd.bidderName}")
    }

    override fun onAdLoadFailed(cloudXError: CloudXError) {
        Log.e("CloudX", "MREC ad failed to load: ${cloudXError.message}")
    }

    override fun onAdDisplayed(cloudXAd: CloudXAd) {
        Log.d("CloudX", "MREC ad displayed")
    }

    override fun onAdClicked(cloudXAd: CloudXAd) {
        Log.d("CloudX", "MREC ad clicked")
    }

    override fun onAdHidden(cloudXAd: CloudXAd) {
        Log.d("CloudX", "MREC ad hidden")
    }

    override fun onAdDisplayFailed(cloudXError: CloudXError) {
        Log.e("CloudX", "MREC ad failed to display: ${cloudXError.message}")
    }

    override fun onAdExpanded(cloudXAd: CloudXAd) {
        Log.d("CloudX", "MREC ad expanded")
    }

    override fun onAdCollapsed(cloudXAd: CloudXAd) {
        Log.d("CloudX", "MREC ad collapsed")
    }
}
MREC ads also auto-refresh by default. Use the same refresh control methods as Banner ads.

Interstitial Ads

class MainActivity : AppCompatActivity(), CloudXInterstitialListener {
    private lateinit var interstitialAd: CloudXInterstitialAd

    private fun createInterstitialAd() {
        interstitialAd = CloudX.createInterstitial("your-interstitial-placement-name")
        interstitialAd.listener = this
        interstitialAd.load()
    }

    private fun showInterstitialAd() {
        if (interstitialAd.isAdReady) {
            interstitialAd.show()
        } else {
            Log.w("CloudX", "Interstitial ad not ready yet")
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        interstitialAd.destroy()
    }

    // CloudXInterstitialListener callbacks
    override fun onAdLoaded(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Interstitial ad loaded from ${cloudXAd.bidderName}")
    }

    override fun onAdLoadFailed(cloudXError: CloudXError) {
        Log.e("CloudX", "Interstitial ad failed to load: ${cloudXError.message}")
    }

    override fun onAdDisplayed(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Interstitial ad displayed")
    }

    override fun onAdDisplayFailed(cloudXError: CloudXError) {
        Log.e("CloudX", "Interstitial ad failed to display: ${cloudXError.message}")
    }

    override fun onAdHidden(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Interstitial ad hidden")
        // Reload for next use
        interstitialAd.load()
    }

    override fun onAdClicked(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Interstitial ad clicked")
    }
}

Error Handling

All SDK errors are returned as CloudXError objects in listener callbacks with a code (error category), message (human-readable description), and optional cause (underlying exception).

Error Code Categories

RangeCategoryCommon Codes
100-199InitializationNOT_INITIALIZED, INVALID_APP_KEY, NO_ADAPTERS_FOUND
200-299NetworkNETWORK_ERROR, NETWORK_TIMEOUT, SERVER_ERROR
300-399Ad LoadingNO_FILL, INVALID_PLACEMENT, LOAD_TIMEOUT
400-499Ad DisplayAD_NOT_READY, AD_EXPIRED, DISPLAY_FAILED
600-699AdapterADAPTER_NO_FILL, ADAPTER_TIMEOUT

Advanced Features

Debug Logging

CloudX.setMinLogLevel(CloudXLogLevel.DEBUG)  // Enable debug logging
CloudX.setMinLogLevel(CloudXLogLevel.NONE)   // Disable all logging
Filter logcat with tag CloudX to see SDK logs.

Test Mode

// Enable Meta Audience Network test mode
import io.cloudx.adapter.meta.enableMetaAudienceNetworkTestMode
enableMetaAudienceNetworkTestMode(true)

Revenue Tracking

Set a revenueListener on any ad format to receive revenue callbacks when an ad impression is tracked. The CloudXAd object contains the revenue value in USD and the winning bidder name.
bannerAd.revenueListener = object : CloudXAdRevenueListener {
    override fun onAdRevenuePaid(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Revenue: ${cloudXAd.revenue} from ${cloudXAd.bidderName}")
    }
}
Works with all ad formats (banner, MREC, interstitial).

Privacy Compliance

The CloudX SDK supports GDPR and CCPA privacy compliance by reading standard IAB privacy strings from SharedPreferences. These values are typically set automatically by your Consent Management Platform (CMP) such as Google UMP, OneTrust, or Sourcepoint.

How It Works

The SDK automatically detects user location and reads consent signals:
  1. EU Users (GDPR): Checks TCF v2 consent for purposes 1-4 and vendor consent (CloudX Vendor ID: 1510)
  2. US Users (CCPA): Checks for sale/sharing opt-out signals
  3. Other Regions: No restrictions applied
When consent is denied or user opts out, the SDK removes PII from ad requests:
  • Advertising ID (GAID) is cleared
  • Geo coordinates (lat/lon) are removed
  • User key-values are not sent
  • Hashed user ID is excluded

Supported Privacy Keys

KeyStandardDescription
IABGPP_HDR_GppStringGPPGlobal Privacy Platform string (modern)
IABGPP_GppSIDGPPSection IDs (e.g., “2” for EU, “7” for US-National, “8” for US-CA)
IABTCF_TCStringTCF v2GDPR consent string (legacy)
IABTCF_gdprAppliesTCF v2Whether GDPR applies (1 = yes, 0 = no)
IABUSPrivacy_StringUS PrivacyCCPA privacy string (legacy, e.g., “1YNN”)
Note: The SDK prioritizes GPP (modern standard) over legacy TCF/US Privacy strings when both are available.

User Targeting

// Set hashed user ID for targeting
CloudX.setHashedUserId("hashed-user-id")

// Set custom user key-value pairs
CloudX.setUserKeyValue("age", "25")
CloudX.setUserKeyValue("gender", "male")
CloudX.setUserKeyValue("location", "US")

// Set custom app key-value pairs
CloudX.setAppKeyValue("app_version", "1.0.0")
CloudX.setAppKeyValue("user_level", "premium")

// Clear all custom key-values
CloudX.clearAllKeyValues()

Support

For support, contact [email protected]