Skip to content

Commit

Permalink
Merge branch 'release/1.1.1' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
G00fY2 committed May 31, 2021
2 parents d7d9115 + 022d4ed commit 30e800c
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 43 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ on:
push:
branches:
- develop
- master
- main
pull_request:
branches:
- develop
- master
- main

jobs:
detekt:
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ There are two different flavors available on `mavenCentral()`:
| V2 model is used (possibly faster, more accurate) | currently V1 model will be downloaded
```kotlin
// bundled:
implementation("io.github.g00fy2.quickie:quickie-bundled:1.1.0")
implementation("io.github.g00fy2.quickie:quickie-bundled:1.1.1")

// unbundled:
implementation("io.github.g00fy2.quickie:quickie-unbundled:1.1.0")
implementation("io.github.g00fy2.quickie:quickie-unbundled:1.1.1")
```

## Quick Start
Expand All @@ -40,7 +40,7 @@ fun handleResult(result: QRResult) {
```
⚠️ **You can't register the ActivityResultContract inside the OnClickListener lambda. This will fail since the code gets executed after the onCreate lifecycle!**
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.
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.
### Responses
The callback you add to the `registerForActivityResult` will receive a subclass of the sealed `QRResult` class:
Expand Down Expand Up @@ -104,6 +104,7 @@ override fun onCreate(savedInstanceState: Bundle?) {
fun handleResult(result: QRResult) {
```
: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.

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

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

## License
Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/Deps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ object Deps {
const val cameraPreview = "androidx.camera:camera-view:${Versions.cameraView}"
}

object Mdc {
object UI {
const val materialDesign = "com.google.android.material:material:${Versions.materialDesign}"
}

Expand Down
8 changes: 4 additions & 4 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object Versions {
const val androidBuildTools = "30.0.3"

const val androidGradle = "4.2.1"
const val kotlin = "1.5.0"
const val kotlin = "1.5.10"

const val appcompat = "1.3.0"

Expand All @@ -15,11 +15,11 @@ object Versions {

const val materialDesign = "1.3.0"

const val barcodeScanning = "16.1.1"
const val barcodeScanningGms = "16.1.4"
const val barcodeScanning = "16.1.2"
const val barcodeScanningGms = "16.1.5"

const val detekt = "1.17.1"
const val gradleVersions = "0.38.0"
const val gradleVersions = "0.39.0"
const val dokka = "1.4.32"

const val junit = "5.7.2"
Expand Down
2 changes: 1 addition & 1 deletion quickie/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ dependencies {
}

group = "io.github.g00fy2.quickie"
version = "1.1.0"
version = "1.1.1"

tasks.register<Jar>("androidJavadocJar") {
archiveClassifier.set("javadoc")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@ package io.github.g00fy2.quickie
import androidx.camera.core.ExperimentalGetImage
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import com.google.android.gms.tasks.Task
import com.google.mlkit.vision.barcode.Barcode
import com.google.mlkit.vision.barcode.BarcodeScannerOptions
import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.common.InputImage

@ExperimentalGetImage
internal class QRCodeAnalyzer(
private val barcodeFormats: IntArray,
private val onSuccess: ((Barcode) -> Unit),
private val onFailure: ((Exception) -> Unit)
) : ImageAnalysis.Analyzer {

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

@ExperimentalGetImage
override fun analyze(imageProxy: ImageProxy) {
if (pendingTask?.isComplete == false || imageProxy.image == null) return
if (imageProxy.image == null) return

pendingTask = barcodeScanner.process(imageProxy.toInputImage())
barcodeScanner.process(imageProxy.toInputImage())
.addOnSuccessListener { codes -> codes.mapNotNull { it }.firstOrNull()?.let { onSuccess(it) } }
.addOnFailureListener { onFailure(it) }
.addOnCompleteListener { imageProxy.close() }
}

@ExperimentalGetImage
private fun ImageProxy.toInputImage() = InputImage.fromMediaImage(image!!, imageInfo.rotationDegrees)
}
16 changes: 10 additions & 6 deletions quickie/src/main/kotlin/io/github/g00fy2/quickie/QROverlayView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ internal class QROverlayView @JvmOverloads constructor(
}
if (drawableRes != 0) {
try {
ResourcesCompat.getDrawable(resources, drawableRes, null)?.limitDrawableSize(ICON_DP_MAX_HEIGHT)?.let {
ResourcesCompat.getDrawable(resources, drawableRes, null)?.limitDrawableSize()?.let {
titleTextView.setCompoundDrawables(null, it, null, null)
}
} catch (ignore: NotFoundException) {
Expand Down Expand Up @@ -135,10 +135,14 @@ internal class QROverlayView @JvmOverloads constructor(
layoutParams = params
}

private fun Drawable.limitDrawableSize(maxDpHeight: Int): Drawable {
val scale = (maxDpHeight * resources.displayMetrics.density) / minimumHeight
if (scale < 1) setBounds(0, 0, (minimumWidth * scale).roundToInt(), (minimumHeight * scale).roundToInt())
else setBounds(0, 0, minimumWidth, minimumHeight)
private fun Drawable.limitDrawableSize(): Drawable {
val heightLimit = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, ICON_MAX_HEIGHT, resources.displayMetrics)
val scale = heightLimit / minimumHeight
if (scale < 1) {
setBounds(0, 0, (minimumWidth * scale).roundToInt(), (minimumHeight * scale).roundToInt())
} else {
setBounds(0, 0, minimumWidth, minimumHeight)
}
return this
}

Expand All @@ -147,6 +151,6 @@ internal class QROverlayView @JvmOverloads constructor(
private const val STROKE_WIDTH = 4f
private const val OUT_RADIUS = 16f
private const val FRAME_MARGIN_RATIO = 1f / 4
private const val ICON_DP_MAX_HEIGHT = 56
private const val ICON_MAX_HEIGHT = 56f
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ContextThemeWrapper
import androidx.camera.core.CameraSelector
import androidx.camera.core.ExperimentalGetImage
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
Expand All @@ -28,11 +27,10 @@ import io.github.g00fy2.quickie.utils.PlayServicesValidator
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

@ExperimentalGetImage
internal class QRScannerActivity : AppCompatActivity() {

private lateinit var binding: QuickieScannerActivityBinding
private lateinit var cameraExecutor: ExecutorService
private lateinit var analysisExecutor: ExecutorService
private var barcodeFormats = intArrayOf(Barcode.FORMAT_QR_CODE)

override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -46,7 +44,7 @@ internal class QRScannerActivity : AppCompatActivity() {
setupEdgeToEdgeUI()
applyScannerConfig()

cameraExecutor = Executors.newSingleThreadExecutor()
analysisExecutor = Executors.newSingleThreadExecutor()

requestCameraPermissionIfMissing { granted ->
if (granted) {
Expand All @@ -60,7 +58,7 @@ internal class QRScannerActivity : AppCompatActivity() {

override fun onDestroy() {
super.onDestroy()
cameraExecutor.shutdown()
analysisExecutor.shutdown()
}

private fun startCamera() {
Expand All @@ -74,13 +72,14 @@ internal class QRScannerActivity : AppCompatActivity() {
.setTargetResolution(Size(1280, 720))
.build()
.also {
it.setAnalyzer(cameraExecutor,
it.setAnalyzer(analysisExecutor,
QRCodeAnalyzer(
barcodeFormats,
{ barcode ->
it.clearAnalyzer()
onSuccess(barcode)
}, { exception ->
},
{ exception ->
it.clearAnalyzer()
onFailure(exception)
}
Expand Down
2 changes: 1 addition & 1 deletion sample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ android {
dependencies {
implementation(project(":quickie"))

implementation(Deps.Mdc.materialDesign)
implementation(Deps.UI.materialDesign)
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import io.github.g00fy2.quickiesample.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {

private lateinit var binding: ActivityMainBinding
private var snackbar: Snackbar? = null
private var selectedBarcodeFormat = BarcodeFormat.FORMAT_ALL_FORMATS

private val scanQrCode = registerForActivityResult(ScanQRCode(), ::showSnackbar)
Expand All @@ -33,16 +32,13 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

setupBarcodeFormatDropdown()
setBarcodeFormatDropdown()

binding.qrScannerButton.setOnClickListener {
snackbar?.dismiss()
scanQrCode.launch(null)
}

binding.customScannerButton.setOnClickListener {
snackbar?.dismiss()
scanCustomCode.launch(
ScannerConfig.build {
setBarcodeFormats(listOf(selectedBarcodeFormat))
Expand All @@ -53,13 +49,13 @@ class MainActivity : AppCompatActivity() {
}
}

private fun setupBarcodeFormatDropdown() {
private fun setBarcodeFormatDropdown() {
ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, BarcodeFormat.values().map { it.name }).let {
binding.barcodeFormatsAutoCompleteTextView.setAdapter(it)
binding.barcodeFormatsAutoCompleteTextView.setText(it.getItem(it.getPosition(selectedBarcodeFormat.name)), false)
binding.barcodeFormatsAutoCompleteTextView.setOnItemClickListener { _, _, position, _ ->
selectedBarcodeFormat = BarcodeFormat.values()[position]
}
}
binding.barcodeFormatsAutoCompleteTextView.setOnItemClickListener { _, _, position, _ ->
selectedBarcodeFormat = BarcodeFormat.values()[position]
}
}

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

snackbar = Snackbar.make(binding.root, text, Snackbar.LENGTH_INDEFINITE).apply {
Snackbar.make(binding.root, text, Snackbar.LENGTH_INDEFINITE).apply {
view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text)?.maxLines = 5
if (result is QRSuccess && result.content is QRContent.Url) {
setAction(R.string.open_action) { openUrl(result.content.rawValue) }
} else {
setAction(R.string.ok_action) { }
}
}
snackbar?.show()
}.show()
}

private fun openUrl(url: String) {
Expand Down

0 comments on commit 30e800c

Please sign in to comment.