Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Built application files
*.apk
*.aab
google-services.json
app/google-services.json
#*.aar
#*.ap_

Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

ID scanning Android app and library. Supports MRZ, NFC, Barcodes, and [ID PASS Lite](https://github.com/idpass/idpass-lite) cards.

[![Get it on Google Play](https://buttercup.pw/static/img/googleplay.svg)](https://play.google.com/store/apps/details?id=org.newlogic.smartscanner)

**Note: The library's API might keep evolving before we reach v1.0, so be careful when upgrading between these pre-v1.0 versions. Starting at v1.0 we will be careful in introducing breaking API changes.**

## Features
Expand Down
63 changes: 37 additions & 26 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
plugins {
id 'com.gladed.androidgitversion' version '0.4.14'
}


apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'

androidGitVersion {
baseCode 1
}

android {
compileSdkVersion 32
Expand All @@ -20,8 +15,8 @@ android {
applicationId "org.newlogic.smartscanner"
minSdkVersion 21
targetSdkVersion 32
versionName androidGitVersion.name()
versionCode androidGitVersion.code()
versionName = "1.0.2"
versionCode = 1

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
Expand All @@ -33,20 +28,20 @@ android {
viewBinding = true
}

signingConfigs{
release {
def props = new Properties()

def fileInputStream = new FileInputStream(file('../signing.properties'))
props.load(fileInputStream)
fileInputStream.close()

storeFile = file('upload-keystore')
storePassword = props['STORE_PASSWORD']
keyAlias = props['KEY_ALIAS']
keyPassword = props['KEY_PASSWORD']
}
}
// signingConfigs{
// release {
// def props = new Properties()
//
// def fileInputStream = new FileInputStream(file('../signing.properties'))
// props.load(fileInputStream)
// fileInputStream.close()
//
// storeFile = file('upload-keystore')
// storePassword = props['STORE_PASSWORD']
// keyAlias = props['KEY_ALIAS']
// keyPassword = props['KEY_PASSWORD']
// }
// }

buildTypes {
debug {
Expand All @@ -55,7 +50,7 @@ android {
}
release {
minifyEnabled false
signingConfig signingConfigs.release
// signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
android.applicationVariants.all { variant ->
Expand Down Expand Up @@ -89,17 +84,16 @@ dependencies {
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.firebase:firebase-analytics-ktx:18.0.1'
implementation 'com.google.firebase:firebase-crashlytics-ktx:17.3.0'
implementation 'com.google.firebase:firebase-crashlytics:17.3.0'
implementation 'com.google.firebase:firebase-analytics:18.0.1'
implementation 'com.google.firebase:firebase-crashlytics-ktx:18.2.12'
implementation 'com.google.firebase:firebase-crashlytics:18.2.12'
implementation 'androidx.multidex:multidex:2.0.1'
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.jakewharton.timber:timber:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
Expand All @@ -111,4 +105,21 @@ dependencies {
implementation 'org.idpass:idpass-lite-java-android:0.1@aar'
// SmartScanner API Intent Call Out
implementation project(path: ':smartscanner-android-api')

//Authentication
implementation "com.auth0:java-jwt:4.4.0"
implementation "com.auth0:auth0:1.30.0"
implementation 'com.auth0:jwks-rsa:0.22.0'

// UI
implementation 'de.hdodenhof:circleimageview:3.1.0'

// Asynch function
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"

implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.12.0"



}
18 changes: 6 additions & 12 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.newlogic.smartscanner">
package="org.newlogic.smartscanner"
android:versionName="1.0.2"
android:versionCode="1">

<uses-feature android:name="android.hardware.camera.any" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
tools:ignore="CoarseFineLocation" />

<uses-feature
android:name="android.hardware.camera"
android:required="true" />
Expand All @@ -26,7 +23,9 @@
android:hardwareAccelerated="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
android:debuggable="true"
tools:ignore="HardcodedDebugMode">
<activity
android:name="MainActivity"
android:exported="true"
Expand All @@ -47,11 +46,6 @@
android:exported="true"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="nosensor" />
<activity
android:name=".result.RawResultActivity"
android:exported="true"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="nosensor" />
<activity
android:name=".settings.SettingsActivity"
android:exported="true"
Expand Down
144 changes: 41 additions & 103 deletions app/src/main/java/org/newlogic/smartscanner/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,22 @@ import com.google.android.material.snackbar.Snackbar
import org.idpass.smartscanner.api.ScannerConstants
import org.idpass.smartscanner.api.ScannerIntent
import org.idpass.smartscanner.lib.SmartScannerActivity
import org.idpass.smartscanner.lib.SmartScannerActivity.Companion.SCANNER_FAIL_RESULT
import org.idpass.smartscanner.lib.SmartScannerActivity.Companion.SCANNER_HEADER_RESULT
import org.idpass.smartscanner.lib.SmartScannerActivity.Companion.SCANNER_IMAGE_TYPE
import org.idpass.smartscanner.lib.SmartScannerActivity.Companion.SCANNER_JWT_CONFIG_UPDATE
import org.idpass.smartscanner.lib.SmartScannerActivity.Companion.SCANNER_RAW_RESULT
import org.idpass.smartscanner.lib.SmartScannerActivity.Companion.SCANNER_RESULT
import org.idpass.smartscanner.lib.SmartScannerActivity.Companion.SCANNER_RESULT_BYTES
import org.idpass.smartscanner.lib.SmartScannerActivity.Companion.SCANNER_SIGNATURE_VERIFICATION
import org.idpass.smartscanner.lib.nfc.NFCActivity
import org.idpass.smartscanner.lib.scanner.config.*
import org.idpass.smartscanner.lib.scanner.config.Config.Companion.OP_SCANNER
import org.idpass.smartscanner.lib.scanner.config.Config.Companion.ORIENTATION
import org.newlogic.smartscanner.databinding.ActivityMainBinding
import org.newlogic.smartscanner.result.IDPassResultActivity
import org.newlogic.smartscanner.result.ResultActivity
import org.newlogic.smartscanner.settings.SettingsActivity
import org.newlogic.smartscanner.settings.SettingsActivity.Companion.ORIENTATION


class MainActivity : AppCompatActivity() {

companion object {

const val OP_SCANNER = 1001
private val imageType = ImageResultType.PATH.value
var imageType = ImageResultType.PATH.value

private fun sampleConfig(isManualCapture: Boolean, label: String = "", orientation : String? = Orientation.PORTRAIT.value) = Config(
branding = true,
Expand All @@ -71,20 +63,18 @@ class MainActivity : AppCompatActivity() {
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
preference = getSharedPreferences(Config.SHARED, Context.MODE_PRIVATE)
preference = getSharedPreferences(SmartScannerApplication.SHARED, Context.MODE_PRIVATE)
}

override fun onStart() {
super.onStart()
// Choose scan modes
binding.itemBarcode.item.setOnClickListener { scanBarcode(BarcodeOptions.default) }
binding.itemIdpassLite.item.setOnClickListener { scanIDPassLite() }
binding.itemMrz.item.setOnClickListener { scanMRZ() }
binding.itemQr.item.setOnClickListener { scanQRCode() }
// binding.itemQrGzip.item.setOnClickListener { scanQRCodeGzip() }
binding.itemNfc.item.setOnClickListener { scanNFC() }
binding.itemPdf417.item.setOnClickListener { scanPDF417() }
binding.itemQr.item.setOnClickListener { scanQRCode() }
// Choose scan type
// binding.itemBarcode.item.setOnClickListener { scanBarcode(BarcodeOptions.default) }
// binding.itemIdpassLite.item.setOnClickListener { scanIDPassLite() }
// binding.itemMrz.item.setOnClickListener { scanMRZ() }
// binding.itemQr.item.setOnClickListener { scanQRCode() }
// binding.itemNfc.item.setOnClickListener { scanNFC() }
binding.itemQrVoucher.item.setOnClickListener { scanQRCode() }
// Change language
binding.languageSettings.setOnClickListener {
startActivity(Intent(this, SettingsActivity::class.java))
Expand Down Expand Up @@ -132,14 +122,7 @@ class MainActivity : AppCompatActivity() {
ScannerOptions(
mode = Modes.MRZ.value,
language = getLanguage(preference),
config = Config(
branding = true,
imageResultType = imageType,
label = "",
isManualCapture = true,
orientation = getOrientation(preference),
showGuide = true
)
config = sampleConfig(isManualCapture = true, orientation = getOrientation(preference)),
)
)
startActivityForResult(intent, OP_SCANNER)
Expand All @@ -160,8 +143,7 @@ class MainActivity : AppCompatActivity() {
header = getString(R.string.label_scan_nfc_capture),
subHeader = getString(R.string.label_scan_nfc_via_mrz),
isManualCapture = false,
branding = true,
showGuide = true
branding = true
)
)
)
Expand All @@ -170,31 +152,11 @@ class MainActivity : AppCompatActivity() {

}

private fun scanPDF417() {
val intent = Intent(this, SmartScannerActivity::class.java)
intent.putExtra(
SmartScannerActivity.SCANNER_OPTIONS,
ScannerOptions(
mode = Modes.PDF_417.value,
language = getLanguage(preference),
scannerSize = ScannerSize.SMALL.value,
config = sampleConfig(false)
)
)
startActivityForResult(intent, OP_SCANNER)
}

private fun scanQRCode() {
val intent = Intent(this, SmartScannerActivity::class.java)
intent.putExtra(
SmartScannerActivity.SCANNER_OPTIONS,
ScannerOptions(
mode = Modes.QRCODE.value,
language = preference?.getString(Language.NAME, Language.EN),
scannerSize = ScannerSize.LARGE.value,
qrCodeOptions = QRcodeOptions(isJson = true),
config = sampleConfig(false)
)
val intent = ScannerIntent.intentQRCode(
isGzipped = true,
isJson = true,
jsonPath = "" // ex: "$.members[1].lastName"
)
startActivityForResult(intent, OP_SCANNER)
}
Expand All @@ -209,61 +171,37 @@ class MainActivity : AppCompatActivity() {
if (requestCode == OP_SCANNER) {
Log.d(SmartScannerActivity.TAG, "Scanner resultCode $resultCode")
if (resultCode == RESULT_OK) {
val bundle = intent?.getBundleExtra(ScannerConstants.RESULT)
val mIntent: Intent;

if (bundle != null) {
// Get Result from Bundle Intent Call Out
if (bundle.getString(ScannerConstants.MODE) == Modes.IDPASS_LITE.value) {
// Get Result from Bundle Intent Call Out
intent?.getBundleExtra(ScannerConstants.RESULT)?.let { bundleResult ->
Log.d(SmartScannerActivity.TAG, "Scanner result bundle: $bundleResult")
if (bundleResult.getString(ScannerConstants.MODE) == Modes.IDPASS_LITE.value) {
// Go to ID PASS Lite Results Screen via bundle
mIntent = Intent(this, IDPassResultActivity::class.java)
mIntent.putExtra(IDPassResultActivity.BUNDLE_RESULT, bundle)
val myIntent = Intent(this, IDPassResultActivity::class.java)
myIntent.putExtra(IDPassResultActivity.BUNDLE_RESULT, bundleResult)
startActivity(myIntent)
} else {
// Go to Results Screen via bundle
mIntent = Intent(this, ResultActivity::class.java)
mIntent.putExtra(ResultActivity.BUNDLE_RESULT, bundle)
// Go to Barcode/MRZ Results Screen via bundle
val resultIntent = Intent(this, ResultActivity::class.java)
resultIntent.putExtra(ResultActivity.BUNDLE_RESULT, bundleResult)
startActivity(resultIntent)
}
} else {
// Get Result from Intent extras
if (intent?.getStringExtra(ScannerConstants.MODE) == Modes.IDPASS_LITE.value) {
// Go to ID PASS Lite Results Screen
val resultBytes = intent.getByteArrayExtra(SCANNER_RESULT_BYTES)
mIntent = Intent(this, IDPassResultActivity::class.java)
mIntent.putExtra(IDPassResultActivity.RESULT, resultBytes)
} ?: run {
// Get Result from JSON String
val result = intent?.getStringExtra(SCANNER_RESULT)
Log.d(SmartScannerActivity.TAG, "Scanner result string: $result")
if (!result.isNullOrEmpty()) {
// Go to Barcode/MRZ Results Screen
val resultIntent = Intent(this, ResultActivity::class.java)
resultIntent.putExtra(ResultActivity.RESULT, result)
startActivity(resultIntent)
} else {

// Check if it should go to the settings instead
val isConfigUpdated = intent?.getBooleanExtra(SCANNER_JWT_CONFIG_UPDATE, false)

// should go to settings
if (isConfigUpdated == true) {
val sIntent = Intent(this, SettingsActivity::class.java)
sIntent.putExtra(SettingsActivity.CONFIG_UPDATED, true)
startActivity(sIntent)
return
}

// Go to Results Screen
val result = intent?.getStringExtra(SCANNER_RESULT)
val verified = intent?.getBooleanExtra(SCANNER_SIGNATURE_VERIFICATION, false)
val rawResult = intent?.getStringExtra(SCANNER_RAW_RESULT)
val failResult = intent?.getStringExtra(SCANNER_FAIL_RESULT)
val headerResult = intent?.getStringExtra(SCANNER_HEADER_RESULT)

mIntent = Intent(this, ResultActivity::class.java)
mIntent.putExtra(ResultActivity.SIGNATURE_VERIFIED, verified)
mIntent.putExtra(ResultActivity.IMAGE_TYPE, intent?.getStringExtra(SCANNER_IMAGE_TYPE))
mIntent.putExtra(ResultActivity.RESULT, result)
mIntent.putExtra(ResultActivity.FAIL_RESULT, failResult)
mIntent.putExtra(ResultActivity.RAW_RESULT, rawResult)
mIntent.putExtra(ResultActivity.HEADER_RESULT, headerResult)

// Go to ID PASS Lite Results Screen
val resultBytes = intent?.getByteArrayExtra(SCANNER_RESULT_BYTES)
val myIntent = Intent(this, IDPassResultActivity::class.java)
myIntent.putExtra(IDPassResultActivity.RESULT, resultBytes)
startActivity(myIntent)
}
}


mIntent.putExtra(ScannerConstants.MODE, intent?.getStringExtra(ScannerConstants.MODE))
startActivity(mIntent)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@ class SmartScannerApplication : MultiDexApplication() {
}
}
}

companion object {
const val SHARED = "SHARED"
}
}
Loading