Force higher resolution for analysis and run it on a background thread

This commit is contained in:
Alexander Bakker 2021-01-19 20:26:45 +01:00
parent 22c93bf5c6
commit 7be1a74cfd
5 changed files with 49 additions and 18 deletions

View file

@ -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) {

View file

@ -53,6 +53,7 @@ public abstract class AegisActivity extends AppCompatActivity implements AegisAp
}
@Override
@CallSuper
protected void onDestroy() {
_app.unregisterLockListener(this);
super.onDestroy();

View file

@ -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 -> {

View file

@ -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()];

View file

@ -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();
}
}