Skip to main content

Overview

Starting in version 4.3.0, the Kount Android SDK provides completion handlers that allow you to execute custom code immediately after data collection completes. This feature gives you precise control over the timing of your application flow based on collection success or failure.
Feature Added: Version 4.3.0Completion handlers help you perform any action of your choice right after DDC (Device Data Collection) completes.

The collectForSession Method

The collectForSession() method accepts three parameters:
  1. Context - Your Activity or Application context
  2. Success Handler - Called when collection completes successfully
  3. Failure Handler - Called when collection fails

Method Signature

KountSDK.collectForSession(
    context: Context,
    onSuccess: (sessionId: String) -> Unit,
    onFailure: (sessionId: String, error: String) -> Unit
)

Success Handler

The success handler is invoked when data collection completes successfully. It receives the session ID as a parameter.
KountSDK.collectForSession(
    this,
    { sessionId ->
        // Collection succeeded!
        Log.d("TAG", "Collection completed with session ID: $sessionId")
        Log.d("TAG", "Status: ${KountSDK.getCollectionStatus()}")
        
        // Now you can:
        // - Enable checkout buttons
        // - Navigate to next screen
        // - Send sessionId to your backend
        // - Update UI to show success
    },
    { sessionId, error ->
        // Handle failure...
    }
)

Failure Handler

The failure handler is invoked when data collection fails. It receives both the session ID and an error message.
KountSDK.collectForSession(
    this,
    { sessionId ->
        // Handle success...
    },
    { sessionId, error ->
        // Collection failed
        Log.d("TAG", "Collection failed with error: $error")
        Log.d("TAG", "Session ID: $sessionId")
        Log.d("TAG", "Status: ${KountSDK.getCollectionStatus()}")
        
        // You can:
        // - Retry collection
        // - Log the error for debugging
        // - Proceed without collection (if acceptable)
        // - Show user-friendly error message
    }
)

Common Use Cases

class CheckoutActivity : AppCompatActivity() {
    private lateinit var checkoutButton: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_checkout)
        
        checkoutButton = findViewById(R.id.checkoutButton)
        checkoutButton.isEnabled = false // Disabled initially

        KountSDK.collectForSession(
            this,
            { sessionId ->
                // Enable button when collection completes
                runOnUiThread {
                    checkoutButton.isEnabled = true
                    Toast.makeText(this, "Ready to checkout", Toast.LENGTH_SHORT).show()
                }
            },
            { sessionId, error ->
                // Enable anyway but log the error
                runOnUiThread {
                    checkoutButton.isEnabled = true
                }
                Log.e("TAG", "Collection failed: $error")
            }
        )
    }
}
KountSDK.collectForSession(
    this,
    { sessionId ->
        // Send session ID to your backend
        sendToBackend(sessionId)
    },
    { sessionId, error ->
        Log.e("TAG", "Failed to collect: $error")
        // Decide whether to proceed without session ID
        sendToBackend(sessionId) // You can still send it
    }
)

private fun sendToBackend(sessionId: String) {
    // Your API call
    val request = TransactionRequest(
        amount = 99.99,
        kountSessionId = sessionId,
        // ... other fields
    )
    apiService.submitTransaction(request)
}
class MainActivity : AppCompatActivity() {
    private lateinit var statusTextView: TextView
    private lateinit var sessionIdTextView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        statusTextView = findViewById(R.id.status)
        sessionIdTextView = findViewById(R.id.sessionId)
        
        statusTextView.text = "Collecting data..."

        KountSDK.collectForSession(
            this,
            { sessionId ->
                runOnUiThread {
                    statusTextView.text = "Collection Status: ${KountSDK.getCollectionStatus()}"
                    sessionIdTextView.text = "Session ID: $sessionId"
                }
            },
            { sessionId, error ->
                runOnUiThread {
                    statusTextView.text = "Collection Failed: $error"
                    statusTextView.setTextColor(Color.RED)
                    sessionIdTextView.text = "Session ID: $sessionId"
                }
            }
        )
    }
}

Real-World Example from Sample App

Here’s the actual implementation from the Kount sample application:
MainActivity.kt
private fun requestLocationPermission(activity: Activity) {
    if (ContextCompat.checkSelfPermission(
            activity,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        ActivityCompat.requestPermissions(
            activity,
            arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
            KountSDK.REQUEST_PERMISSION_LOCATION
        )
    } else {
        location.text = "Allowed"
        
        // Collect data with completion handlers
        KountSDK.collectForSession(
            activity,
            { sessionId ->
                Log.d("TAG", "utils success completed with sessionId $sessionId")
                Log.d("TAG", "DDC status is ${KountSDK.getCollectionStatus()}")
            },
            { sessionId, error ->
                Log.d("TAG", "utils failed with sessionId $error, $sessionId")
                Log.d("TAG", "DDC status is ${KountSDK.getCollectionStatus()}")
            }
        )
    }
}

Best Practices

Always Provide Both Handlers

Even if you don’t need the failure handler, provide an implementation that logs the error for debugging.

Use runOnUiThread for UI Updates

If you’re updating UI elements in the handlers, wrap them in runOnUiThread to ensure thread safety.

Check Collection Status

Use KountSDK.getCollectionStatus() inside handlers to get detailed status information.

Don't Block User Flow

Consider allowing users to proceed even if collection fails, while logging the failure for investigation.
Completion handlers are called on a background thread. Always use runOnUiThread or similar mechanisms when updating UI elements.

Next Steps

Error Handling

Learn comprehensive error handling strategies for collection failures

Build docs developers (and LLMs) love