diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 64532f5a..7acfac69 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -31,6 +31,11 @@
android:windowSoftInputMode="adjustResize"
tools:targetApi="33">
+
+
+ if (isGranted) {
+ setupScanner()
+ } else {
+ Toast.makeText(this, "Camera permission denied.", Toast.LENGTH_SHORT).show()
+ sendResultAndFinish(null)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ if (hasCameraPermission()) {
+ setupScanner()
+ } else {
+ cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
+ }
+ }
+
+ private fun hasCameraPermission(): Boolean {
+ return checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
+ }
+
+ private fun setupScanner() {
+ barcodeView = DecoratedBarcodeView(this).apply {
+ barcodeView.decoderFactory = DefaultDecoderFactory(listOf(BarcodeFormat.QR_CODE))
+ initializeFromIntent(intent)
+ decodeContinuous(object : BarcodeCallback {
+ override fun barcodeResult(result: BarcodeResult?) {
+ result?.text?.let {
+ sendResultAndFinish(it)
+ }
+ }
+
+ override fun possibleResultPoints(resultPoints: MutableList?) {}
+ })
+ }
+
+ setContentView(barcodeView)
+ safeResumeScanner()
+ }
+
+ private fun safeResumeScanner() {
+ try {
+ barcodeView.resume()
+ } catch (e: Exception) {
+ Log.e("QrScanner", "Camera resume failed: ${e.message}")
+ if (!hasFailedToResumeCamera) {
+ hasFailedToResumeCamera = true
+ Toast.makeText(this, "Camera is in use by another app.", Toast.LENGTH_LONG).show()
+ barcodeView.postDelayed({
+ sendResultAndFinish(null)
+ }, 1500)
+ }
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ if (::barcodeView.isInitialized && hasWindowFocus()) {
+ safeResumeScanner()
+ }
+ }
+
+ override fun onPause() {
+ super.onPause()
+ if (::barcodeView.isInitialized) {
+ barcodeView.pause()
+ }
+ }
+
+ override fun onWindowFocusChanged(hasFocus: Boolean) {
+ super.onWindowFocusChanged(hasFocus)
+ if (::barcodeView.isInitialized) {
+ if (hasFocus) safeResumeScanner() else barcodeView.pause()
+ }
+ }
+
+ private fun sendResultAndFinish(result: String?) {
+ setResult(RESULT_OK, Intent().putExtra("qr_result", result))
+ finish()
+ }
+}
diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/QrCodeScanner.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/QrCodeScanner.kt
index 823f7522..d61f5302 100644
--- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/QrCodeScanner.kt
+++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/QrCodeScanner.kt
@@ -1,37 +1,27 @@
package com.greenart7c3.nostrsigner.ui
+import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
-import androidx.lifecycle.compose.LocalLifecycleOwner
-import com.google.zxing.client.android.Intents
-import com.journeyapps.barcodescanner.ScanContract
-import com.journeyapps.barcodescanner.ScanOptions
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.ui.platform.LocalContext
+import com.greenart7c3.nostrsigner.QrCodeScannerActivity
@Composable
-fun SimpleQrCodeScanner(onScan: (String?) -> Unit) {
- val lifecycleOwner = LocalLifecycleOwner.current
+fun SimpleQrCodeScanner(
+ onScan: (String?) -> Unit,
+) {
+ val context = LocalContext.current
+ val launcher = rememberLauncherForActivityResult(
+ contract = ActivityResultContracts.StartActivityForResult(),
+ ) { result ->
+ val text = result.data?.getStringExtra("qr_result")
+ onScan(text)
+ }
- val qrLauncher =
- rememberLauncherForActivityResult(ScanContract()) {
- if (it.contents != null) {
- onScan(it.contents)
- } else {
- onScan(null)
- }
- }
-
- val scanOptions =
- ScanOptions().apply {
- setDesiredBarcodeFormats(ScanOptions.QR_CODE)
- setPrompt("Point to the QR Code")
- setBeepEnabled(false)
- setOrientationLocked(false)
- addExtra(Intents.Scan.SCAN_TYPE, Intents.Scan.MIXED_SCAN)
- }
-
- DisposableEffect(lifecycleOwner) {
- qrLauncher.launch(scanOptions)
- onDispose { }
+ LaunchedEffect(Unit) {
+ val intent = Intent(context, QrCodeScannerActivity::class.java)
+ launcher.launch(intent)
}
}