diff --git a/AGENTS.md b/AGENTS.md index c2750ec..34da7fa 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -158,7 +158,9 @@ Established 2026-08-25, and it decides more than it looks like: silently never matches — while the phone's own camera app, which tries both, does. The scanner asks for `Intents.Scan.MIXED_SCAN`, which alternates normal and inverted frames; keep it that way rather than - making the server dictate the colours. + making the server dictate the colours. `EnrollmentScanActivity` also + turns off the library's 10% framing-rect inset (it decodes only what is + inside it) and its laser/result-point decorations. - **AGP 9 refuses `Provider`s in the source-set API**: generated sources go through `androidComponents.onVariants { it.sources.java?.addGenerated SourceDirectory(task, Task::outputDir) }`, which also carries the task diff --git a/app/androidApp/src/main/AndroidManifest.xml b/app/androidApp/src/main/AndroidManifest.xml index 6e0ac26..a334a2e 100644 --- a/app/androidApp/src/main/AndroidManifest.xml +++ b/app/androidApp/src/main/AndroidManifest.xml @@ -40,5 +40,18 @@ + + + diff --git a/app/androidApp/src/main/kotlin/com/example/aiapp/EnrollmentScanActivity.kt b/app/androidApp/src/main/kotlin/com/example/aiapp/EnrollmentScanActivity.kt new file mode 100644 index 0000000..bd91ac1 --- /dev/null +++ b/app/androidApp/src/main/kotlin/com/example/aiapp/EnrollmentScanActivity.kt @@ -0,0 +1,36 @@ +package com.example.aiapp + +import android.view.View +import com.journeyapps.barcodescanner.CaptureActivity +import com.journeyapps.barcodescanner.DecoratedBarcodeView + +/** + * The screen behind the Settings screen's "Scan QR code" button: + * zxing-android-embedded's capture activity with two of its defaults taken + * off, both because they put work on the person holding the phone. + * + * - **It decodes only the framing rectangle**, which + * `CameraPreview.marginFraction` insets by 10% from every edge and + * `DecoderThread` crops each frame to before the decoder sees it. A code + * that fills the viewfinder keeps decoding -- measured, not assumed -- + * but it does so having spent its quiet zone and margin for error on + * the crop, and anything further out is simply not looked at. Decoding + * the whole preview costs nothing and means the framing is never the + * user's problem. + * - **It decorates the preview** with a red laser line and the dots the + * detector scatters wherever it finds a candidate pattern. That is the + * library's house style; a plain preview is ours. + * + * Orientation is left to the sensor rather than pinned to landscape as the + * library's own manifest entry pins it, so the phone can be held whichever + * way the code is in front of it. + */ +class EnrollmentScanActivity : CaptureActivity() { + override fun initializeContent(): DecoratedBarcodeView { + val view = super.initializeContent() + view.barcodeView.marginFraction = 0.0 + view.viewFinder.visibility = View.GONE + view.statusView.visibility = View.GONE + return view + } +} diff --git a/app/androidApp/src/main/kotlin/com/example/aiapp/SettingsScreen.kt b/app/androidApp/src/main/kotlin/com/example/aiapp/SettingsScreen.kt index af406b9..e99820c 100644 --- a/app/androidApp/src/main/kotlin/com/example/aiapp/SettingsScreen.kt +++ b/app/androidApp/src/main/kotlin/com/example/aiapp/SettingsScreen.kt @@ -87,6 +87,9 @@ fun SettingsScreen( scanLauncher.launch( ScanOptions() .setDesiredBarcodeFormats(ScanOptions.QR_CODE) + .setCaptureActivity(EnrollmentScanActivity::class.java) + // Follow the phone, not the library's landscape pin. + .setOrientationLocked(false) // Decode both polarities: ZXing otherwise looks only for a // dark code on a light ground, and ai-server's QR is block // characters in the terminal's foreground colour -- so on a