diff --git a/quickie/src/main/AndroidManifest.xml b/quickie/src/main/AndroidManifest.xml
index cf62fb9d..242cb9ea 100644
--- a/quickie/src/main/AndroidManifest.xml
+++ b/quickie/src/main/AndroidManifest.xml
@@ -7,7 +7,8 @@
android:required="false"/>
-
+
+
+ uri?.let { analyzeImageFromGallery(it) }
+ }
internal var errorDialog: Dialog? = null
set(value) {
field = value
@@ -68,6 +77,7 @@ internal class QRScannerActivity : AppCompatActivity() {
setupEdgeToEdgeUI()
applyScannerConfig()
+ setupGalleryButton()
analysisExecutor = Executors.newSingleThreadExecutor()
@@ -81,6 +91,64 @@ internal class QRScannerActivity : AppCompatActivity() {
}
}
+ private fun setupGalleryButton() {
+ binding.selectFromGalleryButton.setOnClickListener {
+ launchGalleryPicker()
+ }
+ }
+ private val storagePermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
+ if (granted) {
+ galleryLauncher.launch("image/*")
+ } else {
+ onFailure(Exception("Storage permission required to select images"))
+ }
+ }
+ private fun launchGalleryPicker() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED) {
+ galleryLauncher.launch("image/*")
+ } else {
+ storagePermissionLauncher.launch(Manifest.permission.READ_MEDIA_IMAGES)
+ }
+ } else {
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
+ galleryLauncher.launch("image/*")
+ } else {
+ storagePermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
+ }
+ }
+ }
+
+ private fun analyzeImageFromGallery(imageUri: Uri) {
+ try {
+ val image = InputImage.fromFilePath(this, imageUri)
+ val options = BarcodeScannerOptions.Builder()
+ .setBarcodeFormats(barcodeFormats.sum())
+ .build()
+
+ val scanner = BarcodeScanning.getClient(options)
+
+ binding.overlayView.isLoading = true
+
+ scanner.process(image)
+ .addOnSuccessListener { barcodes ->
+ binding.overlayView.isLoading = false
+ if (barcodes.isNullOrEmpty()) {
+ onFailure(Exception("No QR code found in the image"))
+ } else {
+ onSuccess(barcodes.first())
+ }
+ }
+ .addOnFailureListener { e ->
+ binding.overlayView.isLoading = false
+ onFailure(e)
+ }
+ } catch (e: Exception) {
+ binding.overlayView.isLoading = false
+ onFailure(e)
+ }
+ }
+
override fun onDestroy() {
super.onDestroy()
analysisExecutor.shutdown()
diff --git a/quickie/src/main/res/drawable/quickie_rounded_rectangle_button.xml b/quickie/src/main/res/drawable/quickie_rounded_rectangle_button.xml
new file mode 100644
index 00000000..d2cc4b54
--- /dev/null
+++ b/quickie/src/main/res/drawable/quickie_rounded_rectangle_button.xml
@@ -0,0 +1,14 @@
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/quickie/src/main/res/layout/quickie_scanner_activity.xml b/quickie/src/main/res/layout/quickie_scanner_activity.xml
index 9b379f8d..85a3260d 100644
--- a/quickie/src/main/res/layout/quickie_scanner_activity.xml
+++ b/quickie/src/main/res/layout/quickie_scanner_activity.xml
@@ -19,4 +19,15 @@
android:visibility="invisible"
tools:visibility="visible"
/>
+
+
\ No newline at end of file