Skip to main content
Android Integration
Learn how to integrate the IgniSign signature interface into your Android applications

Overview

The IgniSign Android SDK allows you to integrate electronic signatures directly into your Android applications, providing a seamless experience for your users. The SDK handles the complexities of document presentation, identity verification, signature capture, and legal compliance.

Integration Flow

The general flow for integrating the signature interface into Android applications is as follows:

Installation

To get started with the IgniSign Android SDK, add it to your project by following these steps:

1. Add the IgniSign Maven Repository

Add the IgniSign Maven repository to your project's build.gradle file:

// In your project-level build.gradle file
allprojects {
  repositories {
      google()
      mavenCentral()
      // Add the IgniSign Maven repository
      maven {
          url "https://maven.ignisign.io/repository/maven-public/"
      }
  }
}

Or in your settings.gradle file if you're using the new Android Studio project structure:

// In your settings.gradle file
dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  repositories {
      google()
      mavenCentral()
      // Add the IgniSign Maven repository
      maven {
          url "https://maven.ignisign.io/repository/maven-public/"
      }
  }
}
2. Add the SDK Dependency

Add the IgniSign Android SDK dependency to your app's build.gradle file:

// In your app-level build.gradle file
dependencies {
  // Other dependencies
  implementation 'io.ignisign:ignisign-android:1.0.0' // Replace with the latest version
}
3. Enable Java 8 Features

The SDK requires Java 8 features. Add the following to your app's build.gradle file:

// In your app-level build.gradle file
android {
  // Other configurations
  compileOptions {
      sourceCompatibility JavaVersion.VERSION_1_8
      targetCompatibility JavaVersion.VERSION_1_8
  }
  kotlinOptions {
      jvmTarget = '1.8'
  }
}
4. Add Internet Permission

The SDK requires internet access. Add the following permission to your AndroidManifest.xml file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="your.package.name">
  
  <uses-permission android:name="android.permission.INTERNET" />
  
  <!-- Rest of your manifest -->
</manifest>

Implementation Steps

1
Add IgnisignAndroid View
Add an IgnisignAndroid view in your layout XML
2
Configure Session Parameters
Create instances of IgnisignSignatureSessionDimensions, IgnisignJSSignatureSessionsDisplayOptions, and IgnisignInitParams
3
Set Up View
Call setValues() and initSignatureSession()
4
Implement Callbacks
Implement ISessionCallbacks in your Activity or Fragment

Basic Implementation

Here's a step-by-step guide to implementing IgniSign in your Android application:

1. Add the IgnisignAndroid View to Your Layout

Create a layout file for your signature activity:

<!-- activity_signature.xml -->
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".SignatureActivity">

  <com.ignisign.IgnisignAndroid
      android:id="@+id/ignisignView"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
2. Create the Signature Activity

Create an activity to handle the signature process:

package com.yourcompany.yourapp

import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.ignisign.IgnisignAndroid
import com.ignisign.ISessionCallbacks
import com.ignisign.IgnisignSignatureSessionDimensions
import com.ignisign.IgnisignJSSignatureSessionsDisplayOptions
import com.ignisign.IgnisignInitParams

class SignatureActivity : AppCompatActivity(), ISessionCallbacks {
  
  private lateinit var ignisignView: IgnisignAndroid
  
  override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_signature)
      
      // Get the signature request and signer IDs from your backend
      val signatureRequestId = intent.getStringExtra("signatureRequestId")
      val signerId = intent.getStringExtra("signerId")
      val signatureSessionToken = intent.getStringExtra("signatureSessionToken")
      val signerAuthSecret = intent.getStringExtra("signerAuthSecret") // Required for embedded integration
      
      // Initialize the IgniSign view
      ignisignView = findViewById(R.id.ignisignView)
      
      // Set up the signature session dimensions
      val dimensions = IgnisignSignatureSessionDimensions(
          width = "100%",
          height = "100%"
      )
      
      // Set up display options
      val displayOptions = IgnisignJSSignatureSessionsDisplayOptions(
          showTitle = false,
          showDescription = false,
          darkMode = false,
          forceShowDocumentInformations = false
      )
      
      // Set up initialization parameters
      val initParams = IgnisignInitParams(
          signatureRequestId = signatureRequestId!!,
          signerId = signerId!!,
          signatureSessionToken = signatureSessionToken!!, // Session token from your backend
          signerAuthSecret = signerAuthSecret!!, // Required for embedded integration
          sessionCallbacks = this,
          closeOnFinish = true,
          dimensions = dimensions,
          displayOptions = displayOptions
      )
      
      // Initialize the signature session
      ignisignView.setValues(initParams)
      ignisignView.initSignatureSession()
  }
  
  // Implement ISessionCallbacks
  override fun onSessionComplete(data: String) {
      // Handle successful signature completion
      Log.d(TAG, "Signature completed: $data")
      Toast.makeText(this, "Signature completed successfully", Toast.LENGTH_SHORT).show()
      finish()
  }
  
  override fun onSessionError(error: String) {
      // Handle signature error
      Log.e(TAG, "Signature error: $error")
      Toast.makeText(this, "Error: $error", Toast.LENGTH_SHORT).show()
  }
  
  override fun onSessionCanceled(reason: String) {
      // Handle signature cancellation
      Log.d(TAG, "Signature canceled: $reason")
      Toast.makeText(this, "Signature canceled: $reason", Toast.LENGTH_SHORT).show()
      finish()
  }
  
  override fun onSessionProgress(progress: String) {
      // Handle signature progress updates
      Log.d(TAG, "Progress: $progress")
  }
  
  companion object {
      private const val TAG = "SignatureActivity"
  }
}
3. Launch the Signature Activity

Start the signature process by launching the SignatureActivity from another part of your application:

// In your document list activity or fragment
import android.content.Intent

// ...

private fun startSignatureProcess(signatureRequestId: String, signerId: String) {
  val intent = Intent(this, SignatureActivity::class.java).apply {
      putExtra("signatureRequestId", signatureRequestId)
      putExtra("signerId", signerId)
  }
  startActivity(intent)
}

Advanced Implementation

Using a Fragment

For more flexible integration, you can use a fragment instead of an activity:

package com.yourcompany.yourapp

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.ignisign.IgnisignAndroid
import com.ignisign.ISessionCallbacks
import com.ignisign.IgnisignSignatureSessionDimensions
import com.ignisign.IgnisignJSSignatureSessionsDisplayOptions
import com.ignisign.IgnisignInitParams

class SignatureFragment : Fragment(), ISessionCallbacks {
  
  private lateinit var ignisignView: IgnisignAndroid
  private var signatureRequestId: String? = null
  private var signerId: String? = null
  
  override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      arguments?.let {
          signatureRequestId = it.getString(ARG_SIGNATURE_REQUEST_ID)
          signerId = it.getString(ARG_SIGNER_ID)
      }
  }
  
  override fun onCreateView(
      inflater: LayoutInflater, container: ViewGroup?,
      savedInstanceState: Bundle?
  ): View? {
      // Inflate the layout for this fragment
      return inflater.inflate(R.layout.fragment_signature, container, false)
  }
  
  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      super.onViewCreated(view, savedInstanceState)
      
      // Check required parameters
      if (signatureRequestId == null || signerId == null) {
          throw IllegalArgumentException("signatureRequestId and signerId are required")
      }
      
      // Initialize the IgniSign view
      ignisignView = view.findViewById(R.id.ignisignView)
      
      // Configure session dimensions
      val dimensions = IgnisignSignatureSessionDimensions(
          width = "100%",
          height = "100%"
      )
      
      // Configure display options
      val displayOptions = IgnisignJSSignatureSessionsDisplayOptions(
          hideTitle = true
      )
      
      // Set initialization parameters
      val initParams = IgnisignInitParams(
          signatureRequestId = signatureRequestId!!,
          signerId = signerId!!,
          dimensions = dimensions,
          displayOptions = displayOptions
      )
      
      // Set values and initialize session
      ignisignView.setValues(initParams)
      ignisignView.initSignatureSession()
  }
  
  // Implement ISessionCallbacks
  override fun onSessionComplete(data: String) {
      // Handle successful signature completion
      Log.d(TAG, "Signature completed: $data")
      Toast.makeText(context, "Signature completed successfully", Toast.LENGTH_SHORT).show()
      // Notify the parent activity/fragment
      (activity as? SignatureListener)?.onSignatureComplete(data)
  }
  
  override fun onSessionError(error: String) {
      // Handle signature error
      Log.e(TAG, "Signature error: $error")
      Toast.makeText(context, "Error: $error", Toast.LENGTH_SHORT).show()
      // Notify the parent activity/fragment
      (activity as? SignatureListener)?.onSignatureError(error)
  }
  
  override fun onSessionCanceled(reason: String) {
      // Handle signature cancellation
      Log.d(TAG, "Signature canceled: $reason")
      Toast.makeText(context, "Signature canceled: $reason", Toast.LENGTH_SHORT).show()
      // Notify the parent activity/fragment
      (activity as? SignatureListener)?.onSignatureCanceled(reason)
  }
  
  override fun onSessionProgress(progress: String) {
      // Handle signature progress updates
      Log.d(TAG, "Progress: $progress")
      // Notify the parent activity/fragment
      (activity as? SignatureListener)?.onSignatureProgress(progress)
  }
  
  // Interface for communication with the parent activity/fragment
  interface SignatureListener {
      fun onSignatureComplete(data: String)
      fun onSignatureError(error: String)
      fun onSignatureCanceled(reason: String)
      fun onSignatureProgress(progress: String)
  }
  
  companion object {
      private const val TAG = "SignatureFragment"
      private const val ARG_SIGNATURE_REQUEST_ID = "signatureRequestId"
      private const val ARG_SIGNER_ID = "signerId"
      
      @JvmStatic
      fun newInstance(signatureRequestId: String, signerId: String) =
          SignatureFragment().apply {
              arguments = Bundle().apply {
                  putString(ARG_SIGNATURE_REQUEST_ID, signatureRequestId)
                  putString(ARG_SIGNER_ID, signerId)
              }
          }
  }
}
Customizing the Signature Interface

You can customize the appearance and behavior of the signature interface:

// Create display options with advanced customizations
val displayOptions = IgnisignJSSignatureSessionsDisplayOptions(
  hideTitle = true,                 // Hide the title bar
  darkMode = true,                  // Enable dark mode
  hideProgressBar = false,          // Show progress bar
  customCSS = "body { background-color: #f5f5f5; }", // Custom CSS
  logo = "https://your-company.com/logo.png", // Custom logo
  primaryColor = "#007bff"          // Custom primary color
)

// Create initialization parameters with the custom display options
val initParams = IgnisignInitParams(
  signatureRequestId = signatureRequestId,
  signerId = signerId,
  dimensions = dimensions,
  displayOptions = displayOptions,
  lang = "fr"                       // Set language to French
)
Error Handling

Implement comprehensive error handling to provide a better user experience:

override fun onSessionError(error: String) {
  try {
      // Parse the error JSON if applicable
      val errorObj = JSONObject(error)
      val errorCode = errorObj.optString("code", "UNKNOWN_ERROR")
      val errorMessage = errorObj.optString("message", "An unknown error occurred")
      
      // Handle specific error codes
      when (errorCode) {
          "NETWORK_ERROR" -> {
              // Handle network connectivity issues
              showNetworkErrorDialog()
          }
          "AUTH_ERROR" -> {
              // Handle authentication errors
              showAuthErrorDialog()
          }
          "SESSION_EXPIRED" -> {
              // Handle session expiration
              refreshSession()
          }
          else -> {
              // Handle other errors
              Log.e(TAG, "Signature error: $errorMessage")
              Toast.makeText(this, "Error: $errorMessage", Toast.LENGTH_SHORT).show()
          }
      }
  } catch (e: JSONException) {
      // Handle case where error is not JSON
      Log.e(TAG, "Error parsing error message: $error", e)
      Toast.makeText(this, "Error: $error", Toast.LENGTH_SHORT).show()
  }
}

Production Considerations

Security

When implementing the IgniSign SDK in production, consider these security best practices:

  • API Key Security: Store your API keys securely, preferably on your server side
  • HTTPS: Ensure all communications use HTTPS
  • Signature Token Handling: Generate signature tokens server-side to prevent tampering
  • User Authentication: Properly authenticate users before initiating signature requests
  • WebView Security: Configure WebView with secure settings
Performance

Optimize performance for a smooth user experience:

  • Resource Loading: Initialize the SDK only when needed
  • Memory Management: Release resources properly in onDestroy/onPause
  • Network Handling: Implement proper network state detection and recovery
  • Background Processing: Avoid heavy operations on the UI thread
User Experience

Enhance the user experience with these tips:

  • Loading States: Show proper loading indicators during initialization
  • Error Messages: Provide clear and actionable error messages
  • Orientation Changes: Handle device orientation changes properly
  • Navigation: Implement intuitive navigation flows around the signature process
  • Accessibility: Ensure the signature process is accessible to all users

Common Issues and Solutions

IssueSolution
WebView JavaScript errorsEnsure JavaScript is enabled in the WebView. Add debugging to see JavaScript errors.
Network connectivity issuesImplement network state detection and handle offline scenarios gracefully.
SDK initialization failuresEnsure all required parameters are provided and network connectivity is available.
Memory leaksProperly release the IgnisignAndroid view and clean up resources in onDestroy.

Next Steps

Now that you understand how to integrate the IgniSign signature interface into your Android applications, you might want to explore: