Fix bugs related to qr code scanning. Fixes #13

This commit is contained in:
Michael Mikovsky
2025-07-27 16:27:31 -06:00
parent 5c2b1fef2e
commit 1bae273abd
3 changed files with 86 additions and 48 deletions
@@ -49,12 +49,14 @@ public class CodeGenTask implements Callable<List<Bitmap>> {
private final int randID; private final int randID;
private final int qrSize; private final int qrSize;
private final int qrCount; private final int qrCount;
private final int imageSize;
public CodeGenTask(String data, int randID, int qrSize, int qrCount) { public CodeGenTask(String data, int randID, int qrSize, int qrCount, int imageSize) {
this.data = data; this.data = data;
this.randID = randID; this.randID = randID;
this.qrSize = qrSize; this.qrSize = qrSize;
this.qrCount = qrCount; this.qrCount = qrCount;
this.imageSize = imageSize;
} }
@Override @Override
@@ -68,14 +70,18 @@ public class CodeGenTask implements Callable<List<Bitmap>> {
end = data.length(); end = data.length();
} }
try { try {
// alert("test", ""+Math.ceil((double)data.length()/(double)qrSize)); Bitmap unscaledBitmap = generateQrCode(
qrBitmaps.add(generateQrCode(
FileEditor.byteToChar(FileEditor.internalDataVersion, FileEditor.lengthHeaderBytes) + FileEditor.byteToChar(FileEditor.internalDataVersion, FileEditor.lengthHeaderBytes) +
String.valueOf(FileEditor.byteToChar(randID, FileEditor.lengthHeaderBytes)) + String.valueOf(FileEditor.byteToChar(randID, FileEditor.lengthHeaderBytes)) +
FileEditor.byteToChar(i, FileEditor.lengthHeaderBytes) + FileEditor.byteToChar(i, FileEditor.lengthHeaderBytes) +
FileEditor.byteToChar(qrCount - 1, FileEditor.lengthHeaderBytes) + FileEditor.byteToChar(qrCount - 1, FileEditor.lengthHeaderBytes) +
data.substring(start, end) data.substring(start, end)
)); );
if(unscaledBitmap == null) {
AlertManager.error("Generated image was null!");
continue;
}
qrBitmaps.add(Bitmap.createScaledBitmap(unscaledBitmap, imageSize, imageSize, false));
// alert("title", ""+(qrCount-1)); // alert("title", ""+(qrCount-1));
}catch (WriterException e){ }catch (WriterException e){
AlertManager.error(e); AlertManager.error(e);
@@ -1,10 +1,12 @@
package com.ridgebotics.ridgescout.ui.transfer.codes; package com.ridgebotics.ridgescout.ui.transfer.codes;
import android.app.Activity;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.os.CountDownTimer; import android.os.CountDownTimer;
import android.os.Handler; import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -26,12 +28,18 @@ import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.ridgebotics.ridgescout.utility.TaskRunner; import com.ridgebotics.ridgescout.utility.TaskRunner;
import java.lang.reflect.Executable;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
// Class to show the code transfer thing. // Class to show the code transfer thing.
public class CodeGeneratorView extends Fragment { public class CodeGeneratorView extends Fragment {
@@ -51,6 +59,7 @@ public class CodeGeneratorView extends Fragment {
private static final int defaultQrDelay = 12; private static final int defaultQrDelay = 12;
private int imageSize;
private int minQrSize = 0; private int minQrSize = 0;
private int qrSize = 200; private int qrSize = 200;
@@ -84,6 +93,12 @@ public class CodeGeneratorView extends Fragment {
qrIndexN = binding.qrIndexN; qrIndexN = binding.qrIndexN;
qrIndexD = binding.qrIndexD; qrIndexD = binding.qrIndexD;
DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
// int height = displaymetrics.heightPixels;
imageSize = displaymetrics.widthPixels;
// = 800;
String compressed = new String(FileEditor.blockCompress(data, FileEditor.lengthHeaderBytes), StandardCharsets.ISO_8859_1); String compressed = new String(FileEditor.blockCompress(data, FileEditor.lengthHeaderBytes), StandardCharsets.ISO_8859_1);
if(compressed.isEmpty()){ if(compressed.isEmpty()){
@@ -115,6 +130,7 @@ public class CodeGeneratorView extends Fragment {
@Override @Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
qrDelay = ((double) progress /maxQrSpeed) - 1; qrDelay = ((double) progress /maxQrSpeed) - 1;
// startLoop();
} }
@Override @Override
public void onStartTrackingTouch(SeekBar seekBar) {} public void onStartTrackingTouch(SeekBar seekBar) {}
@@ -134,12 +150,13 @@ public class CodeGeneratorView extends Fragment {
qrCount = ((data.length()+1)/qrSize) +1; qrCount = ((data.length()+1)/qrSize) +1;
qrIndexD.setText(String.valueOf(qrCount)); qrIndexD.setText(String.valueOf(qrCount));
sendData(data); sendData(data);
// startLoop();
} }
}); });
AlertManager.startLoading("Generating codes..."); AlertManager.startLoading("Generating codes...");
new TaskRunner().executeAsync(new CodeGenTask(data, new Random().nextInt(255), qrSize, qrCount), result -> { new TaskRunner().executeAsync(new CodeGenTask(data, new Random().nextInt(255), qrSize, qrCount, imageSize), result -> {
qrBitmaps = result; qrBitmaps = result;
AlertManager.stopLoading(); AlertManager.stopLoading();
qrIndex = 0; qrIndex = 0;
@@ -167,14 +184,17 @@ public class CodeGeneratorView extends Fragment {
qrIndexN.setText(String.valueOf(qrIndex+1)); qrIndexN.setText(String.valueOf(qrIndex+1));
} }
private boolean shouldstop = false;
private void startLoop() { private void startLoop() {
final Handler handler = new Handler(); final Handler handler = new Handler();
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
if(shouldstop){
return;
}
try{ try{
updateQr(); updateQr();
} }
@@ -188,7 +208,12 @@ public class CodeGeneratorView extends Fragment {
} }
} }
}; };
handler.post(runnable); handler.post(runnable);
} }
@Override
public void onDestroy() {
super.onDestroy();
shouldstop = true;
}
} }
@@ -1,31 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<SeekBar
android:id="@+id/qrSizeSlider"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginBottom="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/qrImage" />
<SeekBar
android:id="@+id/qrSpeedSlider"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginBottom="60dp"
app:layout_constraintBottom_toTopOf="@+id/qrSizeSlider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.971"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/qrImage"
app:layout_constraintVertical_bias="0.93" />
<ImageView <ImageView
android:id="@+id/qrImage" android:id="@+id/qrImage"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -36,23 +15,48 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <LinearLayout
android:id="@+id/qrSpeedText" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_margin="3dp"
android:text="QR Speed" android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/qrSpeedSlider" android:background="@drawable/border"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:id="@+id/qrSizeText" <TextView
android:layout_width="wrap_content" android:id="@+id/qrSpeedText"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_marginStart="8dp" android:layout_height="wrap_content"
android:text="QR Size" android:layout_marginStart="8dp"
app:layout_constraintBottom_toTopOf="@+id/qrSizeSlider" android:text="QR Speed"
app:layout_constraintStart_toStartOf="parent" /> android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
app:layout_constraintBottom_toTopOf="@+id/qrSpeedSlider" />
<SeekBar
android:id="@+id/qrSpeedSlider"
android:layout_width="match_parent"
android:layout_height="48dp" />
<TextView
android:id="@+id/qrSizeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="QR Size"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" />
<SeekBar
android:id="@+id/qrSizeSlider"
android:layout_width="match_parent"
android:layout_height="48dp"
tools:layout_editor_absoluteY="135dp" />
</LinearLayout>
<TextView <TextView
android:id="@+id/qrIndexN" android:id="@+id/qrIndexN"
@@ -60,7 +64,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="0" android:text="0"
app:layout_constraintEnd_toStartOf="@+id/qrIndexSlash" app:layout_constraintEnd_toStartOf="@+id/qrIndexSlash"
app:layout_constraintTop_toBottomOf="@+id/qrImage" /> app:layout_constraintTop_toBottomOf="@+id/qrImage"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"/>
<TextView <TextView
android:id="@+id/qrIndexSlash" android:id="@+id/qrIndexSlash"
@@ -69,7 +74,8 @@
android:text="/" android:text="/"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/qrImage" /> app:layout_constraintTop_toBottomOf="@+id/qrImage"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" />
<TextView <TextView
android:id="@+id/qrIndexD" android:id="@+id/qrIndexD"
@@ -77,6 +83,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="0" android:text="0"
app:layout_constraintStart_toEndOf="@+id/qrIndexSlash" app:layout_constraintStart_toEndOf="@+id/qrIndexSlash"
app:layout_constraintTop_toBottomOf="@+id/qrImage" /> app:layout_constraintTop_toBottomOf="@+id/qrImage"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>