/** * Docutain SDK Capacitor * Copyright (c) INFOSOFT Informations- und Dokumentationssysteme GmbH. All rights reserved. * * Docutain SDK Capacitor is a commercial product and requires a license. * Details found in the LICENSE file in the root directory of this source tree. */ /** * Docutain SDK Capacitor * Copyright (c) INFOSOFT Informations- und Dokumentationssysteme GmbH. All rights reserved. * * Docutain SDK Capacitor is a commercial product and requires a license. * Details found in the LICENSE file in the root directory of this source tree. */ package com.docutain.plugin.capacitor import android.app.Activity import android.net.Uri import android.util.Log import android.view.View import androidx.activity.result.ActivityResult import com.getcapacitor.JSObject import com.getcapacitor.Plugin import com.getcapacitor.PluginCall import com.getcapacitor.PluginMethod import com.getcapacitor.annotation.ActivityCallback import com.getcapacitor.annotation.CapacitorPlugin import de.docutain.sdk.Document import de.docutain.sdk.DocutainSDK import de.docutain.sdk.Logger import de.docutain.sdk.dataextraction.AnalyzeConfiguration import de.docutain.sdk.dataextraction.DocumentDataReader import de.docutain.sdk.ui.DocumentScanner import de.docutain.sdk.ui.DocumentScannerConfiguration import de.docutain.sdk.ui.DocutainButton import de.docutain.sdk.ui.DocutainColor import de.docutain.sdk.ui.ScanFilter import de.docutain.sdk.ui.Source import de.docutain.sdk.ui.StatusBarAppearance import de.docutain.sdk.ui.NavigationBarAppearance import de.docutain.sdk.ui.Onboarding import de.docutain.sdk.ui.scantips.ScanTips import de.docutain.sdk.ui.ScanHintPopup import de.docutain.sdk.ui.DocutainListItem import de.docutain.sdk.ui.photopayment.PhotoPaymentResult import de.docutain.sdk.ui.photopayment.PhotoPaymentConfiguration import de.docutain.sdk.ui.photopayment.PaymentAnalyzeConfiguration import de.docutain.sdk.ui.EmptyResultScreen import de.docutain.sdk.ui.BaseScannerConfiguration import de.docutain.sdk.ui.ButtonConfiguration import de.docutain.sdk.ui.ColorConfiguration import de.docutain.sdk.ui.PageEditConfiguration import de.docutain.sdk.ui.TextConfiguration import org.json.JSONArray import org.json.JSONObject import java.io.File import android.util.Base64 @CapacitorPlugin(name = "DocutainSDK") class DocutainSDKPlugin : Plugin() { private val implementation = DocutainSDK private val logTag = "DocutainSdk" private val canceledState = "CANCELED" @PluginMethod fun initSDK(call: PluginCall) { Log.v(logTag, "InitSDK Start") val licenseKey = call.getString("licenseKey") if(!DocutainSDK.initSDK(this.context.applicationContext as android.app.Application, licenseKey!!)){ //init of Docutain SDK failed, get the last error message Log.e(logTag, "Initialization of the Docutain SDK failed: ${DocutainSDK.getLastError()}") //your logic to deactivate access to SDK functionality call.reject(DocutainSDK.getLastError()) } else { call.resolve() } } @PluginMethod fun deleteTempFiles(call: PluginCall) { try { var deleteTraceFileContent = call.getBoolean("deleteTraceFileContent") ?: false Log.v(logTag, "deleteTempFiles" + deleteTraceFileContent) if(DocutainSDK.deleteTempFiles(deleteTraceFileContent)) call.resolve() else call.reject(DocutainSDK.getLastError()) } catch (ex: Exception) { Log.e(logTag, "deleteTempFiles Exception" + ex) call.reject("deleteTempFiles", ex); } } @PluginMethod fun setLogLevel(call: PluginCall) { val LogLevel = call.getString("logLevel") Log.v(logTag, "setLogLevel:" + LogLevel) if(LogLevel.isNullOrEmpty()) { call.reject("LogLevel is null") } else { try { val logLevel: Logger.Level = getLogLevelFromString(LogLevel); Log.d(logTag, "setLogLevel " + logLevel) Logger.setLogLevel(logLevel); call.resolve() } catch (ex: Exception) { Log.e(logTag, "setLogLevel Exception" + ex) call.reject("setLogLevel", ex); } } } @PluginMethod fun getTraceFile(call: PluginCall) { try { val traceFile = Logger.getTraceFile(); val ret = JSObject() ret.put("fileUri", Uri.fromFile(traceFile).toString()) call.resolve(ret); } catch(ex:Exception ) { Log.e(logTag, "getTraceFile Exception"+ ex) call.reject("getTraceFile", ex); } } @PluginMethod fun setAnalyzeConfiguration(call: PluginCall) { Log.v(logTag, "setAnalyzeConfiguration") val analyzeConfig = AnalyzeConfiguration() val config = call.getObject("config") if(config == null){ call.reject("config not provided") return } mapAnalyzeConfiguration(config, analyzeConfig); if(!DocumentDataReader.setAnalyzeConfiguration(analyzeConfig)){ Log.e(logTag,"Setting AnalyzeConfiguration failed: ${DocutainSDK.getLastError()}") call.reject(DocutainSDK.getLastError()); } else { call.resolve() } } @PluginMethod fun setAnalyzeConfigurationDocScan(call: PluginCall) { Log.v(logTag, "setAnalyzeConfigurationDocScan") val analyzeConfig = AnalyzeConfiguration() mapAnalyzeConfiguration(call.data, analyzeConfig); if(!DocumentDataReader.setAnalyzeConfiguration(analyzeConfig)){ Log.e(logTag,"Setting AnalyzeConfiguration failed: ${DocutainSDK.getLastError()}") call.reject(DocutainSDK.getLastError()); } else { call.resolve() } } @PluginMethod fun scanDocument(call: PluginCall) { Log.v(logTag, "scanDocument Start") try { val nativeScanConfig = DocumentScannerConfiguration() val options = call.getObject("config") if(options == null){ call.reject("config not provided") } else { if(!mapDocumentScannerConfiguration(options, nativeScanConfig,true)) { call.reject("DocumentScannerConfiguration not valid") return } } val intent = DocumentScanner.newScanIntent(context.applicationContext, nativeScanConfig) startActivityForResult(call, intent, "scanResult") Log.v(logTag, "scanDocument start OK") } catch(ex:Exception ) { Log.e(logTag, "scanDocument Exception "+ ex) call.reject("scanDocument", ex); } } @PluginMethod fun startDocumentScanner(call: PluginCall) { Log.v(logTag, "startDocumentScanner Start") try { val nativeScanConfig = DocumentScannerConfiguration() if(!mapDocumentScannerConfiguration(call.data, nativeScanConfig)) { call.reject("StartDocumentScannerOptions not valid") return } val intent = DocumentScanner.newScanIntent(context.applicationContext, nativeScanConfig) startActivityForResult(call, intent, "startDocumentScannerResult") Log.v(logTag, "scanDocument start OK") } catch(ex:Exception ) { Log.e(logTag, "scanDocument Exception "+ ex) call.reject("scanDocument", ex); } } @PluginMethod fun loadFile(call: PluginCall) { try { val filepath = call.getString("filepath") val fileUri:Uri = Uri.parse(filepath) Log.v(logTag, "loadFile:" + fileUri) val rc = DocumentDataReader.loadFile(fileUri) Log.d(logTag, "loadFile rc:" + rc) if(rc) call.resolve() else call.reject(DocutainSDK.getLastError()) } catch(ex:Exception ) { Log.e(logTag, "loadFile Exception"+ ex) call.reject("loadFile", ex); } } @PluginMethod fun writePDF(call: PluginCall) { try { var overWrite = call.getBoolean("overWrite", true) //filepath: String, overWrite: Boolean, PageFormat: String, promise: Promise var filepath = call.getString("fileUri") if(filepath.isNullOrEmpty()){ overWrite = true; filepath = DocutainSDK.context.getFilesDir().absolutePath + "/Docutain/Temp/Docutain.pdf"; } val pageFormat = call.getString("pageFormat", "A4") val PDFFormat: Document.PDFPageFormat = getPDFPageFormatFromString(pageFormat!!) var maxSizeKB = call.getInt("maxSizeKB") if(maxSizeKB == null){ maxSizeKB = 0 } //needs to be an absolut path to the file filepath = filepath.replace("file://", "") val ret = JSObject() val file = File(filepath); if(file != null) { val rc = Document.writePDF(file, overWrite!!, PDFFormat, maxSizeKB) if(rc == null){ call.reject(DocutainSDK.getLastError()); return } ret.put("fileUri", Uri.fromFile(rc).toString()) call.resolve(ret) } else{ call.reject("invalid fileUri provided"); } } catch(ex:Exception ) { Log.e(logTag, "writePDF Exception "+ ex) call.reject("writePDF", ex); } } @PluginMethod fun writeImage(call: PluginCall) { try { var filepath = call.getString("fileUri") if(filepath.isNullOrEmpty()){ call.reject("no fileUri provided") return } val pageNumber = call.getInt("pageNumber") if(pageNumber == null){ call.reject("no pageNumber provided") return } //needs to be an absolut path to the file filepath = filepath.replace("file://", "") val file = File(filepath); if(file == null){ call.reject("invalid fileUri provided"); return; } val rc = Document.writeImage(pageNumber, file); if(rc == null){ call.reject(DocutainSDK.getLastError()); return } val ret = JSObject() ret.put("fileUri", Uri.fromFile(rc).toString()) call.resolve(ret) } catch(ex:Exception ) { Log.e(logTag, "writeImage Exception "+ ex) call.reject("writeImage", ex); } } @PluginMethod fun getImageBytes(call: PluginCall) { try { val pageSourceType = call.getString("pageSourceType", "CUT_FILTER") val pageNumber = call.getInt("pageNumber") if(pageNumber == null){ call.reject("no pageNumber provided") return } val sourceType: Document.PageSourceType = getPageSourceTypeFromString(pageSourceType!!); val bytes = Document.getImageBytes(pageNumber, sourceType) if(bytes == null){ call.reject(DocutainSDK.getLastError()); } else{ val ret = JSObject() ret.put("bytes", Base64.encodeToString(bytes, Base64.NO_WRAP)) call.resolve(ret) } } catch(ex:Exception ) { Log.e(logTag, "getImageBytes Exception"+ ex) call.reject("getImageBytes", ex); } } @PluginMethod fun getText(call: PluginCall) { Log.v(logTag, "getText") try { val text = DocumentDataReader.getText() if(text == null) { call.reject(DocutainSDK.getLastError()) } else{ val ret = JSObject() ret.put("text", text) call.resolve(ret); } } catch(ex:Exception ) { Log.e(logTag, "getText Exception"+ ex) call.reject("getText", ex); } } @PluginMethod fun getTextPage(call: PluginCall) { //pageNumber: Int, promise: Promise try { val pageNumber = call.getInt("pageNumber") if(pageNumber == null){ call.reject("no pageNumber provided") return } val text = DocumentDataReader.getText(pageNumber); if(text == null) { call.reject(DocutainSDK.getLastError()) } else{ val ret = JSObject() ret.put("text", text) call.resolve(ret); } } catch(ex:Exception ) { Log.e(logTag, "getTextPage Exception"+ ex) call.reject("getTextPage", ex); } } @PluginMethod fun analyze(call: PluginCall) { Log.v(logTag, "analyze") try { val text = DocumentDataReader.analyze() val ret = JSObject() ret.put("data", text) call.resolve(ret); } catch(ex:Exception) { Log.e(logTag, "analyze Exception"+ ex) call.reject("analyze", ex); } } @PluginMethod fun pageCount(call: PluginCall) { try { val ret = JSObject() ret.put("count", Document.pageCount()) call.resolve(ret); } catch(ex:Exception ) { Log.e(logTag, "pageCount Exception" + ex) call.reject("pageCount", ex); } } companion object { const val NAME = "DocutainSdk" } private fun getLogLevelFromString(loglevel: String) : Logger.Level { when (loglevel.uppercase()) { "DISABLE" -> return Logger.Level.DISABLE; "ASSERT" -> return Logger.Level.ASSERT; "ERROR" -> return Logger.Level.ERROR; "WARNING" -> return Logger.Level.WARNING; "INFO" -> return Logger.Level.INFO; "DEBUG" -> return Logger.Level.DEBUG; "VERBOSE" -> return Logger.Level.VERBOSE; else -> return Logger.Level.ERROR; } } private fun getScanFilterFromString(scanFilter: String) : ScanFilter { when (scanFilter.uppercase()) { "AUTO" -> return ScanFilter.AUTO; "GRAY" -> return ScanFilter.GRAY; "BLACKWHITE" -> return ScanFilter.BLACKWHITE; "ORIGINAL" -> return ScanFilter.ORIGINAL; "TEXT" -> return ScanFilter.TEXT; "AUTO2" -> return ScanFilter.AUTO2; "ILLUSTRATION" -> return ScanFilter.ILLUSTRATION; else -> return ScanFilter.ILLUSTRATION; } } private fun getScanSourceFromString(scanSource: String) : Source { when (scanSource.uppercase()) { "CAMERA" -> return Source.CAMERA; "IMAGE" -> return Source.IMAGE; "GALLERY" -> return Source.GALLERY; "GALLERY_MULTIPLE" -> return Source.GALLERY_MULTIPLE; "CAMERA_IMPORT" -> return Source.CAMERA_IMPORT; else -> return Source.CAMERA; } } private fun getPDFPageFormatFromString(pageFormat: String) : Document.PDFPageFormat { when (pageFormat.uppercase()) { "FIT_TO_PAGES" -> return Document.PDFPageFormat.FIT_TO_PAGES; "A4" -> return Document.PDFPageFormat.A4; "A4_LANDSCAPE" -> return Document.PDFPageFormat.A4_LANDSCAPE; "A5" -> return Document.PDFPageFormat.A5; "A5_LANDSCAPE" -> return Document.PDFPageFormat.A5_LANDSCAPE; "LETTER" -> return Document.PDFPageFormat.LETTER; "LETTER_LANDSCAPE" -> return Document.PDFPageFormat.LETTER_LANDSCAPE; "LEGAL" -> return Document.PDFPageFormat.LEGAL; "LEGAL_LANDSCAPE" -> return Document.PDFPageFormat.LEGAL_LANDSCAPE; else -> return Document.PDFPageFormat.A4; } } private fun getPageSourceTypeFromString(pageSourceType: String) : Document.PageSourceType { when (pageSourceType.uppercase()) { "ORIGINAL" -> return Document.PageSourceType.ORIGINAL; "CUT_FILTER" -> return Document.PageSourceType.CUT_FILTER; "CUT_ONLY" -> return Document.PageSourceType.CUT_ONLY; else -> return Document.PageSourceType.CUT_FILTER; } } private fun getStatusBarAppearanceFromString(statusBarAppearance: String) : StatusBarAppearance { when (statusBarAppearance.uppercase()) { "LIGHT" -> return StatusBarAppearance.LIGHT; else -> return StatusBarAppearance.DARK; } } private fun getNavigationBarAppearanceFromString(navigationBarAppearance: String) : NavigationBarAppearance { when (navigationBarAppearance.uppercase()) { "LIGHT" -> return NavigationBarAppearance.LIGHT; else -> return NavigationBarAppearance.DARK; } } private fun mapAnalyzeConfiguration(config: JSObject, analyzeConfig: AnalyzeConfiguration) { if(config.has("readBIC")) analyzeConfig.readBIC = config.getBoolean("readBIC") if(config.has("readPaymentState")) analyzeConfig.readPaymentState = config.getBoolean("readPaymentState") if(config.has("readSEPACreditor")) analyzeConfig.readSEPACreditor = config.getBoolean("readSEPACreditor") } private fun setButtonConfig(docutainButton: DocutainButton, docutainButtonEntry: JSObject) { if(docutainButtonEntry!=null) { if (docutainButtonEntry.has("title")) docutainButton.title = docutainButtonEntry.getString("title"); if (docutainButtonEntry.has("icon")){ val imgSource = docutainButtonEntry.getString("icon")!! val imgIdentifier = DocutainSDK.context.resources.getIdentifier(imgSource, "drawable", DocutainSDK.context.packageName) docutainButton.icon = imgIdentifier } } } private fun setPageEditConfig(pageEditConfig: PageEditConfiguration, optionsPageEditConfig: JSObject?) { if(optionsPageEditConfig != null){ if (optionsPageEditConfig.has("allowPageFilter")) { pageEditConfig.allowPageFilter = optionsPageEditConfig.getBoolean("allowPageFilter") } if (optionsPageEditConfig.has("allowPageRotation")) { pageEditConfig.allowPageRotation = optionsPageEditConfig.getBoolean("allowPageRotation") } if(optionsPageEditConfig.has("allowPageArrangement")) { pageEditConfig.allowPageArrangement = optionsPageEditConfig.getBoolean("allowPageArrangement") } if(optionsPageEditConfig.has("allowPageCropping")) { pageEditConfig.allowPageCropping = optionsPageEditConfig.getBoolean("allowPageCropping") } if(optionsPageEditConfig.has("allowPageRetake")) { pageEditConfig.allowPageRetake = optionsPageEditConfig.getBoolean("allowPageRetake") } if(optionsPageEditConfig.has("allowPageAdd")) { pageEditConfig.allowPageAdd = optionsPageEditConfig.getBoolean("allowPageAdd") } if(optionsPageEditConfig.has("allowPageDeletion")) { pageEditConfig.allowPageDeletion = optionsPageEditConfig.getBoolean("allowPageDeletion") } if(optionsPageEditConfig.has("pageArrangementShowDeleteButton")) { pageEditConfig.pageArrangementShowDeleteButton = optionsPageEditConfig.getBoolean("pageArrangementShowDeleteButton") } if(optionsPageEditConfig.has("pageArrangementShowPageNumber")) { pageEditConfig.pageArrangementShowPageNumber = optionsPageEditConfig.getBoolean("pageArrangementShowPageNumber") } } } private fun setColorConfig( colorConfig: ColorConfiguration, optionsColorConfig: JSObject?) { if(optionsColorConfig != null) { val keysIter = optionsColorConfig.keys(); val keys: MutableList = ArrayList() while (keysIter.hasNext()) { val key = keysIter.next() val docutainColorEntry = optionsColorConfig.getJSObject(key) if(docutainColorEntry != null){ val light = docutainColorEntry.getString("Light") val dark = docutainColorEntry.getString("Dark") if(light != null && dark != null) { val docutainColor = DocutainColor(light, dark) Log.v("DocutainSdkFull", key + " Light:" + light + " Dark:" + dark) when (key.uppercase()) { "COLORPRIMARY" -> colorConfig.colorPrimary = docutainColor "COLORONPRIMARY" -> colorConfig.colorOnPrimary = docutainColor "COLORSECONDARY" -> colorConfig.colorSecondary = docutainColor "COLORONSECONDARY" -> colorConfig.colorOnSecondary = docutainColor "COLORSCANBUTTONSLAYOUTBACKGROUND" -> colorConfig.colorScanButtonsLayoutBackground = docutainColor "COLORSCANBUTTONSFOREGROUND" -> colorConfig.colorScanButtonsForeground = docutainColor "COLORSCANPOLYGON" -> colorConfig.colorScanPolygon = docutainColor "COLORBOTTOMBARBACKGROUND" -> colorConfig.colorBottomBarBackground = docutainColor "COLORBOTTOMBARFOREGROUND" -> colorConfig.colorBottomBarForeground = docutainColor "COLORTOPBARBACKGROUND" -> colorConfig.colorTopBarBackground = docutainColor "COLORTOPBARFOREGROUND" -> colorConfig.colorTopBarForeground = docutainColor "COLORTOPBARTITLE" -> colorConfig.colorTopBarTitle = docutainColor else -> Log.e("DocutainSdkFull", "mapDocumentScannerConfiguration color not valid "+ key) } } } } } } private fun setTextConfig(textConfig: TextConfiguration, optionsTextConfig: JSObject?) { if(optionsTextConfig != null){ if (optionsTextConfig.has("textSizeBottomToolbar")) textConfig.textSizeBottomToolbar = optionsTextConfig.getDouble("textSizeBottomToolbar").toFloat() if (optionsTextConfig.has("textSizeTopToolbar")) textConfig.textSizeTopToolbar = optionsTextConfig.getDouble("textSizeTopToolbar").toFloat() if (optionsTextConfig.has("textSizeScanButtons")) textConfig.textSizeScanButtons = optionsTextConfig.getDouble("textSizeScanButtons").toFloat() if (optionsTextConfig.has("textSizeTitle")) textConfig.textSizeTitle = optionsTextConfig.getDouble("textSizeTitle").toFloat() if (optionsTextConfig.has("textTitleScanPage")) textConfig.textTitleScanPage = optionsTextConfig.getString("textTitleScanPage") if (optionsTextConfig.has("textTitleEditPage")) textConfig.textTitleEditPage = optionsTextConfig.getString("textTitleEditPage") if (optionsTextConfig.has("textTitleFilterPage")) textConfig.textTitleFilterPage = optionsTextConfig.getString("textTitleFilterPage") if (optionsTextConfig.has("textTitleCroppingPage")) textConfig.textTitleCroppingPage = optionsTextConfig.getString("textTitleCroppingPage") if (optionsTextConfig.has("textTitleArrangementPage")) textConfig.textTitleArrangementPage = optionsTextConfig.getString("textTitleArrangementPage") if (optionsTextConfig.has("textTitleConfirmationPage")) textConfig.textTitleConfirmationPage = optionsTextConfig.getString("textTitleConfirmationPage") if (optionsTextConfig.has("textDocumentTitle")) textConfig.textDocumentTitle = optionsTextConfig.getString("textDocumentTitle") if (optionsTextConfig.has("textFocusHint")) textConfig.textFocusHint = optionsTextConfig.getString("textFocusHint") if (optionsTextConfig.has("textFirstPageHint")) textConfig.textFirstPageHint = optionsTextConfig.getString("textFirstPageHint") if (optionsTextConfig.has("textLastPageHint")) textConfig.textLastPageHint = optionsTextConfig.getString("textLastPageHint") if (optionsTextConfig.has("textOnePageHint")) textConfig.textOnePageHint = optionsTextConfig.getString("textOnePageHint") if (optionsTextConfig.has("textScanProgress")) textConfig.textScanProgress = optionsTextConfig.getString("textScanProgress") if (optionsTextConfig.has("textDeleteDialogCurrentPage")) textConfig.textDeleteDialogCurrentPage = optionsTextConfig.getString("textDeleteDialogCurrentPage")!! if (optionsTextConfig.has("textDeleteDialogAllPages")) textConfig.textDeleteDialogAllPages = optionsTextConfig.getString("textDeleteDialogAllPages")!! if (optionsTextConfig.has("textDeleteDialogCancel")) textConfig.textDeleteDialogCancel = optionsTextConfig.getString("textDeleteDialogCancel") if (optionsTextConfig.has("textTitleScanTipsPage")) textConfig.textTitleScanTipsPage = optionsTextConfig.getString("textTitleScanTipsPage") } } private fun setButtonConfig(buttonConfig: ButtonConfiguration, optionsButtonConfig: JSObject?) { if (optionsButtonConfig != null) { val keysIter = optionsButtonConfig.keys(); val keys: MutableList = ArrayList() while (keysIter.hasNext()) { val key = keysIter.next() val docutainButtonEntry = optionsButtonConfig.getJSObject(key) if (docutainButtonEntry != null) { when (key.uppercase()) { "BUTTONEDITROTATE" -> setButtonConfig( buttonConfig.buttonEditRotate, docutainButtonEntry ) "BUTTONEDITCROP" -> setButtonConfig( buttonConfig.buttonEditCrop, docutainButtonEntry ) "BUTTONEDITFILTER" -> setButtonConfig( buttonConfig.buttonEditFilter, docutainButtonEntry ) "BUTTONEDITARRANGE" -> setButtonConfig( buttonConfig.buttonEditArrange, docutainButtonEntry ) "BUTTONEDITRETAKE" -> setButtonConfig( buttonConfig.buttonEditRetake, docutainButtonEntry ) "BUTTONEDITDELETE" -> setButtonConfig( buttonConfig.buttonEditDelete, docutainButtonEntry ) "BUTTONEDITFINISH" -> setButtonConfig( buttonConfig.buttonEditFinish, docutainButtonEntry ) "BUTTONCROPEXPAND" -> setButtonConfig( buttonConfig.buttonCropExpand, docutainButtonEntry ) "BUTTONCROPSNAP" -> setButtonConfig( buttonConfig.buttonCropSnap, docutainButtonEntry ) "BUTTONCROPFINISH" -> setButtonConfig( buttonConfig.buttonCropFinish, docutainButtonEntry ) "BUTTONSCANAUTOCAPTUREON" -> setButtonConfig( buttonConfig.buttonScanAutoCaptureOn, docutainButtonEntry ) "BUTTONSCANAUTOCAPTUREOFF" -> setButtonConfig( buttonConfig.buttonScanAutoCaptureOff, docutainButtonEntry ) "BUTTONSCANTORCH" -> setButtonConfig( buttonConfig.buttonScanTorch, docutainButtonEntry ) "BUTTONSCANCAPTURE" -> setButtonConfig( buttonConfig.buttonScanCapture, docutainButtonEntry ) "BUTTONSCANFINISH" -> setButtonConfig( buttonConfig.buttonScanFinish, docutainButtonEntry ) "BUTTONCONFIRMATIONFINISH" -> setButtonConfig( buttonConfig.buttonConfirmationFinish, docutainButtonEntry ) "BUTTONEDITADDPAGE" -> setButtonConfig( buttonConfig.buttonEditAddPage, docutainButtonEntry ) "BUTTONSCANIMPORT" -> setButtonConfig( buttonConfig.buttonScanImport, docutainButtonEntry ) else -> Log.e( "DocutainSdkFull", "mapDocumentScannerConfiguration button not valid " + key ) } } } } } private fun setOnboardingConfig(scanConfig: BaseScannerConfiguration, optionsOnboarding: JSObject) { var onboarding: Onboarding? = scanConfig.onboarding if(onboarding == null) { onboarding = Onboarding() scanConfig.onboarding = onboarding } readButtonConfig("buttonNext", onboarding.buttonNext, optionsOnboarding) readButtonConfig("buttonFinish", onboarding.buttonFinish, optionsOnboarding) readButtonConfig("buttonSkip", onboarding.buttonSkip, optionsOnboarding) if (optionsOnboarding.has("buttonBack")) { onboarding.buttonBack = DocutainButton() readButtonConfig("buttonBack", onboarding.buttonBack!!, optionsOnboarding) } if(optionsOnboarding.has("scanHintPopup")) { val value = optionsOnboarding.opt("scanHintPopup") val valueString = optionsOnboarding.opt("scanHintPopup").toString() if(valueString=="null") { onboarding.scanHintPopup = null } else { val optionsScanHintPopup = optionsOnboarding.getJSObject("scanHintPopup")!! var scanHintPopup: ScanHintPopup? = onboarding.scanHintPopup if(scanHintPopup == null) { scanHintPopup = ScanHintPopup() onboarding.scanHintPopup = scanHintPopup } if (optionsScanHintPopup.has("title")) scanHintPopup.title = optionsScanHintPopup.getString("title") if (optionsScanHintPopup.has("message")) scanHintPopup.message = optionsScanHintPopup.getString("message") if (optionsScanHintPopup.has("closeButton")) scanHintPopup.closeButton = optionsScanHintPopup.getString("closeButton") val imageSource = getImageSource(optionsScanHintPopup) if(imageSource != null) scanHintPopup.imageSource = imageSource } } val optionsOnboardingItems = optionsOnboarding.optJSONArray("items") if(optionsOnboardingItems != null) { val items = ArrayList() for (i in 0 until optionsOnboardingItems.length()) { val docutainListItemEntry = optionsOnboardingItems.getJSONObject(i) items.add(readDocutainListItemConfig(docutainListItemEntry)) } if(items.isNullOrEmpty()){ onboarding.items = null; } else { onboarding.items = items; } } } private fun setScanTipsConfig(scanConfig: BaseScannerConfiguration, optionsScanTips: JSObject) { var scanTips: ScanTips? = scanConfig.scanTips if(scanTips == null) { scanTips = ScanTips() scanConfig.scanTips = scanTips } readButtonConfig("toolbarItem", scanTips.toolbarItem, optionsScanTips, true) val optionsScanTipsItems = optionsScanTips.optJSONArray("items") if(optionsScanTipsItems != null) { val items = ArrayList() for (i in 0 until optionsScanTipsItems.length()) { val docutainListItemEntry = optionsScanTipsItems.getJSONObject(i) items.add(readDocutainListItemConfig(docutainListItemEntry)) } if (items.isNullOrEmpty()) { scanTips.items = null; } else { scanTips.items = items; } } } private fun setSourceImagesConfig(scanConfig: BaseScannerConfiguration, sourceImages: JSONArray?) { if(sourceImages != null) { val sourceImageFiles = ArrayList() for (i in 0..sourceImages.length() - 1) { //needs to be an absolut path to the file val filepath = sourceImages.getString(i).replace("file://", "") sourceImageFiles.add(java.io.File(filepath)) } scanConfig.sourceImages = sourceImageFiles } } private fun mapDocumentScannerConfiguration(options: JSObject, scanConfig: BaseScannerConfiguration, NeedToMigrate: Boolean = false): Boolean { try { setPageEditConfig(scanConfig.pageEditConfig, options.getJSObject("pageEditConfig")) setColorConfig(scanConfig.colorConfig, options.getJSObject("ColorConfig")) if(options.has("allowCaptureModeSetting")) scanConfig.allowCaptureModeSetting = options.getBoolean("allowCaptureModeSetting") if(options.has("autoCapture")) scanConfig.autoCapture = options.getBoolean("autoCapture") if(options.has("defaultScanFilter")) scanConfig.defaultScanFilter = getScanFilterFromString(options.getString("defaultScanFilter")!!) if(options.has("source")) scanConfig.source = getScanSourceFromString(options.getString("source")!!) if(options.has("sourceImages")) setSourceImagesConfig(scanConfig, options.get("sourceImages") as JSONArray?) if(options.has("autoCrop")) scanConfig.autoCrop = options.getBoolean("autoCrop") if(options.has("multiPage")) scanConfig.multiPage = options.getBoolean("multiPage") if(options.has("preCaptureFocus")) scanConfig.preCaptureFocus = options.getBoolean("preCaptureFocus") setTextConfig(scanConfig.textConfig, options.getJSObject("textConfig")) setButtonConfig(scanConfig.buttonConfig, options.getJSObject("buttonConfig")) if(options.has("confirmPages")) scanConfig.confirmPages = options.getBoolean("confirmPages") if(options.has("allowPageEditing")) scanConfig.allowPageEditing = options.getBoolean("allowPageEditing") if(options.has("statusBarAppearance")) scanConfig.statusBarAppearance = getStatusBarAppearanceFromString(options.getString("statusBarAppearance")!!) if(options.has("navigationBarAppearance")) scanConfig.navigationBarAppearance = getNavigationBarAppearanceFromString(options.getString("navigationBarAppearance")!!) if(options.has("vibrateOnCapture")) scanConfig.vibrateOnCapture = options.getBoolean("vibrateOnCapture") if(options.has("onboarding")) { val value = options.opt("onboarding") val valueString = options.opt("onboarding").toString() if(valueString=="null") { scanConfig.onboarding = null } else { setOnboardingConfig(scanConfig, options.getJSObject("onboarding")!!) } } if(options.has("scanTips")) { val value = options.opt("scanTips") val valueString = options.opt("scanTips").toString() if(valueString=="null") { scanConfig.scanTips = null } else { setScanTipsConfig(scanConfig, options.getJSObject("scanTips")!!) } } if(NeedToMigrate && scanConfig.onboarding != null && scanConfig.onboarding!!.scanHintPopup != null) { val scanHintPopup = scanConfig.onboarding!!.scanHintPopup!!; // CheckMigration val optionsOnboarding = options.getJSObject("onboarding") var optionsScanHintPopup : JSObject? = null; if(optionsOnboarding != null) optionsScanHintPopup = optionsOnboarding.getJSObject("scanHintPopup") if (options.has("onboardingImageSource") && (optionsScanHintPopup==null || !optionsScanHintPopup.has("imageSource"))) { val imgSource = options.getString("onboardingImageSource")!! scanHintPopup.imageSource = DocutainSDK.context.resources.getIdentifier( imgSource, "drawable", DocutainSDK.context.packageName ) } var optionsTextConfig = options.getJSObject("textConfig") if(optionsTextConfig != null) { if (optionsTextConfig.has("textOnboardingTitle") && (optionsScanHintPopup==null || !optionsScanHintPopup.has("title"))) scanHintPopup.title = optionsTextConfig.getString("textOnboardingTitle") if (optionsTextConfig.has("textOnboardingMessage") && (optionsScanHintPopup==null || !optionsScanHintPopup.has("message"))) scanConfig.onboarding!!.scanHintPopup!!.title = optionsTextConfig.getString("textOnboardingMessage") if (optionsTextConfig.has("textOnboardingCloseButton ") && (optionsScanHintPopup==null || !optionsScanHintPopup.has("closeButton"))) scanHintPopup.closeButton = optionsTextConfig.getString("textOnboardingCloseButton ") } } } catch(ex:Exception ) { Log.e(logTag, "mapDocumentScannerConfiguration Exception "+ ex) return false } return true } @ActivityCallback private fun scanResult(call: PluginCall, result: ActivityResult){ Log.v(logTag, if(result.resultCode == Activity.RESULT_OK) "scan finished" else "scan canceled" ) val ret = JSObject() ret.put("status", if(result.resultCode == Activity.RESULT_OK) "SUCCESS" else "CANCELED") call.resolve(ret) } @PluginMethod fun startPhotoPayment(call: PluginCall) { Log.v(logTag, "startPhotoPayment Start") try { val nativePhotoPaymentConfig = PhotoPaymentConfiguration() if(!mapPhotoPaymentConfiguration(call, nativePhotoPaymentConfig)){ call.reject("StartPhotoPaymentOptions not valid") return } val intent = PhotoPaymentResult().createIntent(context.applicationContext, nativePhotoPaymentConfig) startActivityForResult(call, intent, "photoPaymentResult") Log.v(logTag, "startPhotoPayment start OK") } catch(ex:Exception ) { Log.e(logTag, "startPhotoPayment Exception "+ ex) call.reject("startPhotoPayment", ex); } } @PluginMethod fun resetOnboarding(call: PluginCall) { try { val onboarding = Onboarding(); onboarding.reset(call.getBoolean("onboarding", true)!!, call.getBoolean("scanHintPopup", true)!!) call.resolve() } catch(ex:Exception ) { Log.e(logTag, "resetOnboarding Exception"+ ex) call.reject("resetOnboarding", ex); } } fun defaultItemsToJSONArray(defaultItems: List) : JSONArray { val array = JSONArray() defaultItems.forEach{ val item = JSObject("{\"image\": "+ it.image+ ";\"title\":\""+ it.title+"\""+ ";\"message\":\""+ it.message+"\""+"}") array.put(item) } return array } @PluginMethod fun onboardingDefaultItems(call: PluginCall) { try { val ret = JSObject() ret.put("items", defaultItemsToJSONArray(Onboarding.defaultItems)) call.resolve(ret); } catch(ex:Exception ) { Log.e(logTag, "onboardingDefaultItems Exception" + ex) call.reject("onboardingDefaultItems", ex); } } @PluginMethod fun emptyResultScreenDefaultItems(call: PluginCall) { try { val ret = JSObject() ret.put("items", defaultItemsToJSONArray(EmptyResultScreen.defaultItems)) call.resolve(ret); } catch(ex:Exception ) { Log.e(logTag, "emptyResultScreenDefaultItems Exception" + ex) call.reject("emptyResultScreenDefaultItems", ex); } } @PluginMethod fun scanTipsDefaultItems(call: PluginCall) { try { val ret = JSObject() ret.put("items", defaultItemsToJSONArray(ScanTips.defaultItems)) call.resolve(ret); } catch(ex:Exception ) { Log.e(logTag, "scanTipsDefaultItems Exception" + ex) call.reject("scanTipsDefaultItems", ex); } } private fun getImageSource(entry: JSObject):Int? { if (entry.has("imageSource")) { val imgSource = entry.getString("imageSource")!! return DocutainSDK.context.resources.getIdentifier( imgSource, "drawable", DocutainSDK.context.packageName ) } return null } private fun readButtonConfig(key: String, docutainButton: DocutainButton , entry: JSObject?, toolbarButton: Boolean=false) { if (entry != null) { val docutainButtonEntry = entry.getJSObject(key) if (docutainButtonEntry != null) { if (docutainButtonEntry.has("title")) { docutainButton.title = docutainButtonEntry.getString("title"); if(toolbarButton) { docutainButton.icon = null; return } } if (docutainButtonEntry.has("icon")) { val imgSource = docutainButtonEntry.getString("icon")!! val imgIdentifier = DocutainSDK.context.resources.getIdentifier( imgSource, "drawable", DocutainSDK.context.packageName ) docutainButton.icon = imgIdentifier } } } } private fun readDocutainListItemConfig( entry: JSONObject) : DocutainListItem { var imgIdentifier = 0 if(entry.has("image")){ val imgSource = entry.getString("image")!! imgIdentifier = DocutainSDK.context.resources.getIdentifier( imgSource, "drawable", DocutainSDK.context.packageName ) } return DocutainListItem(imgIdentifier, entry.optString("title","")!!, entry.optString("message","")!!) } private fun mapPhotoPaymentConfiguration(call: PluginCall, photoPaymentConfig: PhotoPaymentConfiguration): Boolean { if(!mapDocumentScannerConfiguration(call.data, photoPaymentConfig)) return false; try { val optionsAnalyzeConfig = call.getObject("analyzeConfig") if (optionsAnalyzeConfig != null) { if(optionsAnalyzeConfig.has("readBIC")) photoPaymentConfig.analyzeConfig.readBIC = optionsAnalyzeConfig.getBoolean("readBIC") if(optionsAnalyzeConfig.has("readPaymentState")) photoPaymentConfig.analyzeConfig.readPaymentState = optionsAnalyzeConfig.getBoolean("readPaymentState") if(optionsAnalyzeConfig.has("readSEPACreditor")) photoPaymentConfig.analyzeConfig.readSEPACreditor = optionsAnalyzeConfig.getBoolean("readSEPACreditor") } if(call.data.has("emptyResultScreen")) { val optionsEmptyResultScreen = call.getObject("emptyResultScreen") val valueString = call.data.opt("emptyResultScreen").toString() if(valueString=="null") { photoPaymentConfig.emptyResultScreen = null } else { var emptyResultScreen: EmptyResultScreen? = photoPaymentConfig.emptyResultScreen if (emptyResultScreen == null) { emptyResultScreen = EmptyResultScreen() photoPaymentConfig.emptyResultScreen = emptyResultScreen } if (optionsEmptyResultScreen.has("title")) emptyResultScreen.title = optionsEmptyResultScreen.getString("title")!! readButtonConfig( "repeatButton", emptyResultScreen.repeatButton, optionsEmptyResultScreen ) val optionsEmptyResultScreenItems = optionsEmptyResultScreen.optJSONArray("items") if (optionsEmptyResultScreenItems != null) { val items = ArrayList() for (i in 0 until optionsEmptyResultScreenItems.length()) { val docutainListItemEntry = optionsEmptyResultScreenItems.getJSONObject(i) items.add(readDocutainListItemConfig(docutainListItemEntry)) } if (items.isNullOrEmpty()) { emptyResultScreen.items = null; } else { emptyResultScreen.items = items; } } } } } catch(ex:Exception ) { Log.e(logTag, "mapPhotoPaymentConfiguration Exception "+ ex) return false } return true } @ActivityCallback private fun startDocumentScannerResult(call: PluginCall, result: ActivityResult){ Log.v(logTag, if(result.resultCode == Activity.RESULT_OK) "scan finished" else "scan canceled" ) val ret = JSObject() if(result.resultCode == Activity.RESULT_OK) { call.resolve(ret) } else { call.reject("user canceled", canceledState) } } @ActivityCallback private fun photoPaymentResult(call: PluginCall, result: ActivityResult){ Log.v(logTag, if(result.resultCode == Activity.RESULT_OK) "scan finished" else "scan canceled" ) val ret = JSObject() if(result.resultCode == Activity.RESULT_OK) { var s = result.data?.getStringExtra("analyzeData") ret.put("data",result.data?.getStringExtra("analyzeData")) call.resolve(ret) } else { call.reject("user canceled", canceledState) } } }