Add in-app qr code scanner
This commit is contained in:
63
app/src/play/java/io/nekohasekai/sfa/vendor/MLKitQRCodeAnalyzer.kt
vendored
Normal file
63
app/src/play/java/io/nekohasekai/sfa/vendor/MLKitQRCodeAnalyzer.kt
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
package io.nekohasekai.sfa.vendor
|
||||
|
||||
import android.util.Log
|
||||
import androidx.camera.core.ExperimentalGetImage
|
||||
import androidx.camera.core.ImageAnalysis
|
||||
import androidx.camera.core.ImageProxy
|
||||
import com.google.mlkit.vision.barcode.BarcodeScannerOptions
|
||||
import com.google.mlkit.vision.barcode.BarcodeScanning
|
||||
import com.google.mlkit.vision.barcode.common.Barcode
|
||||
import com.google.mlkit.vision.common.InputImage
|
||||
|
||||
// kanged from: https://github.com/G00fY2/quickie/blob/main/quickie/src/main/kotlin/io/github/g00fy2/quickie/QRCodeAnalyzer.kt
|
||||
|
||||
class MLKitQRCodeAnalyzer(
|
||||
private val onSuccess: ((String) -> Unit),
|
||||
private val onFailure: ((Exception) -> Unit),
|
||||
) : ImageAnalysis.Analyzer {
|
||||
|
||||
private val barcodeScanner =
|
||||
BarcodeScanning.getClient(
|
||||
BarcodeScannerOptions.Builder().setBarcodeFormats(Barcode.FORMAT_QR_CODE).build()
|
||||
)
|
||||
|
||||
@Volatile
|
||||
private var failureOccurred = false
|
||||
private var failureTimestamp = 0L
|
||||
|
||||
@ExperimentalGetImage
|
||||
override fun analyze(image: ImageProxy) {
|
||||
if (image.image == null) return
|
||||
|
||||
if (failureOccurred && System.currentTimeMillis() - failureTimestamp < 1000L) {
|
||||
Log.d("MLKitQRCodeAnalyzer", "throttled analysis since error occurred in previous pass")
|
||||
image.close()
|
||||
return
|
||||
}
|
||||
|
||||
failureOccurred = false
|
||||
barcodeScanner.process(image.toInputImage())
|
||||
.addOnSuccessListener { codes ->
|
||||
if (codes.isNotEmpty()) {
|
||||
val rawValue = codes.firstOrNull()?.rawValue
|
||||
if (rawValue != null) {
|
||||
Log.d("MLKitQRCodeAnalyzer", "barcode decode success: $rawValue")
|
||||
onSuccess(rawValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
.addOnFailureListener {
|
||||
failureOccurred = true
|
||||
failureTimestamp = System.currentTimeMillis()
|
||||
onFailure(it)
|
||||
}
|
||||
.addOnCompleteListener {
|
||||
image.close()
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalGetImage
|
||||
@Suppress("UnsafeCallOnNullableType")
|
||||
private fun ImageProxy.toInputImage() =
|
||||
InputImage.fromMediaImage(image!!, imageInfo.rotationDegrees)
|
||||
}
|
||||
@@ -3,12 +3,14 @@ package io.nekohasekai.sfa.vendor
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.camera.core.ImageAnalysis
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
|
||||
import com.google.android.play.core.appupdate.AppUpdateOptions
|
||||
import com.google.android.play.core.install.model.AppUpdateType
|
||||
import com.google.android.play.core.install.model.InstallStatus
|
||||
import com.google.android.play.core.install.model.UpdateAvailability
|
||||
import com.google.mlkit.common.MlKitException
|
||||
import io.nekohasekai.sfa.R
|
||||
|
||||
object Vendor : VendorInterface {
|
||||
@@ -74,4 +76,18 @@ object Vendor : VendorInterface {
|
||||
.setMessage(R.string.no_updates_available).setPositiveButton(R.string.ok, null).show()
|
||||
}
|
||||
|
||||
override fun createQRCodeAnalyzer(
|
||||
onSuccess: (String) -> Unit,
|
||||
onFailure: (Exception) -> Unit
|
||||
): ImageAnalysis.Analyzer? {
|
||||
try {
|
||||
return MLKitQRCodeAnalyzer(onSuccess, onFailure)
|
||||
} catch (exception: Exception) {
|
||||
if (exception !is MlKitException || exception.errorCode != MlKitException.UNAVAILABLE) {
|
||||
Log.e(TAG, "failed to create MLKitQRCodeAnalyzer", exception)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user