Skip to content

Commit 30e800c

Browse files
committed
Merge branch 'release/1.1.1' into main
2 parents d7d9115 + 022d4ed commit 30e800c

File tree

10 files changed

+41
-43
lines changed

10 files changed

+41
-43
lines changed

.github/workflows/android.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ on:
44
push:
55
branches:
66
- develop
7-
- master
7+
- main
88
pull_request:
99
branches:
1010
- develop
11-
- master
11+
- main
1212

1313
jobs:
1414
detekt:

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ There are two different flavors available on `mavenCentral()`:
1818
| V2 model is used (possibly faster, more accurate) | currently V1 model will be downloaded
1919
```kotlin
2020
// bundled:
21-
implementation("io.github.g00fy2.quickie:quickie-bundled:1.1.0")
21+
implementation("io.github.g00fy2.quickie:quickie-bundled:1.1.1")
2222

2323
// unbundled:
24-
implementation("io.github.g00fy2.quickie:quickie-unbundled:1.1.0")
24+
implementation("io.github.g00fy2.quickie:quickie-unbundled:1.1.1")
2525
```
2626

2727
## Quick Start
@@ -40,7 +40,7 @@ fun handleResult(result: QRResult) {
4040
```
4141
⚠️ **You can't register the ActivityResultContract inside the OnClickListener lambda. This will fail since the code gets executed after the onCreate lifecycle!**
4242
43-
Check out the [sample](https://github.com/G00fY2/quickie/tree/develop/sample) inside this repo or visit the [Activity Result API documentation](https://developer.android.com/training/basics/intents/result) for more information.
43+
Check out the [sample](https://github.com/G00fY2/quickie/tree/develop/sample) inside this repo or visit the official [Activity Result API documentation](https://developer.android.com/training/basics/intents/result) for more information.
4444
4545
### Responses
4646
The callback you add to the `registerForActivityResult` will receive a subclass of the sealed `QRResult` class:
@@ -104,6 +104,7 @@ override fun onCreate(savedInstanceState: Bundle?) {
104104
fun handleResult(result: QRResult) {
105105
106106
```
107+
:bulb: You can optionally [pass in an ActivityOptionsCompat object](https://developer.android.com/reference/androidx/activity/result/ActivityResultLauncher#launch(I,%20androidx.core.app.ActivityOptionsCompat)) when launching the ActivityResultLauncher to control the scanner launch animation.
107108

108109
## Screenshots / Sample App
109110
You can find the sample app APKs inside the [release](https://github.com/G00fY2/quickie/releases) assets.
@@ -112,7 +113,7 @@ You can find the sample app APKs inside the [release](https://github.com/G00fY2/
112113

113114
## Requirements
114115
* AndroidX
115-
* Min SDK 21+
116+
* Min SDK 21+ (required by CameraX)
116117
* (Google Play Services available on the end device if using `quickie-unbundled`)
117118

118119
## License

buildSrc/src/main/kotlin/Deps.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ object Deps {
88
const val cameraPreview = "androidx.camera:camera-view:${Versions.cameraView}"
99
}
1010

11-
object Mdc {
11+
object UI {
1212
const val materialDesign = "com.google.android.material:material:${Versions.materialDesign}"
1313
}
1414

buildSrc/src/main/kotlin/Versions.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ object Versions {
66
const val androidBuildTools = "30.0.3"
77

88
const val androidGradle = "4.2.1"
9-
const val kotlin = "1.5.0"
9+
const val kotlin = "1.5.10"
1010

1111
const val appcompat = "1.3.0"
1212

@@ -15,11 +15,11 @@ object Versions {
1515

1616
const val materialDesign = "1.3.0"
1717

18-
const val barcodeScanning = "16.1.1"
19-
const val barcodeScanningGms = "16.1.4"
18+
const val barcodeScanning = "16.1.2"
19+
const val barcodeScanningGms = "16.1.5"
2020

2121
const val detekt = "1.17.1"
22-
const val gradleVersions = "0.38.0"
22+
const val gradleVersions = "0.39.0"
2323
const val dokka = "1.4.32"
2424

2525
const val junit = "5.7.2"

quickie/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ dependencies {
4343
}
4444

4545
group = "io.github.g00fy2.quickie"
46-
version = "1.1.0"
46+
version = "1.1.1"
4747

4848
tasks.register<Jar>("androidJavadocJar") {
4949
archiveClassifier.set("javadoc")

quickie/src/main/kotlin/io/github/g00fy2/quickie/QRCodeAnalyzer.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,17 @@ package io.github.g00fy2.quickie
33
import androidx.camera.core.ExperimentalGetImage
44
import androidx.camera.core.ImageAnalysis
55
import androidx.camera.core.ImageProxy
6-
import com.google.android.gms.tasks.Task
76
import com.google.mlkit.vision.barcode.Barcode
87
import com.google.mlkit.vision.barcode.BarcodeScannerOptions
98
import com.google.mlkit.vision.barcode.BarcodeScanning
109
import com.google.mlkit.vision.common.InputImage
1110

12-
@ExperimentalGetImage
1311
internal class QRCodeAnalyzer(
1412
private val barcodeFormats: IntArray,
1513
private val onSuccess: ((Barcode) -> Unit),
1614
private val onFailure: ((Exception) -> Unit)
1715
) : ImageAnalysis.Analyzer {
1816

19-
private var pendingTask: Task<List<Barcode>>? = null
2017
private val barcodeScanner by lazy {
2118
val optionsBuilder = if (barcodeFormats.size > 1) {
2219
BarcodeScannerOptions.Builder().setBarcodeFormats(barcodeFormats.first(), *barcodeFormats.drop(1).toIntArray())
@@ -26,14 +23,16 @@ internal class QRCodeAnalyzer(
2623
BarcodeScanning.getClient(optionsBuilder.build())
2724
}
2825

26+
@ExperimentalGetImage
2927
override fun analyze(imageProxy: ImageProxy) {
30-
if (pendingTask?.isComplete == false || imageProxy.image == null) return
28+
if (imageProxy.image == null) return
3129

32-
pendingTask = barcodeScanner.process(imageProxy.toInputImage())
30+
barcodeScanner.process(imageProxy.toInputImage())
3331
.addOnSuccessListener { codes -> codes.mapNotNull { it }.firstOrNull()?.let { onSuccess(it) } }
3432
.addOnFailureListener { onFailure(it) }
3533
.addOnCompleteListener { imageProxy.close() }
3634
}
3735

36+
@ExperimentalGetImage
3837
private fun ImageProxy.toInputImage() = InputImage.fromMediaImage(image!!, imageInfo.rotationDegrees)
3938
}

quickie/src/main/kotlin/io/github/g00fy2/quickie/QROverlayView.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ internal class QROverlayView @JvmOverloads constructor(
8888
}
8989
if (drawableRes != 0) {
9090
try {
91-
ResourcesCompat.getDrawable(resources, drawableRes, null)?.limitDrawableSize(ICON_DP_MAX_HEIGHT)?.let {
91+
ResourcesCompat.getDrawable(resources, drawableRes, null)?.limitDrawableSize()?.let {
9292
titleTextView.setCompoundDrawables(null, it, null, null)
9393
}
9494
} catch (ignore: NotFoundException) {
@@ -135,10 +135,14 @@ internal class QROverlayView @JvmOverloads constructor(
135135
layoutParams = params
136136
}
137137

138-
private fun Drawable.limitDrawableSize(maxDpHeight: Int): Drawable {
139-
val scale = (maxDpHeight * resources.displayMetrics.density) / minimumHeight
140-
if (scale < 1) setBounds(0, 0, (minimumWidth * scale).roundToInt(), (minimumHeight * scale).roundToInt())
141-
else setBounds(0, 0, minimumWidth, minimumHeight)
138+
private fun Drawable.limitDrawableSize(): Drawable {
139+
val heightLimit = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, ICON_MAX_HEIGHT, resources.displayMetrics)
140+
val scale = heightLimit / minimumHeight
141+
if (scale < 1) {
142+
setBounds(0, 0, (minimumWidth * scale).roundToInt(), (minimumHeight * scale).roundToInt())
143+
} else {
144+
setBounds(0, 0, minimumWidth, minimumHeight)
145+
}
142146
return this
143147
}
144148

@@ -147,6 +151,6 @@ internal class QROverlayView @JvmOverloads constructor(
147151
private const val STROKE_WIDTH = 4f
148152
private const val OUT_RADIUS = 16f
149153
private const val FRAME_MARGIN_RATIO = 1f / 4
150-
private const val ICON_DP_MAX_HEIGHT = 56
154+
private const val ICON_MAX_HEIGHT = 56f
151155
}
152156
}

quickie/src/main/kotlin/io/github/g00fy2/quickie/QRScannerActivity.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import androidx.activity.result.contract.ActivityResultContracts
1212
import androidx.appcompat.app.AppCompatActivity
1313
import androidx.appcompat.view.ContextThemeWrapper
1414
import androidx.camera.core.CameraSelector
15-
import androidx.camera.core.ExperimentalGetImage
1615
import androidx.camera.core.ImageAnalysis
1716
import androidx.camera.core.Preview
1817
import androidx.camera.lifecycle.ProcessCameraProvider
@@ -28,11 +27,10 @@ import io.github.g00fy2.quickie.utils.PlayServicesValidator
2827
import java.util.concurrent.ExecutorService
2928
import java.util.concurrent.Executors
3029

31-
@ExperimentalGetImage
3230
internal class QRScannerActivity : AppCompatActivity() {
3331

3432
private lateinit var binding: QuickieScannerActivityBinding
35-
private lateinit var cameraExecutor: ExecutorService
33+
private lateinit var analysisExecutor: ExecutorService
3634
private var barcodeFormats = intArrayOf(Barcode.FORMAT_QR_CODE)
3735

3836
override fun onCreate(savedInstanceState: Bundle?) {
@@ -46,7 +44,7 @@ internal class QRScannerActivity : AppCompatActivity() {
4644
setupEdgeToEdgeUI()
4745
applyScannerConfig()
4846

49-
cameraExecutor = Executors.newSingleThreadExecutor()
47+
analysisExecutor = Executors.newSingleThreadExecutor()
5048

5149
requestCameraPermissionIfMissing { granted ->
5250
if (granted) {
@@ -60,7 +58,7 @@ internal class QRScannerActivity : AppCompatActivity() {
6058

6159
override fun onDestroy() {
6260
super.onDestroy()
63-
cameraExecutor.shutdown()
61+
analysisExecutor.shutdown()
6462
}
6563

6664
private fun startCamera() {
@@ -74,13 +72,14 @@ internal class QRScannerActivity : AppCompatActivity() {
7472
.setTargetResolution(Size(1280, 720))
7573
.build()
7674
.also {
77-
it.setAnalyzer(cameraExecutor,
75+
it.setAnalyzer(analysisExecutor,
7876
QRCodeAnalyzer(
7977
barcodeFormats,
8078
{ barcode ->
8179
it.clearAnalyzer()
8280
onSuccess(barcode)
83-
}, { exception ->
81+
},
82+
{ exception ->
8483
it.clearAnalyzer()
8584
onFailure(exception)
8685
}

sample/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ android {
4242
dependencies {
4343
implementation(project(":quickie"))
4444

45-
implementation(Deps.Mdc.materialDesign)
45+
implementation(Deps.UI.materialDesign)
4646
}

sample/src/main/kotlin/io/github/g00fy2/quickiesample/MainActivity.kt

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import io.github.g00fy2.quickiesample.databinding.ActivityMainBinding
2323
class MainActivity : AppCompatActivity() {
2424

2525
private lateinit var binding: ActivityMainBinding
26-
private var snackbar: Snackbar? = null
2726
private var selectedBarcodeFormat = BarcodeFormat.FORMAT_ALL_FORMATS
2827

2928
private val scanQrCode = registerForActivityResult(ScanQRCode(), ::showSnackbar)
@@ -33,16 +32,13 @@ class MainActivity : AppCompatActivity() {
3332
super.onCreate(savedInstanceState)
3433
binding = ActivityMainBinding.inflate(layoutInflater)
3534
setContentView(binding.root)
36-
37-
setupBarcodeFormatDropdown()
35+
setBarcodeFormatDropdown()
3836

3937
binding.qrScannerButton.setOnClickListener {
40-
snackbar?.dismiss()
4138
scanQrCode.launch(null)
4239
}
4340

4441
binding.customScannerButton.setOnClickListener {
45-
snackbar?.dismiss()
4642
scanCustomCode.launch(
4743
ScannerConfig.build {
4844
setBarcodeFormats(listOf(selectedBarcodeFormat))
@@ -53,13 +49,13 @@ class MainActivity : AppCompatActivity() {
5349
}
5450
}
5551

56-
private fun setupBarcodeFormatDropdown() {
52+
private fun setBarcodeFormatDropdown() {
5753
ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, BarcodeFormat.values().map { it.name }).let {
5854
binding.barcodeFormatsAutoCompleteTextView.setAdapter(it)
5955
binding.barcodeFormatsAutoCompleteTextView.setText(it.getItem(it.getPosition(selectedBarcodeFormat.name)), false)
60-
binding.barcodeFormatsAutoCompleteTextView.setOnItemClickListener { _, _, position, _ ->
61-
selectedBarcodeFormat = BarcodeFormat.values()[position]
62-
}
56+
}
57+
binding.barcodeFormatsAutoCompleteTextView.setOnItemClickListener { _, _, position, _ ->
58+
selectedBarcodeFormat = BarcodeFormat.values()[position]
6359
}
6460
}
6561

@@ -71,15 +67,14 @@ class MainActivity : AppCompatActivity() {
7167
is QRError -> "${result.exception.javaClass.simpleName}: ${result.exception.localizedMessage}"
7268
}
7369

74-
snackbar = Snackbar.make(binding.root, text, Snackbar.LENGTH_INDEFINITE).apply {
70+
Snackbar.make(binding.root, text, Snackbar.LENGTH_INDEFINITE).apply {
7571
view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text)?.maxLines = 5
7672
if (result is QRSuccess && result.content is QRContent.Url) {
7773
setAction(R.string.open_action) { openUrl(result.content.rawValue) }
7874
} else {
7975
setAction(R.string.ok_action) { }
8076
}
81-
}
82-
snackbar?.show()
77+
}.show()
8378
}
8479

8580
private fun openUrl(url: String) {

0 commit comments

Comments
 (0)