From 7be1a74cfdf0ecbb93c36b2089a02a8c7120d432 Mon Sep 17 00:00:00 2001 From: Alexander Bakker Date: Tue, 19 Jan 2021 20:26:45 +0100 Subject: [PATCH] Force higher resolution for analysis and run it on a background thread --- .../aegis/helpers/QrCodeAnalyzer.java | 6 ++- .../aegis/ui/AegisActivity.java | 1 + .../com/beemdevelopment/aegis/ui/Dialogs.java | 5 ++ .../aegis/ui/MainActivity.java | 3 +- .../aegis/ui/ScannerActivity.java | 52 +++++++++++++------ 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/beemdevelopment/aegis/helpers/QrCodeAnalyzer.java b/app/src/main/java/com/beemdevelopment/aegis/helpers/QrCodeAnalyzer.java index 1c0a7f73..99a3029f 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/helpers/QrCodeAnalyzer.java +++ b/app/src/main/java/com/beemdevelopment/aegis/helpers/QrCodeAnalyzer.java @@ -1,6 +1,9 @@ package com.beemdevelopment.aegis.helpers; +import android.os.Handler; +import android.os.Looper; import android.util.Log; +import android.util.Size; import androidx.annotation.NonNull; import androidx.camera.core.ImageAnalysis; @@ -23,6 +26,7 @@ import static android.graphics.ImageFormat.YUV_444_888; public class QrCodeAnalyzer implements ImageAnalysis.Analyzer { private static final String TAG = QrCodeAnalyzer.class.getSimpleName(); + public static final Size RESOLUTION = new Size(1200, 1600); private final QrCodeAnalyzer.Listener _listener; @@ -53,7 +57,7 @@ public class QrCodeAnalyzer implements ImageAnalysis.Analyzer { try { Result result = reader.decode(bitmap); if (_listener != null) { - _listener.onQrCodeDetected(result); + new Handler(Looper.getMainLooper()).post(() -> _listener.onQrCodeDetected(result)); } } catch (ChecksumException | FormatException | NotFoundException ignored) { diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java index 6d3a057c..1109d7d4 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java @@ -53,6 +53,7 @@ public abstract class AegisActivity extends AppCompatActivity implements AegisAp } @Override + @CallSuper protected void onDestroy() { _app.unregisterLockListener(this); super.onDestroy(); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/Dialogs.java b/app/src/main/java/com/beemdevelopment/aegis/ui/Dialogs.java index acbb6c52..ed7eb818 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/Dialogs.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/Dialogs.java @@ -342,6 +342,11 @@ public class Dialogs { .setNeutralButton(R.string.details, (dialog1, which) -> { textDetails.setVisibility(View.VISIBLE); }) + .setOnDismissListener(dialog12 -> { + if (listener != null) { + listener.onClick(dialog12, -1); + } + }) .create(); dialog.setOnShowListener(d -> { diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java index 1863ac53..69a1b8f4 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java @@ -29,6 +29,7 @@ import com.beemdevelopment.aegis.ViewMode; import com.beemdevelopment.aegis.helpers.BitmapHelper; import com.beemdevelopment.aegis.helpers.FabScrollHelper; import com.beemdevelopment.aegis.helpers.PermissionHelper; +import com.beemdevelopment.aegis.helpers.QrCodeAnalyzer; import com.beemdevelopment.aegis.otp.GoogleAuthInfo; import com.beemdevelopment.aegis.otp.GoogleAuthInfoException; import com.beemdevelopment.aegis.ui.fragments.BackupsPreferencesFragment; @@ -297,7 +298,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene try (InputStream inputStream = getContentResolver().openInputStream(inputFile)) { bitmap = BitmapFactory.decodeStream(inputStream, null, bmOptions); - bitmap = BitmapHelper.resize(bitmap, 640, 480); + bitmap = BitmapHelper.resize(bitmap, QrCodeAnalyzer.RESOLUTION.getWidth(), QrCodeAnalyzer.RESOLUTION.getHeight()); } int[] intArray = new int[bitmap.getWidth() * bitmap.getHeight()]; diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java index e851c613..c6722de3 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/ScannerActivity.java @@ -28,6 +28,8 @@ import com.google.zxing.Result; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Listener { private ProcessCameraProvider _cameraProvider; @@ -37,7 +39,9 @@ public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Lis private int _currentLens; private Menu _menu; + private ImageAnalysis _analysis; private PreviewView _previewView; + private ExecutorService _executor; private int _batchId = 0; private int _batchIndex = -1; @@ -51,6 +55,7 @@ public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Lis _entries = new ArrayList<>(); _lenses = new ArrayList<>(); _previewView = findViewById(R.id.preview_view); + _executor = Executors.newSingleThreadExecutor(); _cameraProviderFuture = ProcessCameraProvider.getInstance(this); _cameraProviderFuture.addListener(() -> { @@ -76,6 +81,12 @@ public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Lis }, ContextCompat.getMainExecutor(this)); } + @Override + protected void onDestroy() { + _executor.shutdownNow(); + super.onDestroy(); + } + @Override protected void onSetTheme() { setTheme(ThemeMap.FULLSCREEN); @@ -91,7 +102,7 @@ public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Lis @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.action_camera) { - _cameraProvider.unbindAll(); + unbindPreview(_cameraProvider); _currentLens = _currentLens == CameraSelector.LENS_FACING_BACK ? CameraSelector.LENS_FACING_FRONT : CameraSelector.LENS_FACING_BACK; bindPreview(_cameraProvider); updateCameraIcon(); @@ -138,29 +149,38 @@ public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Lis .requireLensFacing(_currentLens) .build(); - ImageAnalysis analysis = new ImageAnalysis.Builder() + _analysis = new ImageAnalysis.Builder() + .setTargetResolution(QrCodeAnalyzer.RESOLUTION) .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .build(); - analysis.setAnalyzer(ContextCompat.getMainExecutor(this), new QrCodeAnalyzer(this)); + _analysis.setAnalyzer(_executor, new QrCodeAnalyzer(this)); - cameraProvider.bindToLifecycle(this, selector, preview, analysis); + cameraProvider.bindToLifecycle(this, selector, preview, _analysis); + } + + private void unbindPreview(@NonNull ProcessCameraProvider cameraProvider) { + _analysis = null; + cameraProvider.unbindAll(); } @Override public void onQrCodeDetected(Result result) { - try { - Uri uri = Uri.parse(result.getText().trim()); - if (uri.getScheme() != null && uri.getScheme().equals(GoogleAuthInfo.SCHEME_EXPORT)) { - handleExportUri(uri); - } else { - handleUri(uri); + if (_analysis != null) { + try { + Uri uri = Uri.parse(result.getText().trim()); + if (uri.getScheme() != null && uri.getScheme().equals(GoogleAuthInfo.SCHEME_EXPORT)) { + handleExportUri(uri); + } else { + handleUri(uri); + } + } catch (GoogleAuthInfoException e) { + e.printStackTrace(); + + unbindPreview(_cameraProvider); + Dialogs.showErrorDialog(this, + e.isPhoneFactor() ? R.string.read_qr_error_phonefactor : R.string.read_qr_error, + e, ((dialog, which) -> bindPreview(_cameraProvider))); } - } catch (GoogleAuthInfoException e) { - e.printStackTrace(); - Dialogs.showErrorDialog(this, - e.isPhoneFactor() ? R.string.read_qr_error_phonefactor : R.string.read_qr_error, - e, ((dialog, which) -> bindPreview(_cameraProvider))); - _cameraProvider.unbindAll(); } }