SigningHub Android SDK Integration

The "Android SDK Integration" page is intended for developers who are interested in writing applications which will use the capabilities offered by SigningHub Mobile SDK. It is assumed that the reader has a basic knowledge of Android, Kotlin, and Gradle.


Overview

The SigningHub Android SDK is built on top of our REST-based API web services. This SDK is a quick way to integrate SigningHub with different mobile applications. SigningHub Mobile SDK provides the following features:

  • Document preparation

    • Upload documents from local files, library, and cloud drives (Google Drive, OneDrive, and Dropbox)

    • Add, update, and delete recipients (contact, group, placeholder, electronic seal)

    • Add signature fields (digital signature, electronic signature, In-person signature, initials)

    • Add form fields (input field, check box, radio box)

    • Add attachment field

    • Add QR code

    • Add drop-in comment

  • Access authentication (shared password, OTP, TOTP)

  • Access duration (based on dates, based on days)

  • Document viewing

    • Draft

    • In-Progress

    • Pending

    • Signed

    • Declined

    • Approved

    • Updated

    • Completed

  • Form filling

    • Text field

    • Check box

    • Radio button

    • Drop down, etc.

  • Adding initials

  • Signing In-person

  • Electronic signature (with or without witness signature)

  • Legal notice

  • Server-side signing authentication

  • Signing using a hand-drawn image, an uploaded image (via photo gallery) or text-based typography (using a fixed embedded font)

  • Document signing (digital signature)

  • Authorise remote signing for a qualified signature

  • View existing signatures and verification details

  • Declining a document

  • Approving a document

  • Editing a document

  • Branding

  • Localization


Add SigningHub SDK to an Android application project

To use the SigningHub Mobile SDK in an Android application project, follow the steps below:

  1. In your app-level build.gradle file set minSDK = 24: Android 7.0 or higher. The SigningHub Mobile SDK supports Minimum SDK API 24: Android 7.0.

  2. Open your Android project, and add “signinghub-android-sdk.aar” in the 'app/libs' folder.

  3. Add “gosign-mobile-sdk.aar” in the ‘libs’ folder if you are expected to use remote authorisation signing.

  4. Open build.gradle associated with “app” and include this: it will add the .aar file in the libs folder to your project.

    implementation(fileTree(mapOf("dir" to "libs", "include" to "*.aar")))
  5. We don’t publish the SigningHub SDK on Maven or Google repository; instead, we provide the .aar file. This file does not include metadata information about the dependencies of this SDK, so the host app needs to add this SDK’s dependencies in its Gradle file for the SDK to be fully functional.

    dependencies {
        implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar"))))
    
        // Core AndroidX
        implementation("androidx.core:core-ktx:1.15.0")
        implementation("androidx.appcompat:appcompat:1.7.0")
        implementation("com.google.android.material:material:1.12.0")
    
        // Lifecycle and Navigation
        implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
        implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.7")
        implementation("androidx.navigation:navigation-fragment-ktx:2.8.9")
        implementation("androidx.navigation:navigation-ui-ktx:2.8.9")
        implementation("androidx.paging:paging-runtime-ktx:3.3.6")
    
        // Networking
        implementation("com.squareup.retrofit2:retrofit:2.9.0")
        implementation("com.squareup.moshi:moshi-kotlin:1.15.0")
        implementation("com.squareup.retrofit2:converter-moshi:2.9.0")
        implementation("com.squareup.okhttp3:okhttp:4.12.0")
        implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
    
        // Firebase (Optional)
        implementation("com.google.firebase:firebase-analytics:22.3.0") // Remove if not using Firebase
        implementation("com.google.firebase:firebase-crashlytics-ktx:19.4.1") // Remove if not using Firebase
    
        // Security & Cryptography (Optional)
        implementation("com.madgag.spongycastle:pg:1.54.0.0") // Remove if not using GoSign RAS
        implementation("com.madgag.spongycastle:core:1.54.0.0") // Remove if not using GoSign RAS
        implementation("com.madgag.spongycastle:prov:1.54.0.0") // Remove if not using GoSign RAS
        implementation("com.madgag.spongycastle:pkix:1.54.0.0") // Remove if not using GoSign RAS
    
        // Utility Libraries
        implementation("com.google.code.gson:gson:2.11.0")
        implementation("io.github.chaosleung:pinview:1.4.4")
        implementation("com.facebook.shimmer:shimmer:0.5.0")
        implementation("com.linkedin.android.spyglass:spyglass:3.0.3")
        implementation("com.github.QuadFlask:colorpicker:0.0.15")
        implementation("com.otaliastudios:zoomlayout:1.9.0")
        implementation("com.intuit.sdp:sdp-android:1.1.0")
        implementation("com.intuit.ssp:ssp-android:1.1.0")
        implementation("com.github.AndroidDeveloperLB:AutoFitTextView:10")
        implementation("com.vanniktech:android-image-cropper:4.6.0")
    
        // Fresco
        implementation("com.facebook.fresco:imagepipeline-okhttp3:3.1.3")
        implementation("com.facebook.fresco:fresco:3.1.3") {
            exclude("com.facebook.soloader", "soloader")
            exclude("com.facebook.fresco", "soloader")
            exclude("com.facebook.fresco", "nativeimagefilters")
            exclude("com.facebook.fresco", "nativeimagetranscoder")
            exclude("com.facebook.fresco", "memory-type-native")
            exclude("com.facebook.fresco", "imagepipeline-native")
        }
    }
  6. The final build.gradle.kts file will have the following items.

    plugins {
        alias(libs.plugins.android.application)
        alias(libs.plugins.kotlin.android)
        alias(libs.plugins.navigationSafeArgs)
    }
    
    android {
        namespace = "com.signinghub.example"
        compileSdk = 35
    
        defaultConfig {
            applicationId = "com.signinghub.example"
            minSdk = 24
            targetSdk = 35
            versionCode = 1
            versionName = "1.0"
    
            testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                proguardFiles(
                    getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
                )
            }
        }
        compileOptions {
            sourceCompatibility = JavaVersion.VERSION_11
            targetCompatibility = JavaVersion.VERSION_11
        }
        kotlinOptions {
            jvmTarget = "11"
        }
        buildFeatures {
            viewBinding = true
        }
    }
    
    dependencies {
        implementation(fileTree(mapOf("dir" to "libs", "include" to "*.aar")))
    
        implementation(libs.androidx.core.ktx)
        implementation(libs.androidx.appcompat)
        implementation(libs.material)
        implementation(libs.androidx.activity)
        implementation(libs.androidx.constraintlayout)
        testImplementation(libs.junit)
        androidTestImplementation(libs.androidx.junit)
        androidTestImplementation(libs.androidx.espresso.core)
    
        // Core AndroidX
        implementation(libs.androidx.lifecycle.viewmodel.ktx)
        implementation(libs.androidx.lifecycle.livedata.ktx)
        implementation(libs.androidx.navigation.fragment.ktx)
        implementation(libs.androidx.navigation.ui.ktx)
        implementation(libs.androidx.paging.runtime.ktx)
    
        // Networking
        implementation(libs.retrofit)
        implementation(libs.moshi.kotlin)
        implementation(libs.converter.moshi)
        implementation(libs.okhttp)
        implementation(libs.logging.interceptor)
    
        // Firebase (Optional)
        implementation(libs.firebase.analytics) // Remove if not using Firebase
        implementation(libs.firebase.crashlytics.ktx) // Remove if not using Firebase
    
        // Security & Cryptography (Optional)
        // Remove if not using JSON-based SAD in RAS
        implementation(libs.sc.pg)
        implementation(libs.sc.core)
        implementation(libs.sc.prov)
        implementation(libs.sc.pkix)
    
        // Utility Libraries
        implementation(libs.gson)
        implementation(libs.pinview)
        implementation(libs.shimmer)
        implementation(libs.spyglass)
        implementation(libs.zoomlayout)
        implementation(libs.colorpicker)
        implementation(libs.autoFitTextView)
        implementation(libs.vanniktech.android.image.cropper)
    
        // SDP & SSP
        implementation(libs.sdp.android)
        implementation(libs.ssp.android)
    
        // Fresco
        implementation(libs.imagepipeline.okhttp3)
        implementation("com.facebook.fresco:fresco:3.1.3") {
            exclude("com.facebook.soloader", "soloader")
            exclude("com.facebook.fresco", "soloader")
            exclude("com.facebook.fresco", "nativeimagefilters")
            exclude("com.facebook.fresco", "nativeimagetranscoder")
            exclude("com.facebook.fresco", "memory-type-native")
            exclude("com.facebook.fresco", "imagepipeline-native")
        }
    }
  7. Set the Application class name in the manifest to the following:

    <application
        android:name="com.signinghub.sdk.SHApplication"
    
    // If you have a custom Application class, make sure to extend your application class 
    // with SHApplication class and reference your class in the manifest file like this
    
    <application
        android:name=".MyApplication"
  8. Change the default theme of your App to your desired theme with NO_ACTION_BAR in “styles.xml” file.

  9. (Optional but Recommended) The SigningHub SDK is built using the Material 3 theme. To ensure a consistent and error-free UI experience, it is recommended to extend your app's theme from the SH10M3 theme, as shown below. You can customise the theme properties to match your design preferences.

<resources>
    <style name="Base.Theme.SH10SDKDemo" parent="@style/Theme.SH10M3">
        <item name="android:windowLightStatusBar">true</item>
    </style>

    <style name="Theme.SH10SDKDemo" parent="Base.Theme.SH10SDKDemo" />
</resources>

Using the SigningHub SDK: Features and implementation

The Android application needs to import the following classes in its code:

  • com.signinghub.sdk.managers.SessionManager

  • com.signinghub.sdk.managers.DocumentManager

The SigningHub Mobile Android SDK authenticates the user who is registered in the SigningHub and then provides the supported features.


Authentication

Manages user authentication and session-related operations. This class provides a high-level abstraction for handling authentication.


Features

This class offers the following key features to support secure and seamless authentication:

  • Token Management: Fetch client tokens, refresh access tokens, and manage authentication tokens.

  • User Authentication: Authenticate users via password or Single Sign-On (SSO).

  • Session Management: Check authentication status, retrieve access tokens, and log out users.

  • API Base URL Management: Update and retrieve the API base URL dynamically.

  • Error Handling: Robust error handling with detailed error messages.


Class structure

The SessionManager class with the following key methods:

  • fetchClientToken: Fetches a client token for initial authentication.

  • authenticateWithPassword: Authenticates a user using their email and password.

  • authenticateWithSSO: Authenticates a user via Single Sign-On (SSO).

  • refreshAccessToken: Refreshes an expired access token.

  • LogoutUser: Logs out the user and clears authentication data.

  • isUserAuthenticated: Checks if the user is authenticated.

  • getAccessToken: Retrieves the current access token.


Usage

Code: Session Manager
/**
 * Authenticates a user using their email and password.
 * This method supports optional custom headers (e.g., OTP, Terms Agreement) and allows specifying the authentication method.
 *
 * @param email The user's email address.
 * @param password The user's password.
 * @param baseUrl Optional API base URL. If empty, the stored URL is used.
 * @param headers Optional request headers (e.g., OTP, Terms Agreement headers).
 * @param authMethod The authentication method to use (default: [AuthenticationMethods.PASSWORD]).
 * @param onResult A callback that returns a [Resource] containing either the [AuthenticationResponse] or an error.
 */
fun authenticateWithPassword(
    email: String,
    password: String,
    baseUrl: String = "",
    headers: Map<String, String> = emptyMap(),
    authMethod: AuthenticationMethods = AuthenticationMethods.PASSWORD,
    onResult: (Resource<AuthenticationResponse>) -> Unit,
)

/**
 * Authenticates a user via Single Sign-On (SSO).
 * This method supports SSO authentication using a code, token, or profile name.
 *
 * @param code Optional - Code obtained from OAuth2 or OIDC (authorize response)
 * @param token Optional - Token obtained from 3rd party e.g Office 365, Azure Active Directory, OAuth 2, OIDC
 * @param method Required - Supported method type Possible values are "OFFICE_365", "AZURE_ACTIVE_DIRECTORY", "OAUTH2", "OIDC"
 * @param profileName Optional - Authentication profile name, required for "OAUTH2" and "OIDC". It's an alternative to profile_id, so this can be skipped if profile_id is provided. It's become mandatory for "OFFICE_365" and "AZURE_ACTIVE_DIRECTORY" too if code is provided and token is not provided in the request body.
 * @param baseUrl Optional API base URL. If empty, the stored URL is used.
 * @param headers Optional request headers.
 * @param onResult A callback that returns a [Resource] containing either the [AuthenticationResponse] or an error.
 */
fun authenticateWithSSO(
    code: String = "",
    token: String = "",
    method: String = "",
    profileName: String = "",
    baseUrl: String = "",
    headers: HashMap<String, String>,
    onResult: (Resource<AuthenticationResponse>) -> Unit,
)

/**
 * Logs out the user and clears all authentication-related data.
 * This method also supports optional FCM token invalidation.
 *
 * @param fcmToken Optional FCM token to invalidate during logout.
 * @param onResult A callback that returns a [Resource] containing either the [ResponseBody] or an error.
 */
fun logout(fcmToken: String? = null, onResult: (Resource<ResponseBody>) -> Unit)

/**
 * Fetches a client token required for authentication.
 * This token is typically used as a preliminary step before performing user authentication.
 *
 * @param onResult A callback that returns a [Resource] containing either the [AuthenticationResponse] or an error.
 */
fun fetchClientToken(onResult: (Resource<AuthenticationResponse>) -> Unit) {
    executeRequest(onResult) { authRepository.fetchClientToken() }
}

/**
 * Refreshes the access token using the stored refresh token.
 * This method is useful when the current access token has expired.
 *
 * @param onResult A callback that returns a [Resource] containing either the [AuthenticationResponse] or an error.
 */
fun refreshAccessToken(onResult: (Resource<AuthenticationResponse>) -> Unit) {
    executeRequest(onResult) { authRepository.fetchAccessToken() }
}

Callbacks & example

Code: Example
val sessionManager = SessionManager.getInstance()
sessionManager.authenticateWithPassword(
    email = "user@example. com", password = "password123",
    onResult = { result ->
        when (result) {
            is Resource.Success -> println("Authentication successful: ${result.data?.accessToken}")
            is Resource.Error -> println("Authentication failed: ${result.mErrorDetails?.message}")
            is Resource.Loading -> println("Authenticating...")
            is Resource.Empty -> println("Default empty state")
        }
    },
)

Response

All methods in the SessionManager and all other classes return their results via a Resource sealed class. This class encapsulates the state of an operation, such as success, loading, error, or empty states. The Resource class is generic, allowing it to handle any type of data (T).

Class structure

Code: Resource
/**
 * A sealed class representing the state of a resource (e.g., API response or data operation).
 * This class is used to encapsulate the result of an operation, including success, loading, error, and empty states.
 *
 * The [Resource] class is generic, allowing it to handle any type of data (`T`).
 * It provides a structured way to handle API responses or asynchronous operations in a consistent manner.
 *
 * Subclasses:
 * - [Success]: Represents a successful operation with associated data.
 * - [Loading]: Represents an ongoing operation (e.g., API call in progress).
 * - [Empty]: Represents an operation that returned no data. Mainly to represent clean state
 * - [Error]: Represents a failed operation with error details.
 *
 * @param data The data associated with the resource (nullable).
 * @param statusCode The HTTP status code or custom status code for the operation.
 * @param isSuccess Indicates whether the operation was successful.
 * @param rawResponse The raw HTTP response (nullable).
 * @param headers A map of headers associated with the response.
 * @param errorDetails Details about any errors that occurred during the operation.
 */
sealed class Resource<T>(
    var data: T?,
    var statusCode: Int,
    var isSuccess: Boolean,
    var rawResponse: okhttp3.Response?,
    var headers: Map<String, Any>,
    var errorDetails: ErrorDetails,
) : BaseModel() {

    /**
     * Represents a successful operation with associated data.
     *
     * @param mData The data returned by the operation.
     * @param mStatusCode The HTTP status code (default: 200).
     * @param mHeaders A map of headers associated with the response.
     * @param raw The raw HTTP response (nullable).
     */
    data class Success<T>(
        var mData: T? = null,
        var mStatusCode: Int = 200,
        var mHeaders: Map<String, Any> = emptyMap(),
        var raw: okhttp3.Response? = null,
    ) : Resource<T>(mData, mStatusCode, true, raw, mHeaders, ErrorDetails())

    /**
     * Represents an ongoing operation (e.g., an API call in progress).
     *
     * @param message A message describing the loading state (e.g., "Loading...").
     * @param mData Optional data that may be available during loading.
     */
    data class Loading<T>(val message: String = "", var mData: T? = null) :
        Resource<T>(mData, -1, false, null, emptyMap(), ErrorDetails())

    /**
     * Represents an operation that returned no data.
     *
     * @param message A message describing the empty state (default: "Empty").
     */
    data class Empty<T>(val message: String = "Empty") :
        Resource<T>(null, -1, false, null, emptyMap(), ErrorDetails())

    /**
     * Represents a failed operation with error details.
     *
     * @param mStatusCode The HTTP status code or custom error code (default: 400).
     * @param mHeaders A map of headers associated with the error response.
     * @param mErrorDetails Details about the error that occurred.
     * @param mData Optional data that may be available despite the error.
     */
    data class Error<T>(
        var mStatusCode: Int = 400,
        var mHeaders: Map<String, Any> = emptyMap(),
        var mErrorDetails: ErrorDetails,
        var mData: T? = null,
    ) : Resource<T>(mData, mStatusCode, false, null, mHeaders, mErrorDetails)
}
Code: Example
SessionManager.getInstance().fetchClientToken { resource ->
    when (resource) {
        is Resource.Success -> println("Client token fetched: ${resource.mData}")
        is Resource.Loading -> println("Fetching client token...")
        is Resource.Empty -> println("No data returned")
        is Resource.Error -> println("Error: ${resource.mErrorDetails.message}")
    }
}

Open document

Once the authentication is done, document opening can be handled via the DocumentManager class.


Overview

The DocumentManager class is a utility object provided by the SigningHub SDK to manage document-related workflows. It simplifies the process of creating, cloning, and opening workflows for actions such as signing or reviewing documents. This class serves as the primary entry point for interacting with the SDK's workflow management features.

Key Features:

  • Workflow Initialisation: Start new workflows from scratch or by cloning existing packages.

  • Workflow Management: Open existing workflows for actions like signing or reviewing.

  • Lifecycle-Aware Results: Uses ActivityResultLauncher for handling activity results in a modern and lifecycle-aware manner.

  • Efficient Workflow Handling: Pre-fetched workflow details can be used to avoid redundant API calls.


Class structure

The DocumentManager class is a singleton object with the following key methods:

  • startNewWorkFlow: Starts a new workflow from scratch.

  • startNewWorkflowFromExistingPackage: Starts a new workflow by cloning documents from an existing package.

  • openPackageViewer: Opens an existing workflow for actions like signing or reviewing.

  • startSdkActivity: A private helper method to launch the SDK's main activity with the required parameters.


Usage

/**
 * Starts a new workflow from scratch with default SigningHub settings.
 *
 * **Parameters:**
 * - `context`: The calling activity context required to launch the SDK activity.
 * - `folderName`: (Optional) The name of the folder where the workflow will be stored.
 * - `activityResultLauncher`: A lifecycle-aware launcher to handle the result of the launched activity.
 *
 * **Behavior:**
 * - Opens the workflow creation interface with no pre-existing configurations.
 */
fun startNewWorkFlow(
    context: Context,
    folderName: String = "",
    activityResultLauncher: ActivityResultLauncher<Intent>,
) 
/**
 * Starts a new workflow by duplicating documents from an existing package.
 *
 * **Parameters:**
 * - `context`: The calling activity context required to launch the SDK activity.
 * - `packageId`: The unique ID of the existing package whose documents will be cloned.
 * - `activityResultLauncher`: A lifecycle-aware launcher to handle the result of the launched activity.
 *
 * **Behavior:**
 * - Displays a toast message if `packageId` is empty.
 * - Opens the workflow creation interface with documents cloned from the specified package.
 */
fun startNewWorkflowFromExistingPackage(
    context: Context,
    packageId: String,
    activityResultLauncher: ActivityResultLauncher<Intent>,
)

/**
 * Opens an existing workflow for actions such as signing or reviewing.
 *
 * **Parameters:**
 * - `context`: The calling activity context required to launch the SDK activity.
 * - `packageId`: The unique ID of the workflow package to open.
 * - `activityResultLauncher`: A lifecycle-aware launcher to handle the result of the launched activity.
 *
 * **Behavior:**
 * - Displays a toast message if `packageId` is empty.
 * - Calls the `getWorkflowDetails` API to fetch the workflow status and details before opening it.
 */
fun openPackageViewer(
    context: Context,
    packageId: String,
    activityResultLauncher: ActivityResultLauncher<Intent>,
)

/**
 * Opens an existing workflow using pre-fetched workflow details.
 *
 * **Parameters:**
 * - `context`: The calling activity context required to launch the SDK activity.
 * - `workflowDetails`: The pre-fetched workflow details (`RMWorkFlowDetails`) to be used directly.
 * - `activityResultLauncher`: A lifecycle-aware launcher to handle the result of the launched activity.
 *
 * **Behavior:**
 * - Updates the workflow details in the repository without calling the `getWorkflowDetails` API.
 * - Opens the workflow viewer directly, making this method more efficient.
 */
fun openPackageViewer(
    context: Context,
    workflowDetails: RMWorkFlowDetails,
    activityResultLauncher: ActivityResultLauncher<Intent>,
)

Branding

Branding in SigningHubSDK allows customisation of the app's appearance using different colour levels. The backend provides two types of branding:

  • Admin Branding – Applied globally across all enterprises.

  • Enterprise Branding – Custom branding per enterprise.

Developers can retrieve branding settings using the REST APIs provided by SigningHub. The SDK automatically applies branding when provided with valid colour data for branding.


Colour level usage in the app

  • Level 2: Primary button background (used for main action buttons).

  • Level 3: Negative actions (e.g., Delete, Remove, Logout).

  • For filled negative buttons, Level 3 is the background colour.

  • For outlined/text buttons, Level 3 is the text/icon colour.

  • Level 5: Content displayed on Level 2 colour (text colour).

  • Level 15: Text and icon colour for the negative button's colour.


Branding API endpoints

API calls for branding are written in GlobalRepository. When you call the APIs using our provided repository, branding colours are applied automatically.

fun fetchAdminBranding() {
    viewModelScope.launch {
        GlobalRepository.instance.getAdminBranding()
    }
}

fun fetchEnterpriseBranding() {
    viewModelScope.launch {
        GlobalRepository.instance.getEnterpriseBranding(true)
    }
}

Custom branding

If you do not call the APIs mentioned above and want to provide your own colours directly, you can use the helper function provided in the document manager. Ensure that you call this method before opening any workflow.

/**
 * Sets the branding colours for the application.
 *
 * The branding colours can be retrieved from one of the following sources:
 * - **Admin Branding API**
 * - **Enterprise Branding API**
 * - **Manually provided colors** in HEX format.
 *
 * **Important Notes:**
 * - If no custom branding colours are provided, the SDK will use the default colours defined in its resource files.
 * - Only the following levels are used in the Android app:
 *   - **Level 2** → Primary button background color.
 *   - **Level 3** → Negative action button colour (e.g., delete, remove, logout).
 *   - **Level 5** → Content text colour displayed on Level 2 buttons.
 *   - **Level 15** → Text and icon colour for negative buttons.
 *
 * @param brandingColor The `BrandingColors` object containing the colour levels.
 */
fun setBrandingColors(brandingColor: BrandingColors)


Code: Example
/**
 * Sets the branding colours for the application. Colour should be in Hex form. Only these levels are supported; if no colour is provided, default values will be used
 */
DocumentManager.setBrandingColors(.    BrandingColors(
        levelTwoColor = "#795548",
        levelFiveColor = "#FFFFFF",
        levelThreeColor = "#8332a8",
        levelFifteenColor = "#FFFFFF",
    )
)

Push notifications for Android level 33 or above (Optional)

To be able to receive push notifications on Android level 33 or above, Runtime permission is required as per the Google Developer Guide. Add Runtime permission on App side:


Example project on Bitbucket

To help developers get started quickly, we provide an example project hosted on Bitbucket. This project demonstrates how to integrate and use the SigningHub SDK within an Android application.

Repository URL: SigningHub SH10 SDK Example

Steps to use the example project:

  • Open the Project in Android Studio.

  • Add the SigningHub SDK:

    • Navigate to the app/libs folder.

    • Manually place your signinghub-sdk-release.aar file inside this folder.

  • Sync and Run the Project:

    • In Android Studio, click on File > Sync Project with Gradle Files.

    • Build and run the project on a device or emulator.

  1. The SDK AAR file is not included in the example project due to licensing. You must add your own signinghub-sdk-release.aar file inside the app/libs folder to successfully run the project.

Last updated

Was this helpful?