Android SDK 2.0 - How to Integrate and Power Your Brand Community in Android Apps?

Integrating the Genuin Android SDK enables developers to:

  • Build a Community Media Network directly within their app
  • Accelerate development using pre-built modules (Core, UI, Camera, AI)
  • Enable SSO-based seamless authentication
  • Deliver personalized, contextual video feeds and placements
  • Unlock monetization capabilities via ad-supported experiences
  • Support deep linking, push notifications, and advanced targeting

Guide (Step-by-Step Integration)

1. SDK Overview

SDKDescriptionDependency
CoreIncludes the core functionality of the Genuin Ecosystem: Embeds and User authentication.com.begenuin:core:2.1.2
UIAdditional UI flows like comments, search, deep-links, notifications, group/community detail etc.com.begenuin:ui:2.1.2
CameraCamera flows for video content creation.com.begenuin:camera:2.1.2
AIAdditional flows for AI assisted community/group creation.com.begenuin:ai:2.1.2

2. Requirements

PlatformMinimum SDK VersionMinimum AGP VersionLanguageSupported OrientationsSupported Destinations
Android248.6.0Java/KotlinPortraitMobile

3. Installation

While the SDK officially requires a minimum version of 24, you can integrate it into older versions by adding the following code to your app-level manifest.

In AndroidManifext.xml
<uses-sdk
tools:overrideLibrary="com.begenuin.core, ..." />

Incorporate the necessary Genuin modules (Core, UI, Camera, AI) as detailed in the dependency overview.

Overriding the library for lower SDK versions may result in partial feature failures in specific scenarios.

1. Add repo details in project level gradle

Kotlin-settings.gradle.kts
dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  repositories {
    google()
    mavenCentral()
    maven {
      setUrl("https://jitpack.io")
    }
  }
}

Groovy-build.gradle
allprojects {
  repositories {
    google()
    mavenCentral()
    maven {
      setUrl("https://jitpack.io")
    }
  }

2. Add Dependencies in app level gradle

a. For core SDK

Kotlin-build.gradle.kts
val genuinVersion = "2.1.2"
implementation("com.begenuin:core:$genuinVersion")

Groovy-build.gradle
def genuinVersion = "2.1.2"
implementation "com.begenuin:core:$genuinVersion"

b. For UI SDK

Kotlin-build.gradle.kts
val genuinVersion = "2.1.2"
implementation("com.begenuin:core:$genuinVersion")
implementation("com.begenuin:ui:$genuinVersion")

Groovy-build.gradle
def genuinVersion = "2.1.2"
implementation "com.begenuin:core:$genuinVersion"
implementation "com.begenuin:ui:$genuinVersion"

c. For Camera SDK

Kotlin-build.gradle.kts
val genuinVersion = "2.1.2"
implementation("com.begenuin:core:$genuinVersion")
implementation("com.begenuin:ui:$genuinVersion")
implementation("com.begenuin:camera:$genuinVersion")

Groovy-build.gradle
def genuinVersion = "2.1.2"
implementation "com.begenuin:core:$genuinVersion"
implementation "com.begenuin:ui:$genuinVersion"
implementation "com.begenuin:camera:$genuinVersion"

d. For AI SDK

Kotlin-build.gradle.kts
val genuinVersion = "2.1.2"
implementation("com.begenuin:core:$genuinVersion")
implementation("com.begenuin:ui:$genuinVersion")
implementation("com.begenuin:camera:$genuinVersion")
implementation("com.begenuin:ai:$genuinVersion")

Groovy-build.gradle
def genuinVersion = "2.1.2"
implementation "com.begenuin:core:$genuinVersion"
implementation "com.begenuin:ui:$genuinVersion"
implementation "com.begenuin:camera:$genuinVersion"
implementation "com.begenuin:ai:$genuinVersion"

Maintain consistent versioning across all SDK modules using the same version (2.1.2).

Dependency Hierarchy

The SDK modules adhere to a modular dependency hierarchy, forming a chain where each successive component requires the preceding modules to function correctly:

ai ← camera ← ui ← core

Module Usage Guidelines

  • core - Foundation module; can be utilized independently and is required by all other modules.
  • ui - Inherits from core; requires core for integration.
  • camera - Inherits from ui and core; both must be included.
  • ai - Inherits from camera, ui, and core; requires all three upstream dependencies.

Adhere to the modular dependency hierarchy by including all required modules in the correct sequence when extending functionality beyond core.

3. Add permissions to AndroidManifest.xml

Mandatory Permissions

AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

The following permissions are optional and may be declared in your AndroidManifest.xml based on specific feature requirements:

a. UI SDK Permissions

  • Enable users to add Contacts as Members within Communities and Groups:
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS" />
  • Enabling Push Notifications for end users:
AndroidManifest.xml
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

b. Camera SDK Permissions

  • Enable users to Record and Create Video Content within the app using Camera and Microphone access:
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature
    android:name="android.hardware.camera"
    android:required="false" />
  • To allow user to Upload Content from their gallery
AndroidManifest.xml
//API level > 32
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
//API level <= 32
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" 
        android:maxSdkVersion="32"/>

c. AI SDK Permissions

  • Enable the creation of AI-Powered Communities tailored to the User Location:
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

4. Initialize SDK

YourApplication.kt
class YourApplication : Application() {
  override fun onCreate() {
    // For Prod Environment
    GenuinSDK.initSDK(this, "YOUR_API_KEY")
    // For QA Environment
    GenuinSDK.initSDK(this, "YOUR_API_KEY", genuinEnv = GenuinEnv.QA)
    }
}

YourActivity.kt
class YourActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // For Prod Environment
        GenuinSDK.initSDK(application, "YOUR_API_KEY")
        // For QA Environment
        GenuinSDK.initSDK(application, "YOUR_API_KEY", genuinEnv = GenuinEnv.QA)
    }
}

5. Customizing the Default Loader

The SDK utilizes Lottie animations for the default loading experience. To implement a custom loader, place your animation file named loader_mix.json within the res/raw directory. It is imperative to use the exact filename specified for proper asset overriding.

Within your AndroidManifest.xml, ensure the <application> tag is configured with android:allowBackup="false".

Monetization

  • To enable the Monetization add the below code:
AndroidManifest.xml
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />

It is mandatory to declare the use of the Advertising ID within the Google Play Console for your application.

Declaration Steps:

  • Access and log in to your Google Play Console.
  • Navigate to and select the target application.
  • Proceed to Policy and programs > App content.
  • Locate the Advertising ID section and select Manage.
  • Confirm by selecting “yes” to declare that the app utilizes the Advertising ID.
  • Complete the required questionnaire and submit your declaration.

Embed Integration (Kotlin)

Ensure you have completed the initial 3 installation steps to facilitate Carousel Embed implementation.

Embed Overview

Review the Carousel View specifications for mobile platforms.

1. Implementation via XML

activity_embed.xml
<LinearLayout
      android:id="@+id/llCarouselContainer"
      android:layout_width="match_parent"
      android:layout_height="300dp">
      <com.begenuin.core.ui.customview.embed.GenuinEmbedView
        android:id="@+id/carousel"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="16dp"
        app:interTileSpacing="12dp"
        app:leftInset="12dp"
        app:topInset="12dp"
        app:rightInset="12dp"
        app:bottomInset="12dp"
        app:tileCornerRadius="12dp"
        />
</LinearLayout>

The Carousel Container height must be set to a fixed value or match_parent. Utilizing wrap_content is prohibited as it will cause the carousel embed to fail to render.

EmbedActivity.kt (With SSO)
//This is Optional
val params = HashMap<String, Any>()
params["name"] = "John Doe"
params["email"] = "john.doe@begenuin.com"
params["nickname"] = "john"
params["mobile"] = "1XXXXXXXXXX"

//This is Optional
val contextualParams = HashMap<String, Any>()
contextualParams["page_context"] = pageContext
val geoJson = JSONObject()
geoJson.put("lat", XXXX.XXX)
geoJson.put("long", XXXX.XXX)
contextualParams["geo"] = geoJson.toString()
genuinEmbedView.apply {
            setEmbedParams(
               embedId = "YOUR_EMBED_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
               isShowProfileEnabled = false
            )
            setActivity(activityContext)
            setSSOToken("YOUR_SSO_TOKEN")
            setParams(params) // User specific params
            setInterTileSpacing(24) // values should be in pixels
            setInsets(
               left = 24, // values should be in pixels
               top = 24, // values should be in pixels
               right = 24, // values should be in pixels
               bottom = 24, // values should be in pixels
            )
            setTileCornerRadius(24) // values should be in pixels
            setContextualParams(contextualParams) // Contextual params
            load()
        }

EmbedActivity.kt (Without SSO)
//This is Optional
val contextualParams = HashMap<String, Any>()
contextualParams["page_context"] = pageContext
val geoJson = JSONObject()
geoJson.put("lat", XXXX.XXX)
geoJson.put("long", XXXX.XXX)
contextualParams["geo"] = geoJson.toString()
genuinEmbedView.apply {
            setEmbedParams(
               embedId = "YOUR_EMBED_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
               isShowProfileEnabled = false
            )
            setActivity(activityContext)
            setInterTileSpacing(24) // values should be in pixels
            setInsets(
               left = 24, // values should be in pixels
               top = 24, // values should be in pixels
               right = 24, // values should be in pixels
               bottom = 24, // values should be in pixels
            )
            setTileCornerRadius(24) // values should be in pixels
            setContextualParams(contextualParams) // Contextual params
            load()
        }

2. Load Carousel Embed Programmatically

activity_embed.xml
<LinearLayout
     android:id="@+id/llCarouselContainer"
     android:layout_width="match_parent"
     android:layout_height="300dp">           
</LinearLayout>

The Carousel Container height must be set to a fixed value or match_parent. Utilizing wrap_content is prohibited as it will cause the carousel embed to fail to render.

EmbedActivity.kt (With SSO)
val genuinEmbedView = GenuinEmbedView(context)
llCarouselContainer.addView(genuinEmbedView)

//This is Optional
val params = HashMap<String, Any>()
params["name"] = "John Doe"
params["email"] = "john.doe@begenuin.com"
params["nickname"] = "john"
params["mobile"] = "1XXXXXXXXXX"

//This is Optional
val contextualParams = HashMap<String, Any>()
contextualParams["page_context"] = pageContext
val geoJson = JSONObject()
geoJson.put("lat", XXXX.XXX)
geoJson.put("long", XXXX.XXX)
contextualParams["geo"] = geoJson.toString()
genuinEmbedView.apply {
            setEmbedParams(
               embedId = "YOUR_EMBED_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
               isShowProfileEnabled = false
            )
            setActivity(activityContext)
            setInterTileSpacing(24) // values should be in pixels
            setInsets(
               left = 24, // values should be in pixels
               top = 24, // values should be in pixels
               right = 24, // values should be in pixels
               bottom = 24, // values should be in pixels
            )
            setTileCornerRadius(24) // values should be in pixels
            setSSOToken("YOUR_SSO_TOKEN")
            setParams(params) // User specific params
            setContextualParams(contextualParams) // Contextual params
            load()
        }

EmbedActivity.kt (Without SSO)
//This is Optional
val contextualParams = HashMap<String, Any>()
contextualParams["page_context"] = pageContext
val geoJson = JSONObject()
geoJson.put("lat", XXXX.XXX)
geoJson.put("long", XXXX.XXX)
contextualParams["geo"] = geoJson.toString()

val genuinEmbedView = GenuinEmbedView(context)
llCarouselContainer.addView(genuinEmbedView)
genuinEmbedView.apply {
            setEmbedParams(
               embedId = "YOUR_EMBED_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
               isShowProfileEnabled = false
            )
            setActivity(activityContext)
            setInterTileSpacing(24) // values should be in pixels
            setInsets(
               left = 24, // values should be in pixels
               top = 24, // values should be in pixels
               right = 24, // values should be in pixels
               bottom = 24, // values should be in pixels
            )
            setTileCornerRadius(24) // values should be in pixels
            setContextualParams(contextualParams) // Contextual params
            load()
        }

To initialize an Embed, you must provide the activity context via setActivity(activityContext). For seamless authentication, invoke setSSOToken("YOUR_SSO_TOKEN") to facilitate Embed with SSO integration.

Configure EmbedParams according to your implementation requirements using the following parameters:

  1. embedId - The specific Embed ID designated for loading.
  2. uniqueId (Optional) - Facilitates displaying the same embedId across multiple screens or multiple times within a single screen.
  3. interactionDeepLink (Optional) - A deep link URL that overrides regular flows; interaction in full-screen view will redirect to this validated URL.
  4. isDirectDeepLinkEnabled (Optional) - Boolean (default: false); when enabled, redirects interactions to the specific video within the associated white-labelled app, ignoring any provided interactionDeepLink.

Implementation of isDirectDeepLinkEnabled requires a white-labelled domain and active Deep Link Handling within the target application.

5. isShowProfileEnabled (Optional) - Boolean (default: false); if enabled for authenticated users, renders the profile picture in the full-screen view for access to account settings and logout.

User-Specific Parameters (Optional)

a. name - String parameter utilized for signup and login flows.

b. mobile - String parameter utilized for signup and login flows.

c. email - String parameter utilized for signup and login flows.

d. nickname - String parameter; uses an existing Genuin ecosystem nickname if available, or generates a new one.

e. profile_image - String parameter; pass this to render the user's profile image within the SDK.

Contextual Parameters (Optional)

a. page_context - String parameter; provides context to load specifically tailored feeds.

b. lat - Float parameter; used within geo to load content based on latitude and context.

c. long - Float parameter; used within geo to load content based on longitude and context.

Design Configurations (Optional)

a. interTileSpacing - Defines spacing between carousel items (default: 8dp).

b. carouselInset - Edge insets for the carousel view (default: top: 8dp, left: 16dp, bottom: 0dp, right: 16dp).

c. tileCornerRadius - Corner radius for carousel items (default: 8dp).

1

3. Manage carousel videos auto-play

EmbedActivity.kt
override fun onResume() {
    super.onResume()
    genuinEmbedView.play()
}

override fun onPause() {
    genuinEmbedView.pause()
    super.onPause()
}

override fun onDestroy() {
    genuinEmbedView.release()
    super.onDestroy()
}

4. Asynchronous Embed Feed Loading

To facilitate asynchronous feed loading, utilize the loadAsync method with a callback implementation. This callback is triggered upon completion of the data fetch, returning a boolean flag to verify operation success and the retrieval of a non-empty feed.

activity_full_embed.xml
genuinEmbedView.loadAsync {
  success ->
    if (success) { 
      binding.genuinEmbedView.visibility = View.VISIBLE
    }
}

Full Screen Embed

activity_full_embed.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

Put below code in FullEmbedActivity.kt file

FullEmbedActivity.kt
import com.begenuin.core.ui.fragment.FeedEmbedFragment

class FullEmbedActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_full_embed)

        //This is Optional
        val params = HashMap<String, Any>()
        params["name"] = "John Doe"
        params["email"] = "john.doe@begenuin.com"
        params["nickname"] = "john"
        params["mobile"] = "1XXXXXXXXXX"

        //This is Optional
        val contextualParams = HashMap<String, Any>()
        contextualParams["page_context"] = pageContext
        val geoJson = JSONObject()
        geoJson.put("lat", XXXX.XXX)
        geoJson.put("long", XXXX.XXX)
        contextualParams["geo"] = geoJson.toString()

        val feedEmbedFragment = FeedEmbedFragment.newInstance(
               embedId = "YOUR_EMBED_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
               isShowProfileEnabled = false,
               ssoToken = "YOUR_SSO_TOKEN",
               params = params // User specific params,
               contextualParams = contextualParams
            )
        feedEmbedFragment.let {
            supportFragmentManager.beginTransaction()
                .add(R.id.frameLayout, it)
                .addToBackStack("EmbedFullFeed").commit()
        }
    }
}

Configure FullScreenEmbed by providing the following arguments:

  1. embedId - The specific Embed ID designated for loading.
  2. uniqueId (Optional) - Facilitates displaying the same embedId across multiple screens or multiple times within a single screen.
  3. interactionDeepLink (Optional) - A deep link URL that overrides regular flows; interaction in full-screen view will redirect to this validated URL. Incorrect URLs will result in redirection failure.
  4. isDirectDeepLinkEnabled (Optional) - Boolean (default: false); when enabled, redirects interactions to the specific video within the associated white-labelled app, ignoring any provided interactionDeepLink.

Implementation of isDirectDeepLinkEnabled requires a white-labelled domain and active Deep Link Handling within the target application.

5. isShowProfileEnabled (Optional) - Boolean (default: false); if enabled for authenticated users, renders the profile picture in the full-screen view for access to account settings and logout.

6. ssoToken (Optional) - Pass "YOUR_SSO_TOKEN" to facilitate seamless auto-login and Embed with SSO integration.

User-Specific Parameters (Optional)

a. name - String parameter utilized for signup/login flows.

b. mobile - String parameter utilized for signup/login flows.

c. email - String parameter utilized for signup/login flows.

d. nickname - String parameter; uses an existing Genuin ecosystem nickname if available, or generates a new one.

e. profile_image - String parameter; pass this to render the user's profile image within the SDK.

Contextual Parameters (Optional)

a. page_context - String parameter; provides context to load specifically tailored feeds.

b. lat - Float parameter; used within geo to load content based on latitude and context.

c. long - Float parameter; used within geo to load content based on longitude and context.

Standard Wall Embed

Implement the code below in the activity_standard_wall_embed.xml file:

activity_standard_wall_embed.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

Put below code in StandardWallEmbedActivity.kt file

StandardWallEmbedActivity.kt
import com.begenuin.core.ui.fragment.FeedEmbedFragment

class StandardWallEmbedActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_standard_wall_embed)

        //This is Optional
        val params = HashMap<String, Any>()
        params["name"] = "John Doe"
        params["email"] = "john.doe@begenuin.com"
        params["nickname"] = "john"
        params["mobile"] = "1XXXXXXXXXX"

        //This is Optional
        val contextualParams = HashMap<String, Any>()
        contextualParams["page_context"] = pageContext
        val geoJson = JSONObject()
        geoJson.put("lat", XXXX.XXX)
        geoJson.put("long", XXXX.XXX)
        contextualParams["geo"] = geoJson.toString()

        val feedEmbedFragment = FeedEmbedFragment.newInstance(
               embedId = "YOUR_EMBED_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
               isShowProfileEnabled = false,
               ssoToken = "YOUR_SSO_TOKEN",
               params = params, // User specific params
               contextualParams = contextualParams // Contextual params
            )

        feedEmbedFragment.let {
            supportFragmentManager.beginTransaction()
                .add(R.id.frameLayout, it)
                .addToBackStack("EmbedStandardWallFeed").commit()
        }
    }
}

Configure StandardWallEmbed according to your implementation requirements using the following parameters:

  1. embedId - The specific Embed ID designated for loading.
  2. uniqueId (Optional) - Facilitates displaying the same embedId across multiple screens or multiple times within a single screen.
  3. isShowProfileEnabled (Optional) - Boolean (default: false); if enabled for authenticated users, renders the profile picture in the full-screen view for access to account settings and logout.
  4. isDirectDeepLinkEnabled (Optional) - Boolean (default: false); when enabled, redirects interactions to the specific video within the associated white-labelled app, ignoring any provided interactionDeepLink.

Implementation of isDirectDeepLinkEnabled requires a white-labelled domain and active Deep Link Handling within the target application.

5. isShowProfileEnabled (Optional) - Boolean (default: false); if enabled for authenticated users, renders the profile picture in the full-screen view for access to account settings and logout.

6. ssoToken (Optional) - Pass "YOUR_SSO_TOKEN" to facilitate seamless auto-login and Embed with SSO integration.

User-Specific Parameters (Optional)

a. name - String parameter utilized for signup and login flows.

b. mobile - String parameter utilized for signup and login flows.

c. email - String parameter utilized for signup and login flows.

d. nickname - String parameter; uses an existing Genuin ecosystem nickname if available, or generates a new one.

e. profile_image - String parameter; pass this to render the user's profile image within the SDK.

Contextual Parameters (Optional)

a. page_context - String parameter; provides context to load specifically tailored feeds.

b. lat - Float parameter; used within geo to load content based on latitude and context.

c. long - Float parameter; used within geo to load content based on longitude and context.

Embed in Compose

Ensure you have completed the initial 3 installation steps to facilitate Carousel Embed implementation.

Carousel Embed

Review the Carousel View specifications for mobile platforms.

Basic Embed
@Composable
fun CarouselComposeViewWrapper(
    modifier: Modifier = Modifier,
    embedId: String,
)
{
    val context = LocalContext.current
    val activity = context as? Activity?: throw IllegalStateException("Context is not an Activity!")

    AndroidView(
        modifier = modifier,
        factory = { viewContext ->
            // Creates view
            GenuinEmbedView(viewContext)
                .setEmbedParams(
                    embedId,
                )
                .setActivity(activity)
                .load()
        }
    )
}

Embed with Customization & SSO
@Composable
fun CarouselComposeViewWrapper(
    modifier: Modifier = Modifier,
    embedId: String,
    uniqueId: String = "",
    ssoToken: String = "",
    isDirectDeepLinkEnabled: Boolean = false,
    isShowProfileEnabled: Boolean = false,
    interTileSpacing: Int = 24,
    tileCornerRadius: Int = 24,
    leftInsets: Int = 24,
    topInsets: Int = 24,
    rightInsets: Int = 24,
    bottomInsets: Int = 24,
    params: HashMap<String, Any>? = null,
    contextualParams: HashMap<String, Any>? = null,
) 
{
    val context = LocalContext.current
    val activity =
        context as? Activity ?: throw IllegalStateException("Context is not an Activity!")

    AndroidView(
        modifier = modifier,
        factory = { viewContext ->
            // Creates view
            GenuinEmbedView(viewContext)
                .setEmbedParams(
                    embedId = embedId,
                    uniqueId = uniqueId,
                    isShowProfileEnabled = isShowProfileEnabled,
                    isDirectDeepLinkEnabled = isDirectDeepLinkEnabled
                )
                .setActivity(activity)
                .setInterTileSpacing(interTileSpacing) // values should be in pixels
                .setInsets(
                    left = leftInsets, // values should be in pixels
                    top = topInsets, // values should be in pixels
                    right = rightInsets, // values should be in pixels
                    bottom = bottomInsets, // values should be in pixels
                )
                .setTileCornerRadius(tileCornerRadius)// values should be in pixels
                .setSSOToken(ssoToken)
                .setParams(params)
                .setContextualParams(contextualParams)
                .load()
        }
    )
}

The Carousel Container height must be set to a fixed value or match_parent. Utilizing wrap_content is prohibited as it will cause the carousel embed to fail to render.

Example Implementation

Basic Embed
CarouselComposeViewWrapper(
        embedId = "YOUR_EMBED_ID",
        modifier = Modifier.fillMaxWidth().height(400.dp) // Height can be dynamic
    )

Embed With Customization and SSO
//This is Optional
    val params = HashMap<String, Any>()
    params["name"] = "John Doe"
    params["email"] = "john.doe@begenuin.com"
    params["nickname"] = "john"
    params["mobile"] = "1XXXXXXXXXX"

    //This is Optional
    val contextualParams = HashMap<String, Any>()
    contextualParams["page_context"] = "YOUR_CONTEXT_VALUE"
    val geoJson = JSONObject()
    geoJson.put("lat", XXXX.XXX) // value in double
    geoJson.put("long", XXXX.XXX) // value in double
    contextualParams["geo"] = geoJson.toString()

    CarouselComposeViewWrapper(
        embedId = "YOUR_EMBED_ID",
        uniqueId = "UNIQUE_ID",
        ssoToken = "YOUR_SSO_TOKEN",
        isShowProfileEnabled = false,
        isDirectDeepLinkEnabled = false,
        tileCornerRadius = 32,
        leftInsets = 32,
        topInsets = 32,
        rightInsets = 32,
        bottomInsets = 32,
        params = params,
        contextualParams = contextualParams,
        modifier = Modifier.fillMaxWidth().height(400.dp)
    )

For seamless authentication, invoke setSSOToken("YOUR_SSO_TOKEN") to facilitate Embed with SSO integration.

Configure EmbedParams according to your implementation requirements using the following parameters:

  1. embedId - The specific Embed ID designated for loading.
  2. uniqueId (Optional) - Facilitates displaying the same embedId across multiple screens or multiple times within a single screen.
  3. interactionDeepLink (Optional) - A deep link URL that overrides regular flows; interaction in full-screen view will redirect to this validated URL.
  4. isDirectDeepLinkEnabled (Optional) - Boolean (default: false); when enabled, redirects interactions to the specific video within the associated white-labelled app, ignoring any provided interactionDeepLink.

Implementation of isDirectDeepLinkEnabled requires a white-labelled domain and active Deep Link Handling within the target application.

5. isShowProfileEnabled (Optional) - Boolean (default: false); if enabled for authenticated users, renders the profile picture in the full-screen view for access to account settings and logout.

User-Specific Parameters (Optional)

a. name - String parameter utilized for signup and login flows.

b. mobile - String parameter utilized for signup and login flows.

c. email - String parameter utilized for signup and login flows.

d. nickname - String parameter; uses an existing Genuin ecosystem nickname if available, or generates a new one.

e. profile_image - String parameter; pass this to render the user's profile image within the SDK.

Contextual Parameters (Optional)

a. page_context - String parameter; provides context to load specifically tailored feeds.

b. lat - Float parameter; used within geo to load content based on latitude and context.

c. long - Float parameter; used within geo to load content based on longitude and context.

Design Configurations (Optional)

a. interTileSpacing - Defines spacing between carousel items (default: 8dp).

b. carouselInset - Edge insets for the carousel view (default: top: 8dp, left: 16dp, bottom: 0dp, right: 16dp).

c. tileCornerRadius - Corner radius for carousel items (default: 8dp).

1

Standard Wall Embed

To implement a standard wall, the hosting parent activity must inherit from FragmentActivity.

Basic Embed
@Composable
fun StandardWallComposeFragmentWrapper(
    modifier: Modifier = Modifier,
    embedId: String,
    ) {
    val context = LocalContext.current
    val activity = context as? FragmentActivity
        ?: throw IllegalStateException("Context is not a FragmentActivity")
    AndroidView(
        factory = { ctx ->
            FragmentContainerView(ctx).apply {
                id = View.generateViewId()

                // Load fragment just once
                if (activity.supportFragmentManager.findFragmentById(id) == null) {
                    activity.supportFragmentManager.beginTransaction()
                        .replace(id, FeedEmbedFragment.newInstance(embedId = embedId))
                        .commit()
                }
            }
        },
        modifier = modifier
    )
}

Embed With Customization and SSO
@Composable
fun StandardWallComposeFragmentWrapper(
    modifier: Modifier = Modifier,
    embedId: String,
    uniqueId: String = "",
    ssoToken: String = "",
    isDirectDeepLinkEnabled: Boolean = false,
    isShowProfileEnabled: Boolean = false,
    params: HashMap<String, Any>? = null,
    contextualParams: HashMap<String, Any>? = null,
) {
    val context = LocalContext.current
    val activity = context as? FragmentActivity
        ?: throw IllegalStateException("Context is not a FragmentActivity")
    AndroidView(
        factory = { ctx ->
            FragmentContainerView(ctx).apply {
                id = View.generateViewId()

                // Load fragment just once
                if (activity.supportFragmentManager.findFragmentById(id) == null) {
                    val feedEmbedFragment = FeedEmbedFragment.newInstance(
                        embedId = embedId,
                        uniqueId = uniqueId,
                        ssoToken = ssoToken,
                        isDirectDeepLinkEnabled = isDirectDeepLinkEnabled,
                        isShowProfileEnabled = isShowProfileEnabled,
                        params = params,
                        contextualParams = contextualParams
                    )
                    activity.supportFragmentManager.beginTransaction()
                        .replace(id, feedEmbedFragment)
                        .commit()
                }
            }
        },
        modifier = modifier
    )
}

Example usage

Basic Embed
StandardWallComposeFragmentWrapper(
                            embedId = "YOUR_EMBED_ID",
                            modifier = Modifier.fillMaxSize()
                        )

Embed with Customization and SSO
//This is Optional
    val params = HashMap<String, Any>()
    params["name"] = "John Doe"
    params["email"] = "john.doe@begenuin.com"
    params["nickname"] = "john"
    params["mobile"] = "1XXXXXXXXXX"

    //This is Optional
    val contextualParams = HashMap<String, Any>()
    contextualParams["page_context"] = "YOUR_CONTEXT_VALUE"
    val geoJson = JSONObject()
    geoJson.put("lat", XXXX.XXX) // value in double
    geoJson.put("long", XXXX.XXX) // value in double
    contextualParams["geo"] = geoJson.toString()

    StandardWallComposeFragmentWrapper(
        embedId = "YOUR_EMBED_ID",
        uniqueId = "UNIQUE_ID",
        ssoToken = "YOUR_SSO_TOKEN",
        isShowProfileEnabled = false,
        isDirectDeepLinkEnabled = false,
        params = params,
        contextualParams = contextualParams,
        modifier = Modifier.fillMaxSize()
    )

Configure StandardWallEmbed by providing the following arguments:

  1. embedId - The specific Embed ID designated for loading.
  2. uniqueId (Optional) - Facilitates displaying the same embedId across multiple screens or multiple times within a single screen.
  3. isShowProfileEnabled (Optional) - Boolean (default: false); if enabled for authenticated users, renders the profile picture in the full-screen view for access to account settings and logout.
  4. isDirectDeepLinkEnabled (Optional) - Boolean (default: false); when enabled, redirects interactions to the specific video within the associated white-labelled app, ignoring any provided interactionDeepLink.

Implementation of isDirectDeepLinkEnabled requires a white-labelled domain and active Deep Link Handling within the target application.

5. isShowProfileEnabled (Optional) - Boolean (default: false); if enabled for authenticated users, renders the profile picture in the full-screen view for access to account settings and logout.

6. ssoToken (Optional) - Pass "YOUR_SSO_TOKEN" to facilitate seamless auto-login and Embed with SSO integration.

User-Specific Parameters (Optional)

a. name - String parameter utilized for signup/login flows.

b. mobile - String parameter utilized for signup/login flows.

c. email - String parameter utilized for signup/login flows.

d. nickname - String parameter; uses an existing Genuin ecosystem nickname if available, or generates a new one.

e. profile_image - String parameter; pass this to render the user's profile image within the SDK.

Contextual Parameters (Optional)

a. page_context - String parameter; provides context to load specifically tailored feeds.

b. lat - Float parameter; used within geo to load content based on latitude and context.

c. long - Float parameter; used within geo to load content based on longitude and context.

Placement Integration

1. Implementation via XML

activity_placement.xml
<LinearLayout
      android:id="@+id/llPlacementContainer"
      android:layout_width="match_parent"
      android:layout_height="300dp">
      <com.begenuin.core.ui.customview.embed.GenuinPlacementView
        android:id="@+id/carousel"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="16dp"
        app:interTileSpacing="12dp"
        app:leftInset="12dp"
        app:topInset="12dp"
        app:rightInset="12dp"
        app:bottomInset="12dp"
        app:tileCornerRadius="12dp"
        />
</LinearLayout>

The Placement Container height must be set to a fixed value or match_parent. Utilizing wrap_content is prohibited as it will cause the placement to fail to render.

PlacementActivity.kt (With SSO)
//This is Optional
val params = HashMap<String, Any>()
params["name"] = "John Doe"
params["email"] = "john.doe@begenuin.com"
params["nickname"] = "john"
params["mobile"] = "1XXXXXXXXXX"

//This is Optional
val geoJson = JSONObject()
geoJson.put("lat", XX.XXX)
geoJson.put("long",  XX.XXX)
geoJson.put("radius_limit", <RADIUS_LIMIT>)
val placeJson = JSONObject()
placeJson.put("country", "<COUNTRY_CODE>")
placeJson.put("state", "<STATE>")
placeJson.put("city", "<CITY>")
placeJson.put("zipcode", <ZIP>)

val userSegmentsJson = JSONObject()
userSegmentsJson.put("age", "<AGE>")
userSegmentsJson.put("min_age", "<MIN_AGE>")
userSegmentsJson.put("max_age", "<MAX_AGE>")
userSegmentsJson.put("segment", "<SEGMENT>")
userSegmentsJson.put("gender", "M/F/O")
userSegmentsJson.put("race", "<RACE>")
val contextualParams = HashMap<String, Any>()
contextualParams["page_context"] = "<PAGE_CONTEXT>"
contextualParams["geo"] = geoJson.toString()
contextualParams["place"] = placeJson.toString()
contextualParams["time"] = <timestamp>
contextualParams["user_segments"] = userSegmentsJson.toString()
contextualParams["url"] = "https://url/"
contextualParams["brands_ids"] = JSONArray(arrayListOf(brandId1, brandId2))
contextualParams["community_ids"] = JSONArray(arrayListOf("comm_id1","comm_id2"))
contextualParams["loop_ids"] = JSONArray(arrayListOf("loop_id1", "loop_id2"))
contextualParams["user_interest"] = JSONArray(arrayListOf(""))
contextualParams["posted_by_user_ids"] = JSONArray(arrayListOf("user_id1", "user_id2"))
contextualParams["previous_page_context"] = "<PREVIOUS_PAGE_CONTEXT>"
contextualParams["user_context"] = "<CONTEXT>"
genuinPlacementView.apply {
            setPlacementParams(
               placementId = "YOUR_PLACEMENT_ID", 
               styleId = "YOUR_STYLE_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
            )
            setActivity(activityContext)
            setSSOToken("YOUR_SSO_TOKEN")
            setParams(params) // User specific params
            setInterTileSpacing(24) // values should be in pixels
            setInsets(
               left = 24, // values should be in pixels
               top = 24, // values should be in pixels
               right = 24, // values should be in pixels
               bottom = 24, // values should be in pixels
            )
            setTileCornerRadius(24) // values should be in pixels
            setContextualParams(contextualParams) // Contextual params
            load()
        }

PlacementActivity.kt (Without SSO)
//This is Optional
val geoJson = JSONObject()
geoJson.put("lat", XX.XXX)
geoJson.put("long",  XX.XXX)
geoJson.put("radius_limit", <RADIUS_LIMIT>)
val placeJson = JSONObject()
placeJson.put("country", "<COUNTRY_CODE>")
placeJson.put("state", "<STATE>")
placeJson.put("city", "<CITY>")
placeJson.put("zipcode", <ZIP>)
val userSegmentsJson = JSONObject()
userSegmentsJson.put("age", "<AGE>")
userSegmentsJson.put("min_age", "<MIN_AGE>")
userSegmentsJson.put("max_age", "<MAX_AGE>")
userSegmentsJson.put("segment", "<SEGMENT>")
userSegmentsJson.put("gender", "M/F/O")
userSegmentsJson.put("race", "<RACE>")
val contextualParams = HashMap<String, Any>()
contextualParams["page_context"] = "<PAGE_CONTEXT>"
contextualParams["geo"] = geoJson.toString()
contextualParams["place"] = placeJson.toString()
contextualParams["time"] = <timestamp>
contextualParams["user_segments"] = userSegmentsJson.toString()
contextualParams["url"] = "https://url/"
contextualParams["brands_ids"] = JSONArray(arrayListOf(brandId1, brandId2))
contextualParams["community_ids"] = JSONArray(arrayListOf("comm_id1","comm_id2"))
contextualParams["loop_ids"] = JSONArray(arrayListOf("loop_id1", "loop_id2"))
contextualParams["user_interest"] = JSONArray(arrayListOf(""))
contextualParams["posted_by_user_ids"] = JSONArray(arrayListOf("user_id1", "user_id2"))
contextualParams["previous_page_context"] = "<PREVIOUS_PAGE_CONTEXT>"
contextualParams["user_context"] = "<CONTEXT>"
genuinPlacementView.apply {
            setPlacementParams(
               placementId = "YOUR_PLACEMENT_ID", 
               styleId = "YOUR_STYLE_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
            )
            setActivity(activityContext)
            setInterTileSpacing(24) // values should be in pixels
            setInsets(
               left = 24, // values should be in pixels
               top = 24, // values should be in pixels
               right = 24, // values should be in pixels
               bottom = 24, // values should be in pixels
            )
            setTileCornerRadius(24) // values should be in pixels
            setContextualParams(contextualParams) // Contextual params
            load()
        }

2. Load Placement Programmatically

activity_placement.xml
<LinearLayout
     android:id="@+id/llPlacementContainer"
     android:layout_width="match_parent"
     android:layout_height="300dp">           
</LinearLayout>

The Placement Container height must be set to a fixed value or match_parent. Utilizing wrap_content is prohibited as it will cause the placement to fail to render.

PlacementActivity.kt (With SSO)
val genuinPlacementView = GenuinPlacementView(context)
llPlacementContainer.addView(genuinPlacementView)

//This is Optional
val params = HashMap<String, Any>()
params["name"] = "John Doe"
params["email"] = "john.doe@begenuin.com"
params["nickname"] = "john"
params["mobile"] = "1XXXXXXXXXX"

//This is Optional
val geoJson = JSONObject()
geoJson.put("lat", XX.XXX)
geoJson.put("long",  XX.XXX)
geoJson.put("radius_limit", <RADIUS_LIMIT>)
val placeJson = JSONObject()
placeJson.put("country", "<COUNTRY_CODE>")
placeJson.put("state", "<STATE>")
placeJson.put("city", "<CITY>")
placeJson.put("zipcode", <ZIP>)
val userSegmentsJson = JSONObject()
userSegmentsJson.put("age", "<AGE>")
userSegmentsJson.put("min_age", "<MIN_AGE>")
userSegmentsJson.put("max_age", "<MAX_AGE>")
userSegmentsJson.put("segment", "<SEGMENT>")
userSegmentsJson.put("gender", "M/F/O")
userSegmentsJson.put("race", "<RACE>")
val contextualParams = HashMap<String, Any>()
contextualParams["page_context"] = "<PAGE_CONTEXT>"
contextualParams["geo"] = geoJson.toString()
contextualParams["place"] = placeJson.toString()
contextualParams["time"] = <timestamp>
contextualParams["user_segments"] = userSegmentsJson.toString()
contextualParams["url"] = "https://url/"
contextualParams["brands_ids"] = JSONArray(arrayListOf(brandId1, brandId2))
contextualParams["community_ids"] = JSONArray(arrayListOf("comm_id1","comm_id2"))
contextualParams["loop_ids"] = JSONArray(arrayListOf("loop_id1", "loop_id2"))
contextualParams["user_interest"] = JSONArray(arrayListOf(""))
contextualParams["posted_by_user_ids"] = JSONArray(arrayListOf("user_id1", "user_id2"))
contextualParams["previous_page_context"] = "<PREVIOUS_PAGE_CONTEXT>"
contextualParams["user_context"] = "<CONTEXT>"
genuinPlacementView.apply {
            setPlacementParams(
               placementId = "YOUR_PLACEMENT_ID", 
               styleId = "YOUR_STYLE_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
            )
            setActivity(activityContext)
            setInterTileSpacing(24) // values should be in pixels
            setInsets(
               left = 24, // values should be in pixels
               top = 24, // values should be in pixels
               right = 24, // values should be in pixels
               bottom = 24, // values should be in pixels
            )
            setTileCornerRadius(24) // values should be in pixels
            setSSOToken("YOUR_SSO_TOKEN")
            setParams(params) // User specific params
            setContextualParams(contextualParams) // Contextual params
            load()
        }

PlacementActivity.kt (Without SSO)
//This is Optional
val geoJson = JSONObject()
geoJson.put("lat", XX.XXX)
geoJson.put("long",  XX.XXX)
geoJson.put("radius_limit", <RADIUS_LIMIT>)
val placeJson = JSONObject()
placeJson.put("country", "<COUNTRY_CODE>")
placeJson.put("state", "<STATE>")
placeJson.put("city", "<CITY>")
placeJson.put("zipcode", <ZIP>)
val userSegmentsJson = JSONObject()
userSegmentsJson.put("age", "<AGE>")
userSegmentsJson.put("min_age", "<MIN_AGE>")
userSegmentsJson.put("max_age", "<MAX_AGE>")
userSegmentsJson.put("segment", "<SEGMENT>")
userSegmentsJson.put("gender", "M/F/O")
userSegmentsJson.put("race", "<RACE>")
val contextualParams = HashMap<String, Any>()
contextualParams["page_context"] = "<PAGE_CONTEXT>"
contextualParams["geo"] = geoJson.toString()
contextualParams["place"] = placeJson.toString()
contextualParams["time"] = <timestamp>
contextualParams["user_segments"] = userSegmentsJson.toString()
contextualParams["url"] = "https://url/"
contextualParams["brands_ids"] = JSONArray(arrayListOf(brandId1, brandId2))
contextualParams["community_ids"] = JSONArray(arrayListOf("comm_id1","comm_id2"))
contextualParams["loop_ids"] = JSONArray(arrayListOf("loop_id1", "loop_id2"))
contextualParams["user_interest"] = JSONArray(arrayListOf(""))
contextualParams["posted_by_user_ids"] = JSONArray(arrayListOf("user_id1", "user_id2"))
contextualParams["previous_page_context"] = "<PREVIOUS_PAGE_CONTEXT>"
contextualParams["user_context"] = "<CONTEXT>"
val genuinPlacementView = GenuinPlacementView(context)
llPlacementContainer.addView(genuinPlacementView)
genuinPlacementView.apply {
            setPlacementParams(
               placementId = "YOUR_PLACEMENT_ID", 
               styleId = "YOUR_STYLE_ID", 
               uniqueId="UNIQUE_ID",
               interactionDeepLink = "YOUR_DEEPLINK",
               isDirectDeepLinkEnabled = false,
            )
            setActivity(activityContext)
            setInterTileSpacing(24) // values should be in pixels
            setInsets(
               left = 24, // values should be in pixels
               top = 24, // values should be in pixels
               right = 24, // values should be in pixels
               bottom = 24, // values should be in pixels
            )
            setTileCornerRadius(24) // values should be in pixels
            setContextualParams(contextualParams) // Contextual params
            load()
        }

To initialize a Placement, you must provide the activity context via setActivity(activityContext). For seamless authentication, invoke setSSOToken("YOUR_SSO_TOKEN") to facilitate Placement with SSO integration.

Configure PlacementParams according to your implementation requirements using the following parameters:

  1. placementId - The specific Placement ID designated for loading.
  2. styleId - The specific Style ID designated for loading.
  3. uniqueId (Optional) - Facilitates displaying the same placement across multiple screens or multiple times within a single screen.
  4. interactionDeepLink (Optional) - A deep link URL that overrides regular flows; interaction in full-screen view will redirect to this validated URL. Incorrect URLs will result in redirection failure.
  5. isDirectDeepLinkEnabled (Optional) - Boolean (default: false); when enabled, redirects interactions to the specific video within the associated white-labelled app, ignoring any provided interactionDeepLink.

Implementation of isDirectDeepLinkEnabled requires a white-labelled domain and active Deep Link Handling within the target application.

User-Specific Parameters (Optional)

a. name - String parameter utilized for signup and login flows.

b. mobile - String parameter utilized for signup and login flows.

c. email - String parameter utilized for signup and login flows.

d. nickname - String parameter; uses an existing Genuin ecosystem nickname if available, or generates a new one.

e. profile_image - String parameter; pass this to render the user's profile image within the SDK.

Contextual Parameters (Optional)

a. page_context - String parameter; provides context to load specifically tailored feeds.

b. lat - Float parameter; used within geo to load content based on latitude and context.

c. long - Float parameter; used within geo to load content based on longitude and context.

Design Configurations (Optional)

a. interTileSpacing - Defines spacing between carousel items (default: 8dp).

b. Inset - Edge insets for the placement view (default: top: 8dp, left: 16dp, bottom: 0dp, right: 16dp).

c. tileCornerRadius - Corner radius for carousel items (default: 8dp).

1

3. Carousel Auto-Play Management

PlacementActivity.kt
override fun onResume() {
    super.onResume()
    genuinPlacementView.play()
}
override fun onPause() {
    genuinPlacementView.pause()
    super.onPause()
}
override fun onDestroy() {
    genuinPlacementView.release()
    super.onDestroy()
}

4. Asynchronous Placement Feed Loading

To facilitate asynchronous feed loading, utilize the loadAsync method with a callback implementation. This callback is triggered upon completion of the data fetch, returning a boolean flag to verify operation success and the retrieval of a non-empty feed.

activity_full_placement.xml
genuinPlacementView.loadAsync {
  success ->
    if (success) { 
      binding.genuinPlacementView.visibility = View.VISIBLE
    }
}

Authentication: Auto Login Approach

To implement Auto Login within the SDK, invoke the following method upon successful user authentication within your application:

This method is redundant if Embed/Placement with SSO has already been integrated.

YourClass.kt
GenuinSDK.ssoLogin(context = "YOUR_CONTEXT", ssoToken = "YOUR_SSO_TOKEN")

Configuration Options (Optional)

Configure your implementation by providing the following optional arguments:

YourActivity.kt
val params = HashMap<String, Any>()
params["name"] = "John Doe"
params["email"] = "john.doe@begenuin.com"
params["nickname"] = "john"
params["mobile"] = "1XXXXXXXXXX"
GenuinSDK.ssoLogin(
    context = "YOUR_CONTEXT", 
    ssoToken = "YOUR_SSO_TOKEN",
    params = params //This is optional
)

User-Specific Parameters (Optional)

  1. a. name - String parameter utilized for signup/login flows.
  2. b. mobile - String parameter utilized for signup/login flows.
  3. c. email - String parameter utilized for signup/login flows.
  4. d. nickname - String parameter; uses an existing Genuin ecosystem nickname if available, or generates a new one.
  5. e. profile_image - String parameter; pass this to render the user's profile image within the SDK.

Optional Callback

YourClass.kt
GenuinSDK.ssoLogin(
    context = "YOUR_CONTEXT", 
    ssoToken = "YOUR_SSO_TOKEN",
    params = "YOUR_OPTIONAL_PARAMS",
    onComplete = {
        isSuccess: Boolean ->
        //Manage callback for Login Completion
    }
)
YourClass.java
GenuinSDK.INSTANCE.ssoLogin(
        "CONTEXT",
        "SSO-TOKEN",
        "OPTIONAL-PARAMETERS",
        (isSuccess) -> {
            //Manage callback for Login Completion
            return Unit.INSTANCE;
        }
);

Authentication: Custom Login Approach

To implement a bespoke login process tailored to specific application requirements, adhere to the following procedural steps:

YourActivity.kt
GenuinSDK.registerInterface(object : GenuinInterface {
            override fun onLogin(context: Activity) {
                /*
                    This callback will be triggered when user attempts to login
                    within one of the Genuin embeds. Application login process
                    should be initiated here.
                    When your application's auth process is successfully completed,
                    call GenuinSDK.ssoLogin(context, "ssoToken") to automatically
                    manage SDK login.
                */
            }
})

Logout Implementation: Auto Login Approach

To handle user logout within the SDK, invoke the following method upon successful termination of the user session in your application:

index.html
GenuinSDK.ssoLogout(context = “YOUR_CONTEXT”)

Optional Callback

YourClass.kt
GenuinSDK.ssoLogout(
    context = "YOUR_CONTEXT",
    onComplete = {
        isSuccess: Boolean ->
        //Manage callback for Logout Completion
    }
)

YourClass.java
GenuinSDK.INSTANCE.ssoLogout(
        "CONTEXT",
        (isSuccess) -> {
            //Manage callback for Logout Completion
            return Unit.INSTANCE;
        }
);

Deep Link Handling

Ensure you have completed the initial 3 installation steps to facilitate Deep Link integration.

Prerequisites:

  1. Establish a white-labelled domain for your community by following the designated procedural steps.
  2. Adhere to the Android App Link specifications to incorporate deep linking functionality within your application.

The host parameter must be configured as "YOUR_WHITE-LABELLED_DOMAIN".

3. Upon successful deep link configuration, verify that your assetlinks.json file conforms to the structure below:

assetlinks.json
[{"target":{"package_name":"YOUR_PACKAGE_NAME","sha256_cert_fingerprints":["YOUR_KEYSTORE'S_SHA256_FINGERPRINTS"],"namespace":"android_app"},"relation":["delegate_permission/common.handle_all_urls"]}]

4. Deploy the assetlinks.json file to your white-labelled domain at the following location: https://YOUR_WHITE-LABELLED_DOMAIN/.well-known/assetlinks.json

To incorporate Deep Link Handling within your application:

You may invoke the method specified below immediately upon receiving a deep link, or alternatively, defer the call until the application's home screen has fully initialized.

YourCustomActivity.kt
GenuinSDK.handleDeepLink(context = "YOUR_CONTEXT", intent = "YOUR_DEEPLINK_ACTIVITY_INTNET")

This method must be invoked upon each receipt of a deep link; the SDK will automatically process Genuin-specific deep links while disregarding all others.

LinkOutInterceptor (Optional)

To facilitate the interception of external link interactions, implement the LinkOutInterceptor utilizing the following configuration:

YourActivity.kt
GenuinSDK.registerLinkOutInterceptor(object : GenuinLinkOutInterceptor {
    override fun onLinkOutIntercept(intent: Intent, context: Activity) {
                /*
                    This callback will be triggered when user clicks on linkouts 
                    from any video and if it is found that link is handled by your app.
                    You will receive whole intent data same as we will be receiving while 
                    deeplink is clicked so you can handle the deeplink redirection from here
                    in your app
                */
    }
})

Push Notification Management

Ensure you have completed the initial 3 installation steps to facilitate Push Notification handling.

Prerequisites:

  1. Configure an application within the Firebase Console by adhering to the established procedural steps.
  2. Acquire the google-services.json configuration file and incorporate it into your project directory.
  3. Implement the Firebase Cloud Messaging (FCM) SDK within your application according to the official documentation.

Retrieve the FCM Registration Token and register it utilizing the Genuin SDK interface.

index.html
private fun getFirebaseToken(){
        FirebaseMessaging.getInstance().token
            .addOnCompleteListener { task: Task<String> ->
                if (!task.isSuccessful) {
                    return@addOnCompleteListener
                }
                // Get new FCM registration token
                val token = task.result
                // Register token with Genuin SDK
                GenuinSDK.registerFCMToken("YOUR_CONTEXT", token)
            }
    }

To facilitate the management of foreground notifications when the application is active in the foreground:

MyFirebaseMessagingService.kt
class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        val data: Map<String, String> = remoteMessage.getData()
        if (GenuinSDK.willHandleForegroundNotification(data)) {
            val message = remoteMessage.notification?.body ?: ""
            GenuinSDK.handleForegroundNotifications(
                context = this,
                data = data,
                message = message,
                smallNotificationIcon = R.drawable.ic_small_notifications // Your app's notification small icon
            )
        } else {
            // Handle other push notifications for your app
        }
    }

    /**
     * There are two scenarios when onNewToken is called:
     * 1) When a new token is generated on initial app startup
     * 2) Whenever an existing token is changed
     * Under #2, there are three scenarios when the existing token is changed:
     * A) App is restored to a new device
     * B) User uninstalls/reinstall the app
     * C) User clears app data
     */
    override fun onNewToken(s: String) {
        super.onNewToken(s)
        GenuinSDK.registerFCMToken(this, s)
    }
}

The willHandleForegroundNotification method verifies whether the Genuin SDK will process a specific notification payload when the application is active in the foreground.

Background and Terminated State Notification Handling

  • Upon a user interaction with a notification, the SDK delivers the associated notification payload directly to your application's launcher activity.
YourLauncherActivity.kt
if (GenuinSDK.willHandleNotification(intent)) {
     GenuinSDK.handleBackgroundNotifications(context = "YOUR_CONTEXT", intent)
}

The willHandleNotification method verifies whether the Genuin SDK will process the provided notification payload.

Specs & Limitations

System Behavior

  • SDK follows modular dependency hierarchy
  • Embed/Placement requires activity context
  • Feeds can be loaded synchronously or asynchronously
  • Auto-play requires lifecycle handling (onResume/onPause)

Validation Rules

  • All SDK modules must use same version (2.1.2)
  • Container height must NOT be wrap_content
  • Deep linking requires proper domain setup
  • SSO token must be valid for auto login

Limitations

  • Minimum supported SDK version: 24
  • Override for lower SDK may cause partial feature failures
  • Some features (AI, Camera) require additional permissions
  • Monetization requires Play Console declaration

Related Articles / Next Steps

Support

For assistance, contact: support@begenuin.com

Genuin Footer