From a59e01f81ec77f72d676ab000d14211d3797b778 Mon Sep 17 00:00:00 2001 From: josh-socure Date: Fri, 18 Oct 2024 10:11:01 -0400 Subject: [PATCH] Sample App v5 Update --- README.md | 9 +- sample-app/app/build.gradle | 27 ++++-- .../java/com/socure/docv/sdk/sample/Api.kt | 69 ++++++++++++++ .../socure/docv/sdk/sample/MainActivity.kt | 94 +++++++++++++++---- sample-app/build.gradle | 4 +- 5 files changed, 169 insertions(+), 34 deletions(-) create mode 100644 sample-app/app/src/main/java/com/socure/docv/sdk/sample/Api.kt diff --git a/README.md b/README.md index 71a1273..191ebf7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Predictive DocV Android SDK v4 +# Predictive DocV Android SDK v5 Learn how to integrate the Predictive Document Verification (DocV) Android SDK into your Android application. @@ -8,10 +8,11 @@ Before getting started, check that your development environment meets the follow - Android SDK Version 22 (OS Version 5.1) and later -The DocV Android SDK v4 is compiled with: +The DocV Android SDK v5 is compiled with: -- `compileSdkVersion 33` -- Java 11 +- `compileSdkVersion 34` +- Java 17 +- Kotlin 1.8.10 > Note: Auto Capture feature requires Android SDK Version 28 (OS Version 9.0) and later with at least 3 GB of RAM. If the device does not meet these requirements, only the manual capture feature will be available. diff --git a/sample-app/app/build.gradle b/sample-app/app/build.gradle index 0ba30ce..f8eb2e7 100644 --- a/sample-app/app/build.gradle +++ b/sample-app/app/build.gradle @@ -4,27 +4,28 @@ plugins { } android { - compileSdk 33 + compileSdk 34 defaultConfig { applicationId "com.socure.docv.sdk.sample" minSdk 22 - targetSdk 33 + targetSdk 34 versionCode 11 - versionName "4.3.0" + versionName "5.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.debug } } compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { @@ -38,10 +39,16 @@ dependencies { implementation 'com.google.android.material:material:1.6.1' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - def sdk_version = "4.3.1" + def sdk_version = "5.0.0" implementation "com.socure.android:docv-capture:$sdk_version" - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + def retrofit_version = "2.9.0" + implementation "com.squareup.retrofit2:retrofit:$retrofit_version" + implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" + + def lifecycle_version = "2.5.1" + implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" + + def okhttp_version = "4.9.3" + implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version" } diff --git a/sample-app/app/src/main/java/com/socure/docv/sdk/sample/Api.kt b/sample-app/app/src/main/java/com/socure/docv/sdk/sample/Api.kt new file mode 100644 index 0000000..8187daf --- /dev/null +++ b/sample-app/app/src/main/java/com/socure/docv/sdk/sample/Api.kt @@ -0,0 +1,69 @@ +package com.socure.docv.sdk.sample + +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.http.Body +import retrofit2.http.HeaderMap +import retrofit2.http.POST + +private const val BASE_URL = "https://service.socure.com/" + +fun transaction(): TransactionService { + return Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .client(OkHttpBuilder().getBuilder()) + .build().create(TransactionService::class.java) +} + +interface TransactionService { + @POST("api/5.0/documents/request") + suspend fun createTransaction( + @HeaderMap headers: Map, + @Body request: TransactionRequest + ): TransactionResponse +} + +data class TransactionResponse( + val data: Data +) { + + data class Data( + val eventId: String, + val authToken: String, + val docvTransactionToken: String, + val qrcode: String, + val url: String + ) +} + +data class TransactionRequest( + val config: TransactionConfig, + val previousReferenceId: String? = null +) { + + data class TransactionConfig( + val useCaseKey: String, + val language: String = "en" + ) +} + +class OkHttpBuilder { + fun getBuilder(): OkHttpClient { + with(OkHttpClient.Builder()) { + readTimeout(120L, TimeUnit.SECONDS) + connectTimeout(120L, TimeUnit.SECONDS) + writeTimeout(120L, TimeUnit.SECONDS) + + if (BuildConfig.DEBUG) { + val loggingInterceptor = HttpLoggingInterceptor() + loggingInterceptor.level = HttpLoggingInterceptor.Level.HEADERS + addInterceptor(loggingInterceptor) + } + return build() + } + } +} \ No newline at end of file diff --git a/sample-app/app/src/main/java/com/socure/docv/sdk/sample/MainActivity.kt b/sample-app/app/src/main/java/com/socure/docv/sdk/sample/MainActivity.kt index a718879..3f24365 100644 --- a/sample-app/app/src/main/java/com/socure/docv/sdk/sample/MainActivity.kt +++ b/sample-app/app/src/main/java/com/socure/docv/sdk/sample/MainActivity.kt @@ -6,17 +6,39 @@ import android.content.pm.PackageManager import android.net.Uri import android.os.Bundle import android.provider.Settings +import android.util.Log import android.widget.Button import android.widget.Toast import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContentProviderCompat.requireContext import androidx.core.content.ContextCompat +import androidx.core.content.ContextCompat.startActivity +import androidx.lifecycle.lifecycleScope import com.google.android.material.snackbar.Snackbar -import com.socure.docv.capturesdk.api.SocureDocVHelper +import com.socure.docv.capturesdk.api.SocureDocVContext +import com.socure.docv.capturesdk.api.SocureDocVError +import com.socure.docv.capturesdk.api.SocureSdk import com.socure.docv.capturesdk.common.utils.ResultListener -import com.socure.docv.capturesdk.common.utils.ScanError -import com.socure.docv.capturesdk.common.utils.ScannedData +import com.socure.docv.capturesdk.common.utils.SocureDocVFailure +import com.socure.docv.capturesdk.common.utils.SocureDocVSuccess +import com.socure.docv.capturesdk.common.utils.SocureResult +import java.util.concurrent.TimeUnit +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.http.Body +import retrofit2.http.HeaderMap +import retrofit2.http.POST + +private const val TAG = "MainActivity" +private const val ID_PLUS_KEY = "YOUR_ID_PLUS_KEY" +private const val PUBLIC_KEY = "YOUR_PUBLIC_KEY" class MainActivity : AppCompatActivity() { @@ -36,35 +58,72 @@ class MainActivity : AppCompatActivity() { // initiate Socure SDK private fun launchSocureSdk() { - startForResult.launch( - SocureDocVHelper.getIntent(this, "YOUR_SOCURE_API_KEY", null) - ) + lifecycleScope.launch(Dispatchers.IO) { + runCatching { + transaction() + .createTransaction( + createHeaderMap(), + TransactionRequest( + config = TransactionRequest.TransactionConfig( + useCaseKey = "socure_default" + ), + ) + ) + }.onSuccess { + startForResult.launch( + SocureSdk.getIntent( + this@MainActivity, + SocureDocVContext( + it.data.docvTransactionToken, + PUBLIC_KEY, + false + ) + ) + ) + }.onFailure { + withContext(Dispatchers.Main) { + Toast.makeText( + this@MainActivity, + "Failed to get transaction token", + Toast.LENGTH_SHORT + ).show() + } + } + } } // handle response from Socure SDK private var startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> result.data?.let { - SocureDocVHelper.getResult(it, object : ResultListener { - override fun onSuccess(scannedData: ScannedData) { + SocureSdk.getResult(it) { result -> + Log.d(TAG, "onResult called: $result") + if (result is SocureDocVSuccess) { Toast.makeText( this@MainActivity, - "Success -> Session ID: ${scannedData.sessionId}", - Toast.LENGTH_LONG + "onSuccess called: ${result.sessionToken}", + Toast.LENGTH_SHORT ).show() - } - - override fun onError(scanError: ScanError) { + } else { + val error = result as? SocureDocVFailure Toast.makeText( this@MainActivity, - "Failure: ${scanError.statusCode} -> ${scanError.errorMessage}", - Toast.LENGTH_LONG + "onError called: ${error?.sessionToken}, ${error?.error}", + Toast.LENGTH_SHORT ).show() } - }) + } } } + private fun createHeaderMap(): Map { + val headerMap = mutableMapOf() + headerMap["Authorization"] = "SocureApiKey".plus(" ") + .plus(ID_PLUS_KEY) + headerMap["content-type"] = "application/json" + return headerMap + } + // is camera permission granted private fun isCameraPermissionGranted() = ContextCompat.checkSelfPermission( this, @@ -94,5 +153,4 @@ class MainActivity : AppCompatActivity() { .show() } } - -} \ No newline at end of file +} diff --git a/sample-app/build.gradle b/sample-app/build.gradle index 0932efc..8984e2c 100644 --- a/sample-app/build.gradle +++ b/sample-app/build.gradle @@ -2,9 +2,9 @@ plugins { id 'com.android.application' version '7.1.2' apply false id 'com.android.library' version '7.1.2' apply false - id 'org.jetbrains.kotlin.android' version '1.6.21' apply false + id 'org.jetbrains.kotlin.android' version '1.8.0' apply false } task clean(type: Delete) { delete rootProject.buildDir -} \ No newline at end of file +}