-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Android sample application in Kotlin
Android sample application in Kotlin with quickcapture document scanning sdk implementation.With full help doc and technical documentation for developers for easier implementation and try.
- Loading branch information
1 parent
0bb7081
commit ac021b8
Showing
35 changed files
with
1,081 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
plugins { | ||
id 'com.android.application' | ||
id 'org.jetbrains.kotlin.android' | ||
} | ||
|
||
android { | ||
namespace 'com.extrieve.quickcapture.docappkotlin' | ||
compileSdk 33 | ||
|
||
defaultConfig { | ||
applicationId "com.extrieve.quickcapture.docappkotlin" | ||
minSdk 21 | ||
targetSdk 33 | ||
versionCode 1 | ||
versionName "1.0" | ||
|
||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
} | ||
|
||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
} | ||
} | ||
compileOptions { | ||
sourceCompatibility JavaVersion.VERSION_1_8 | ||
targetCompatibility JavaVersion.VERSION_1_8 | ||
} | ||
kotlinOptions { | ||
jvmTarget = '1.8' | ||
} | ||
} | ||
|
||
dependencies { | ||
|
||
implementation 'androidx.core:core-ktx:1.8.0' | ||
implementation 'androidx.appcompat:appcompat:1.6.1' | ||
implementation 'com.google.android.material:material:1.5.0' | ||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' | ||
implementation 'com.extrieve.quickcapture:QCv2:2.1.2' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Add project specific ProGuard rules here. | ||
# You can control the set of applied configuration files using the | ||
# proguardFiles setting in build.gradle. | ||
# | ||
# For more details, see | ||
# http://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# If your project uses WebView with JS, uncomment the following | ||
# and specify the fully qualified class name to the JavaScript interface | ||
# class: | ||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
# public *; | ||
#} | ||
|
||
# Uncomment this to preserve the line number information for | ||
# debugging stack traces. | ||
#-keepattributes SourceFile,LineNumberTable | ||
|
||
# If you keep the line number information, uncomment this to | ||
# hide the original source file name. | ||
#-renamesourcefileattribute SourceFile |
24 changes: 24 additions & 0 deletions
24
...pp/src/androidTest/java/com/extrieve/quickcapture/docappkotlin/ExampleInstrumentedTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.extrieve.quickcapture.docappkotlin | ||
|
||
import androidx.test.platform.app.InstrumentationRegistry | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
|
||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
import org.junit.Assert.* | ||
|
||
/** | ||
* Instrumented test, which will execute on an Android device. | ||
* | ||
* See [testing documentation](http://d.android.com/tools/testing). | ||
*/ | ||
@RunWith(AndroidJUnit4::class) | ||
class ExampleInstrumentedTest { | ||
@Test | ||
fun useAppContext() { | ||
// Context of the app under test. | ||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext | ||
assertEquals("com.extrieve.quickcapture.docappkotlin", appContext.packageName) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools"> | ||
|
||
<application | ||
android:allowBackup="true" | ||
android:dataExtractionRules="@xml/data_extraction_rules" | ||
android:fullBackupContent="@xml/backup_rules" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:supportsRtl="true" | ||
android:theme="@style/Theme.DocAppKotlin" | ||
tools:targetApi="31"> | ||
<activity | ||
android:name=".MainActivity" | ||
android:exported="true"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
|
||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
</application> | ||
|
||
</manifest> |
194 changes: 194 additions & 0 deletions
194
kotlin_sample/app/src/main/java/com/extrieve/quickcapture/docappkotlin/MainActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
package com.extrieve.quickcapture.docappkotlin | ||
|
||
import android.content.ContextWrapper | ||
import android.content.Intent | ||
import android.content.pm.PackageManager | ||
import android.graphics.BitmapFactory | ||
import android.net.Uri | ||
import android.os.Build | ||
import androidx.appcompat.app.AppCompatActivity | ||
import android.os.Bundle | ||
import android.util.Log | ||
import android.view.View | ||
import android.widget.ImageView | ||
import android.widget.Toast | ||
import androidx.activity.result.ActivityResult | ||
import androidx.activity.result.ActivityResultLauncher | ||
import androidx.activity.result.contract.ActivityResultContracts | ||
import androidx.core.app.ActivityCompat | ||
import androidx.core.content.ContextCompat | ||
import java.io.File | ||
import java.io.IOException | ||
|
||
import com.extrieve.quickcapture.sdk.*; | ||
|
||
class MainActivity : AppCompatActivity() { | ||
/*DEV_HELP : Declare variables for the classes from SDK*/ | ||
private var cameraHelper: CameraHelper? = null | ||
private var imageHelper: ImgHelper? = null | ||
|
||
/*DEV_HELP : Declare variables for ActivityResultLauncher to accept result from camera activity | ||
* As CameraHelper is an activity based class*/ | ||
private var captureActivityResultLauncher: ActivityResultLauncher<Intent>? = null | ||
private val REQUIREDPERMISSIONS = arrayOf("android.permission.CAMERA") | ||
var fileCollection: ArrayList<String>? = null | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(R.layout.activity_main) | ||
checkAndPromptPermissions() | ||
|
||
/*DEV_HELP : Initialise object of ImgHelper class.Pass the current activity context*/ | ||
imageHelper = ImgHelper(this) | ||
/*DEV_HELP : Initialise object CameraHelper*/ | ||
cameraHelper = CameraHelper() | ||
|
||
/*DEV_HELP : assign registerForActivityResult for getting result from CameraHelper*/ | ||
captureActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { | ||
result: ActivityResult -> handleCaptureActivityResult(result) | ||
} | ||
|
||
/*DEV_HELP : Capture Document with SDK Button click handler*/ | ||
findViewById<View>(R.id.getPictureButton).setOnClickListener { | ||
setConfig() | ||
openCameraActivity() | ||
} | ||
} | ||
|
||
/*DEV_HELP : Basic permission for App/SDK to work*/ | ||
private fun checkAndPromptPermissions() { | ||
for (permission in REQUIREDPERMISSIONS) { | ||
if (ContextCompat.checkSelfPermission( | ||
this, | ||
permission | ||
) != PackageManager.PERMISSION_GRANTED | ||
) { | ||
ActivityCompat.requestPermissions( | ||
this, | ||
REQUIREDPERMISSIONS, | ||
REQUEST_CODE_PERMISSIONS | ||
) | ||
} | ||
} | ||
} | ||
|
||
override fun onRequestPermissionsResult( | ||
requestCode: Int, | ||
permissions: Array<String>, | ||
grantResults: IntArray | ||
) { | ||
super.onRequestPermissionsResult(requestCode, permissions, grantResults) | ||
if (requestCode == REQUEST_CODE_PERMISSIONS) { | ||
for (permission in REQUIREDPERMISSIONS) { | ||
if (ContextCompat.checkSelfPermission( | ||
this, | ||
permission | ||
) != PackageManager.PERMISSION_GRANTED | ||
) { | ||
Toast.makeText(this, "Permissions not granted by the user.", Toast.LENGTH_SHORT) | ||
.show() | ||
finish() | ||
} | ||
//Got permission | ||
} | ||
} | ||
} | ||
|
||
/*DEV_HELP : SetUp SDKConfig - Refer tech. Doc. for further info.*/ | ||
private fun setConfig() { | ||
imageHelper!!.SetPageLayout(4) //A1-A7(1-7),PHOTO,CUSTOM,ID(8,9,10) | ||
imageHelper!!.SetImageQuality(1) //0,1,2 - Photo_Quality, Document_Quality, Compressed_Document | ||
imageHelper!!.SetDPI(200) //int dpi_val = 100, 150, 200, 300, 500, 600; | ||
|
||
//can set output file path | ||
CameraSupport.CamConfigClass.OutputPath = buildStoragePath() | ||
} | ||
|
||
/*DEV_HELP : BuildStoragePath*/ | ||
private fun buildStoragePath(): String { | ||
val c = ContextWrapper(this) | ||
return c.getExternalFilesDir(".GoNoGoImages")!!.absolutePath | ||
} | ||
|
||
/*DEV_HELP : handleCaptureActivityResult definition*/ | ||
private fun handleCaptureActivityResult(result: ActivityResult) { | ||
run { | ||
val resultCode = result.resultCode | ||
if (resultCode != RESULT_OK) { | ||
return | ||
} | ||
val data = result.data | ||
var status: Boolean? = null | ||
if (data != null) { | ||
status = data.extras!!["STATUS"] as Boolean? | ||
} | ||
val description = data!!.extras!!["DESCRIPTION"] as String? | ||
if (!status!!) { | ||
val imageCaptureLog = "Description : " + description + | ||
".Exception: " + CameraSupport.CamConfigClass.LastLogInfo | ||
Log.d("INFO", imageCaptureLog) | ||
Toast.makeText(this, imageCaptureLog, Toast.LENGTH_LONG).show() | ||
finishActivity(MainActivity.Companion.REQUEST_CODE_FILE_RETURN) | ||
return | ||
} | ||
fileCollection = data.extras!!["fileCollection"] as ArrayList<String>? | ||
if (fileCollection == null || fileCollection!!.isEmpty()) return | ||
try { | ||
showImages(fileCollection!!) | ||
} catch (e: IOException) { | ||
e.printStackTrace() | ||
} | ||
finishActivity(REQUEST_CODE_FILE_RETURN) | ||
} | ||
} | ||
|
||
/*DEV_HELP : showImages*/ | ||
@Throws(IOException::class) | ||
private fun showImages(FilesPath: ArrayList<String>) { | ||
val fileCollectionLength = FilesPath.size | ||
for (i in 0 until fileCollectionLength) { | ||
val dir = FilesPath[i] | ||
val imgFile = File(dir) | ||
//notifyMediaStoreScanner(imgFile); | ||
if (imgFile.exists()) { | ||
val myBitmap = BitmapFactory.decodeFile(imgFile.absolutePath) | ||
val myImage = findViewById<ImageView>(R.id.displayImageView) | ||
myImage.setImageBitmap(myBitmap) | ||
} | ||
Toast.makeText(this, "SDK captured $fileCollectionLength images.", Toast.LENGTH_SHORT) | ||
.show() | ||
} | ||
} | ||
|
||
/*DEV_HELP : OpenCameraActivity*/ | ||
private fun openCameraActivity() { | ||
|
||
/*DEV_HELP : Check basic permissions for camera if needed*/ | ||
//if (!MainActivity.this.allPermissionsGranted()) { | ||
//Toast.makeText(MainActivity.this, "Permissions not granted by the user.", Toast.LENGTH_SHORT).show(); | ||
/*DEV_HELP : TODO : handle invalid permission*/ | ||
// return; | ||
// } | ||
try { | ||
/*DEV_HELP :redirecting to camera*/ | ||
val captureIntent = Intent(this, Class.forName("com.extrieve.quickcapture.sdk.CameraHelper")) | ||
val photoURI = Uri.parse(CameraSupport.CamConfigClass.OutputPath) | ||
grantUriPermission( | ||
this.packageName, photoURI, | ||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION | ||
) | ||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) { | ||
captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) | ||
} | ||
captureActivityResultLauncher!!.launch(captureIntent) | ||
} catch (ex: Exception) { | ||
/*DEV_HELP : TODO : handle invalid Exception*/ | ||
Toast.makeText(this, "Failed to open camera -" + ex.message, Toast.LENGTH_LONG).show() | ||
} | ||
} | ||
|
||
companion object { | ||
private const val REQUEST_CODE_PERMISSIONS = 1001 | ||
private const val REQUEST_CODE_FILE_RETURN = 1004 | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
kotlin_sample/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:aapt="http://schemas.android.com/aapt" | ||
android:width="108dp" | ||
android:height="108dp" | ||
android:viewportWidth="108" | ||
android:viewportHeight="108"> | ||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> | ||
<aapt:attr name="android:fillColor"> | ||
<gradient | ||
android:endX="85.84757" | ||
android:endY="92.4963" | ||
android:startX="42.9492" | ||
android:startY="49.59793" | ||
android:type="linear"> | ||
<item | ||
android:color="#44000000" | ||
android:offset="0.0" /> | ||
<item | ||
android:color="#00000000" | ||
android:offset="1.0" /> | ||
</gradient> | ||
</aapt:attr> | ||
</path> | ||
<path | ||
android:fillColor="#FFFFFF" | ||
android:fillType="nonZero" | ||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" | ||
android:strokeWidth="1" | ||
android:strokeColor="#00000000" /> | ||
</vector> |
Oops, something went wrong.