Make bluetooth work, Make alert() better, and more formal errors

This commit is contained in:
astatin3
2024-07-24 15:27:13 -06:00
parent d063319c84
commit 588a71763a
24 changed files with 342 additions and 195 deletions
+28 -14
View File
@@ -1,22 +1,36 @@
# ScoutingApp2025
Ridgebotics 2025 scouting app in Android
TODO:
- Add an "unselect" option to all of the scouting fields
- Make a word cloud for the compiled mode of notes input type
- Make pit and match data field builder UIs. I don't want to have to keep editing a variable
- Add "history" view type to the teams view menu.
- Add CSV exporting
## TODO:
#### Scouting:
- Make the "Compile" menu
- The compile menu should be a shortcut to view all the team's stats from the upcoming match, from the teams view
- Make the file browser UI
- Fix the code scanning progress indicator
- Add more types of data fields.
- Make server software to allow for easy sync over wifi
- Make practice mode
- AI overview of scouting data for a team???
- Bluetooth data sync
#### Data Analysis:
- Add CSV exporting
- Statbotics intigration
- AI overview of scouting data for a team???
#### Functionality:
- Improve the code scanning progress indicator. It has a rounding error, I think.
- Add more types of data fields.
- Make server software to allow for easy sync over wifi
- Test the scouting app
## In Progress:
#### Scouting:
#### Data Analysis:
- Add "history" view type to the teams view menu.
- Sentiment analysis of text input type
- Make a word cloud for the compiled mode of text input type
#### Functionality:
- Make pit and match data field builder UIs. I don't want to have to keep editing a variable
## Done:
#### Scouting:
- Add an "unselect" option to all of the scouting fields
#### Data Analysis:
#### Functionality:
- Make the file browser UI
- Bluetooth data sync
- Formalize error messages & stacktraces
@@ -1,9 +1,11 @@
package com.astatin3.scoutingapp2025;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import com.astatin3.scoutingapp2025.scoutingData.fields;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import com.google.android.material.bottomnavigation.BottomNavigationView;
@@ -27,16 +29,6 @@ public class MainActivity extends AppCompatActivity {
private BottomNavigationView navView;
private void alert(String title, String content) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setMessage(content);
alert.setTitle(title);
alert.setPositiveButton("OK", null);
alert.setCancelable(true);
alert.create().show();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -50,6 +42,8 @@ public class MainActivity extends AppCompatActivity {
fields.save(fields.pitsFieldsFilename, fields.default_pit_fields);
}
AlertManager.init(this);
Objects.requireNonNull(getSupportActionBar()).hide();
super.onCreate(savedInstanceState);
@@ -1,5 +1,6 @@
package com.astatin3.scoutingapp2025.SettingsVersionStack;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import java.nio.charset.StandardCharsets;
@@ -54,7 +55,7 @@ public abstract class settingsVersion {
}
}
}catch (Exception e){
e.printStackTrace();
AlertManager.error(e);
}
return null;
@@ -6,6 +6,7 @@ import com.astatin3.scoutingapp2025.types.data.dataType;
import com.astatin3.scoutingapp2025.types.data.stringType;
import com.astatin3.scoutingapp2025.types.input.inputType;
import com.astatin3.scoutingapp2025.types.data.intType;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.ByteBuilder;
@@ -35,7 +36,7 @@ public class ScoutingDataWriter {
fileEditor.writeFile(filename, bytes);
return true;
} catch (ByteBuilder.buildingException e) {
e.printStackTrace();
AlertManager.error(e);
return false;
}
}
@@ -84,7 +85,7 @@ public class ScoutingDataWriter {
return psda;
} catch (BuiltByteParser.byteParsingExeption e){
e.printStackTrace();
AlertManager.error(e);
return null;
}
}
@@ -5,6 +5,7 @@ import com.astatin3.scoutingapp2025.types.input.inputType;
import com.astatin3.scoutingapp2025.types.input.textType;
import com.astatin3.scoutingapp2025.types.input.sliderType;
import com.astatin3.scoutingapp2025.types.input.textType;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.ByteBuilder;
@@ -54,7 +55,7 @@ public class fields {
fileEditor.writeFile(filename, bb.build());
return true;
}catch (ByteBuilder.buildingException e) {
e.printStackTrace();
AlertManager.error(e);
return false;
// throw new RuntimeException(e);
}
@@ -86,7 +87,7 @@ public class fields {
return values;
// return true;
} catch (Exception e) {
e.printStackTrace();
AlertManager.error(e);
return null;
// return false;
}
@@ -1,5 +1,6 @@
package com.astatin3.scoutingapp2025.types;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.ByteBuilder;
import com.astatin3.scoutingapp2025.utility.fileEditor;
@@ -33,7 +34,7 @@ public class file {
return bb.build();
} catch (ByteBuilder.buildingException e) {
e.printStackTrace();
AlertManager.error(e);
return null;
}
}
@@ -50,7 +51,7 @@ public class file {
return f;
}catch (BuiltByteParser.byteParsingExeption e){
e.printStackTrace();
AlertManager.error(e);
return null;
}
}
@@ -2,6 +2,7 @@ package com.astatin3.scoutingapp2025.types;
import androidx.annotation.NonNull;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.ByteBuilder;
@@ -31,7 +32,7 @@ public class frcEvent {
return bb.build();
} catch (ByteBuilder.buildingException e) {
e.printStackTrace();
AlertManager.error(e);
return null;
}
}
@@ -58,7 +59,7 @@ public class frcEvent {
return frc;
}catch (BuiltByteParser.byteParsingExeption e){
e.printStackTrace();
AlertManager.error(e);
return null;
}
}
@@ -2,6 +2,7 @@ package com.astatin3.scoutingapp2025.types;
import androidx.annotation.NonNull;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.ByteBuilder;
@@ -27,7 +28,7 @@ public class frcMatch {
.addInt(redAlliance[2])
.build();
} catch (ByteBuilder.buildingException e) {
e.printStackTrace();
AlertManager.error(e);
return new byte[1];
}
}
@@ -49,7 +50,7 @@ public class frcMatch {
return frc;
} catch (BuiltByteParser.byteParsingExeption e) {
e.printStackTrace();
AlertManager.error(e);
return null;
}
}
@@ -2,6 +2,7 @@ package com.astatin3.scoutingapp2025.types;
import androidx.annotation.NonNull;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.ByteBuilder;
@@ -33,7 +34,7 @@ public class frcTeam {
.addInt(startingYear)
.build();
} catch (ByteBuilder.buildingException e) {
e.printStackTrace();
AlertManager.error(e);
return null;
}
}
@@ -54,7 +55,7 @@ public class frcTeam {
return frc;
} catch (BuiltByteParser.byteParsingExeption e) {
e.printStackTrace();
AlertManager.error(e);
return null;
}
}
@@ -36,15 +36,6 @@ public class settingsFragment extends Fragment {
private android.widget.ScrollView ScrollArea;
private android.widget.TableLayout Table;
private void alert(String title, String content) {
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage(content);
alert.setTitle(title);
alert.setPositiveButton("OK", null);
alert.setCancelable(true);
alert.create().show();
}
private void setDropdownItems(Spinner dropdown, String[] items){
ArrayAdapter<String> adapter = new ArrayAdapter<>(requireActivity(), android.R.layout.simple_spinner_item, items);
dropdown.setAdapter(adapter);
@@ -12,6 +12,7 @@ import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.RequestTask;
import com.astatin3.scoutingapp2025.types.frcEvent;
import com.astatin3.scoutingapp2025.types.frcMatch;
@@ -46,16 +47,6 @@ public class TBAView extends ScrollView {
super(context, attributeSet);
}
private void alert(String title, String content) {
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage(content);
alert.setTitle(title);
alert.setPositiveButton("OK", null);
alert.setCancelable(true);
alert.create().show();
}
public void start(FragmentTransferBinding binding, String yearStr) {
Table = binding.matchTable;
@@ -143,7 +134,7 @@ public class TBAView extends ScrollView {
tr.setBackgroundColor(0x30FFFF00);
}
} catch (Exception e) {
e.printStackTrace();
AlertManager.error(e);
}
@@ -179,7 +170,7 @@ public class TBAView extends ScrollView {
toggle = !toggle;
}
}catch (JSONException j){
alert("Error", "Invalid JSON");
AlertManager.alert("Error", "Invalid JSON");
}
}
@@ -352,9 +343,9 @@ public class TBAView extends ScrollView {
btn.setOnClickListener(v -> {
if(saveData(matchesOBJ, teamData, eventData)){
alert("Info", "Saved!");
AlertManager.alert("Info", "Saved!");
}else{
alert("Error", "Error saving files.");
AlertManager.alert("Error", "Error saving files.");
}
});
@@ -465,8 +456,8 @@ public class TBAView extends ScrollView {
// });
}catch (JSONException j){
j.printStackTrace();
alert("Error", "Invalid JSON");
AlertManager.error(j);
AlertManager.alert("Error", "Invalid JSON");
}
}
@@ -505,8 +496,8 @@ public class TBAView extends ScrollView {
return fileEditor.setEvent(event);
}catch (JSONException j){
j.printStackTrace();
alert("Error", "Invalid JSON");
AlertManager.error(j);
AlertManager.alert("Error", "Invalid JSON");
return false;
}
}
@@ -99,8 +99,8 @@ public class TransferFragment extends Fragment {
public void show_ui(){
binding.mainSelectLayout.setVisibility(View.VISIBLE);
binding.noEventError.setVisibility(View.GONE);
binding.loadSelectLayout.setVisibility(View.GONE);
binding.bluetoothSenderView.setVisibility(View.GONE);
binding.bluetoothReceiverView.setVisibility(View.GONE);
@@ -313,6 +313,7 @@ public class TransferFragment extends Fragment {
private void start_upload_bluetooth(byte[] data){
binding.loadSelectLayout.setVisibility(View.GONE);
binding.bluetoothSenderView.setVisibility(View.VISIBLE);
binding.bluetoothSenderView.init();
binding.bluetoothSenderView.set_data(data);
@@ -321,6 +322,7 @@ public class TransferFragment extends Fragment {
private void start_download_bluetooth(){
binding.loadSelectLayout.setVisibility(View.GONE);
binding.bluetoothReceiverView.setVisibility(View.VISIBLE);
binding.bluetoothReceiverView.init();
}
@@ -11,6 +11,8 @@ import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -48,7 +50,8 @@ public class BluetoothReceiver {
private static final int REQUEST_BLUETOOTH_PERMISSIONS = 1;
public static void requestBluetoothPermissions(Activity activity) {
public static void
requestBluetoothPermissions(Activity activity) {
List<String> permissionsNeeded = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@@ -116,28 +119,36 @@ public class BluetoothReceiver {
// Handle incoming data here
handleIncomingData();
} catch (IOException e) {
e.printStackTrace();
AlertManager.error(e);
}
}
}
}).start();
}
private void handleIncomingData() throws IOException {
private void handleIncomingData() throws IOException {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
bytes = inputStream.read(buffer);
if (bytes != -1) {
// Process received data here
// receiveddata.processReceivedData(buffer, bytes);
System.out.println(Arrays.toString(buffer));
try {
while (true) {
bytes = inputStream.read(buffer);
if (bytes != -1) {
receiveddata.processReceivedData(buffer, bytes);
}
}
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("bt socket closed, read return: -1")) {
receiveddata.onConnectionStop();
System.out.println("Bluetooth socket closed, treating as end of stream");
} else {
throw e;
}
}
}
public interface receivedData {
public void processReceivedData(byte[] data, int bytes);
public void onConnectionStop();
}
@@ -1,20 +1,28 @@
package com.astatin3.scoutingapp2025.ui.transfer.bluetooth;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Looper;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.astatin3.scoutingapp2025.MainActivity;
import com.astatin3.scoutingapp2025.R;
import com.astatin3.scoutingapp2025.types.file;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.DataFormatException;
public class BluetoothReceiverView extends LinearLayout {
private BluetoothReceiver bluetoothReceiver;
@@ -24,23 +32,39 @@ public class BluetoothReceiverView extends LinearLayout {
public BluetoothReceiverView(Context context) {
super(context);
init(context);
// init(context);
}
public BluetoothReceiverView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
// init(context);
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.view_bluetooth_receiver, this, true);
// private void alert(String title, String content) {
// AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
// dialog.setCancelable(true);
// dialog.setTitle(title);
// dialog.setMessage(content);
//
// final AlertDialog alert = dialog.create();
// alert.show();
//
// }
public void init() {
LayoutInflater.from(getContext()).inflate(R.layout.view_bluetooth_receiver, this, true);
// bluetoothReceiver = new BluetoothReceiver(context);
bluetoothReceiver = new BluetoothReceiver(context, new BluetoothReceiver.receivedData() {
bluetoothReceiver = new BluetoothReceiver(getContext(), new BluetoothReceiver.receivedData() {
@Override
public void processReceivedData(byte[] data, int bytes) {
receiveFile(data,bytes);
receiveData(data, bytes);
}
@Override
public void onConnectionStop() {
finished_recieve();
}
});
@@ -49,12 +73,12 @@ public class BluetoothReceiverView extends LinearLayout {
statusTextView = findViewById(R.id.statusTextView);
if (!bluetoothReceiver.isBluetoothSupported()) {
Toast.makeText(context, "Bluetooth is not supported on this device", Toast.LENGTH_SHORT).show();
AlertManager.error("Bluetooth is not supported on this device");
return;
}
if (!bluetoothReceiver.isBluetoothEnabled()) {
Toast.makeText(context, "Please enable Bluetooth", Toast.LENGTH_SHORT).show();
AlertManager.error("Please enable Bluetooth");
}
startListeningButton.setOnClickListener(new OnClickListener() {
@@ -78,8 +102,11 @@ public class BluetoothReceiverView extends LinearLayout {
statusTextView.setText("Listening for incoming connections...");
startListeningButton.setEnabled(false);
stopListeningButton.setEnabled(true);
recievedBytes = new ArrayList<>();
} catch (IOException e) {
Toast.makeText(getContext(), "Failed to start listening: " + e.getMessage(), Toast.LENGTH_SHORT).show();
AlertManager.error("Failed to start listening: " + e.getMessage());
}
}
@@ -90,19 +117,57 @@ public class BluetoothReceiverView extends LinearLayout {
startListeningButton.setEnabled(true);
stopListeningButton.setEnabled(false);
} catch (IOException e) {
Toast.makeText(getContext(), "Failed to stop listening: " + e.getMessage(), Toast.LENGTH_SHORT).show();
AlertManager.error("Failed to stop listening: " + e.getMessage());
}
}
private void receiveFile(byte[] data, int bytes) {
System.out.println(Arrays.toString(data) + ", " + bytes);
private List<byte[]> recievedBytes;
private void receiveData(byte[] data, int bytes) {
byte[] newBytes = fileEditor.getByteBlock(data, 0, bytes);
System.out.println("Recieved " + bytes + " Bytes over bluetooth!");
recievedBytes.add(newBytes);
}
private void finished_recieve() {
String result_filenames = "";
try {
byte[] resultBytes = fileEditor.combineByteArrays(recievedBytes);
resultBytes = fileEditor.blockUncompress(resultBytes);
BuiltByteParser bbp = new BuiltByteParser(resultBytes);
ArrayList<BuiltByteParser.parsedObject> result = bbp.parse();
for (int i = 0; i < result.size(); i++) {
if (result.get(i).getType() != file.typecode) continue;
file f = file.decode((byte[]) result.get(i).get());
if (f != null) {
System.out.println(f.filename);
if (f.write())
result_filenames += f.filename + "\n";
}
}
} catch (DataFormatException e) {
AlertManager.error(e);
} catch (BuiltByteParser.byteParsingExeption e) {
AlertManager.error(e);
}
AlertManager.alert("Completed!", result_filenames);
}
public void onDestroy() {
try {
bluetoothReceiver.stopListening();
} catch (IOException e) {
e.printStackTrace();
}
if (bluetoothReceiver != null)
try {
bluetoothReceiver.stopListening();
} catch (IOException e) {
AlertManager.error(e);
}
}
}
@@ -11,6 +11,8 @@ import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
@@ -26,7 +28,7 @@ public class BluetoothSender {
private Context context;
private BluetoothAdapter bluetoothAdapter;
private BluetoothSocket socket;
private OutputStream outputStream;
public OutputStream outputStream;
public BluetoothSender(Context context) {
this.context = context;
@@ -120,8 +122,14 @@ public class BluetoothSender {
public void close() throws IOException {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
AlertManager.error(e);
}
if (socket != null) {
socket.close();
}
@@ -10,16 +10,13 @@ import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import com.astatin3.scoutingapp2025.R;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
public class BluetoothSenderView extends LinearLayout {
@@ -32,36 +29,34 @@ public class BluetoothSenderView extends LinearLayout {
public BluetoothSenderView(Context context) {
super(context);
init(context);
}
public BluetoothSenderView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public void set_data(byte[] data){
data_to_send = data;
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.view_bluetooth_sender, this, true);
public void init() {
LayoutInflater.from(getContext()).inflate(R.layout.view_bluetooth_sender, this, true);
bluetoothSender = new BluetoothSender(context);
bluetoothSender = new BluetoothSender(getContext());
deviceListView = findViewById(R.id.deviceListView);
sendFileButton = findViewById(R.id.sendFileButton);
deviceList = new ArrayList<>();
deviceArrayAdapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1);
deviceArrayAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1);
deviceListView.setAdapter(deviceArrayAdapter);
if (!bluetoothSender.isBluetoothSupported()) {
Toast.makeText(context, "Bluetooth is not supported on this device", Toast.LENGTH_SHORT).show();
AlertManager.toast("Bluetooth is not supported on this device");
return;
}
if (!bluetoothSender.isBluetoothEnabled()) {
Toast.makeText(context, "Please enable Bluetooth", Toast.LENGTH_SHORT).show();
AlertManager.toast("Please enable Bluetooth");
} else {
listPairedDevices();
}
@@ -72,10 +67,10 @@ public class BluetoothSenderView extends LinearLayout {
BluetoothDevice selectedDevice = deviceList.get(position);
try {
bluetoothSender.connectToDevice(selectedDevice);
Toast.makeText(context, "Connected to " + selectedDevice.getName(), Toast.LENGTH_SHORT).show();
AlertManager.toast("Connected to " + selectedDevice.getName());
sendFileButton.setEnabled(true);
} catch (IOException e) {
Toast.makeText(context, "Failed to connect: " + e.getMessage(), Toast.LENGTH_SHORT).show();
AlertManager.toast("Failed to connect: " + e.getMessage());
}
}
});
@@ -83,9 +78,7 @@ public class BluetoothSenderView extends LinearLayout {
sendFileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// You would typically launch a file picker here
// For this example, we'll just send a dummy file
sendDummyFile();
sendData();
}
});
}
@@ -98,29 +91,35 @@ public class BluetoothSenderView extends LinearLayout {
deviceArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
Toast.makeText(getContext(), "No paired devices found", Toast.LENGTH_SHORT).show();
AlertManager.toast("No paired devices found");
}
}
private void sendDummyFile() {
private void sendData() {
try {
for(int i = 0; i < Math.floor((double) data_to_send.length /1024); i++){
bluetoothSender.sendData(fileEditor.getByteBlock(data_to_send, (i*1024), (i+1)*1024));
// System.out.println(Arrays.toString(buffer));
byte[] compressed = fileEditor.blockCompress(data_to_send);
for(int i = 0; i < Math.ceil((double) compressed.length/1024); i++){
bluetoothSender.sendData(fileEditor.getByteBlock(compressed, i*1024, (i+1)*1024));
}
bluetoothSender.close();
sendFileButton.setEnabled(false);
Toast.makeText(getContext(), "File sent successfully", Toast.LENGTH_SHORT).show();
AlertManager.toast("File sent successfully");
} catch (IOException e) {
Toast.makeText(getContext(), "Failed to send file: " + e.getMessage(), Toast.LENGTH_SHORT).show();
AlertManager.toast("Failed to send file: " + e.getMessage());
}
}
public void onDestroy() {
try {
bluetoothSender.close();
} catch (IOException e) {
e.printStackTrace();
}
if(bluetoothSender != null)
try {
bluetoothSender.close();
} catch (IOException e) {
AlertManager.error(e);
}
}
}
@@ -3,6 +3,7 @@ package com.astatin3.scoutingapp2025.ui.transfer.codes;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
@@ -46,7 +47,7 @@ public class codeScanTask extends AsyncTask<String, String, String>{
Result result = reader.decode(binaryBitmap, hints);
return result.getText();
} catch (NotFoundException | ChecksumException | FormatException e) {
e.printStackTrace();
// AlertManager.error(e);
}
return null;
@@ -13,6 +13,7 @@ import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.astatin3.scoutingapp2025.databinding.FragmentTransferBinding;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
@@ -60,16 +61,6 @@ public class generatorView extends ConstraintLayout {
super(context, attributeSet);
}
private void alert(String title, String content) {
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage(content);
alert.setTitle(title);
alert.setPositiveButton("OK", null);
alert.setCancelable(true);
alert.create().show();
}
private Bitmap generateQrCode(String contents) throws WriterException {
final int size = 512;
@@ -91,7 +82,7 @@ public class generatorView extends ConstraintLayout {
result = writer.encode(contents, BarcodeFormat.DATA_MATRIX, size, size, hints);
} catch (IllegalArgumentException e) {
// Unsupported format
e.printStackTrace();
AlertManager.error(e);
return null;
}
@@ -122,39 +113,14 @@ public class generatorView extends ConstraintLayout {
qrIndexN = binding.qrIndexN;
qrIndexD = binding.qrIndexD;
String compressed = new String(fileEditor.blockCompress(inputData), StandardCharsets.ISO_8859_1);
String compiledData = "";
for(int i=0;i<Math.ceil((double) inputData.length / fileEditor.maxCompressedBlockSize);i++){
final int start = i*fileEditor.maxCompressedBlockSize;
int end = ((i+1)*fileEditor.maxCompressedBlockSize);
if(end > inputData.length) {
end = inputData.length;
}
byte[] dataBlock = fileEditor.getByteBlock(inputData, start, end);
final String compressedBlock =
new String(
fileEditor.compress(dataBlock),
StandardCharsets.ISO_8859_1);
compiledData +=
new String(
fileEditor.toBytes(compressedBlock.length(), 2),
StandardCharsets.ISO_8859_1) +
compressedBlock;
}
if(compiledData.isEmpty()){
alert("Error!", "Empty data!");
if(compressed.isEmpty()){
AlertManager.alert("Error!", "Empty data!");
return;
}
minQrSize = Math.round(compiledData.length()/maxQrCount)+1;
minQrSize = Math.round((float)compressed.length() / maxQrCount)+1;
qrSizeSlider.setMax(maxQrSize-minQrSize);
qrSpeedSlider.setMax((minQrSpeed-maxQrSpeed)*2);
@@ -162,7 +128,7 @@ public class generatorView extends ConstraintLayout {
qrSizeSlider.setProgress(minQrSize+qrSize);
qrSpeedSlider.setProgress(defaultQrDelay+5);
sendData(compiledData);
sendData(compressed);
}
private void sendData(String data){
@@ -223,7 +189,7 @@ public class generatorView extends ConstraintLayout {
));
// alert("title", ""+(qrCount-1));
}catch (WriterException e){
e.printStackTrace();
AlertManager.error(e);
}
}
qrIndex = 0;
@@ -27,6 +27,7 @@ import androidx.lifecycle.LifecycleOwner;
import com.astatin3.scoutingapp2025.databinding.FragmentTransferBinding;
import com.astatin3.scoutingapp2025.types.file;
import com.astatin3.scoutingapp2025.utility.AlertManager;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import com.google.common.util.concurrent.ListenableFuture;
@@ -305,7 +306,8 @@ public class scannerView extends ConstraintLayout {
try {
byte[] compiledBytes = compiledString.getBytes(StandardCharsets.ISO_8859_1);
byte[] resultBytes = blockUncompress(compiledBytes);
byte[] resultBytes = fileEditor.blockUncompress(compiledBytes);
String result_filenames = "";
@@ -321,30 +323,14 @@ public class scannerView extends ConstraintLayout {
result_filenames += f.filename + "\n";
}
alert("Completed!", result_filenames);
AlertManager.alert("Completed!", result_filenames);
}catch (Exception e){
e.printStackTrace();
AlertManager.error(e);
}
}
prevQrIndex = qrIndex;
}
private static byte[] blockUncompress(byte[] data) throws DataFormatException {
List<byte[]> uncompressedData = new ArrayList<>();
int curIndex = 0;
while(curIndex < data.length){
final int blockLength = fileEditor.fromBytes(fileEditor.getByteBlock(data, curIndex, curIndex+2), 2);
uncompressedData.add(
fileEditor.decompress(
fileEditor.getByteBlock(data, curIndex+2, curIndex+blockLength+2)
)
);
curIndex += blockLength+2;
}
return fileEditor.combineByteArrays(uncompressedData);
}
}
@@ -0,0 +1,72 @@
package com.astatin3.scoutingapp2025.utility;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Looper;
import android.widget.Toast;
import java.io.PrintWriter;
import java.io.StringWriter;
public class AlertManager {
private static Context context;
public static void init(Context c){
context = c;
}
public static void alert(String title, String content) {
((Activity) context).runOnUiThread(new Runnable() {
public void run() {
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setMessage(content);
alert.setTitle(title);
alert.setPositiveButton("OK", null);
alert.setCancelable(true);
alert.create().show();
}
});
}
public static void toast(String content) {
((Activity) context).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(context, content, Toast.LENGTH_LONG).show();
}
});
}
public static void error(String content) {
((Activity) context).runOnUiThread(new Runnable() {
public void run() {
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setMessage(content);
alert.setTitle("Error!");
alert.setPositiveButton("OK", null);
alert.setCancelable(true);
alert.create().show();
}
});
}
public static void error(Exception e) {
((Activity) context).runOnUiThread(new Runnable() {
public void run() {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setMessage(sw.toString());
alert.setTitle(e.getMessage());
alert.setPositiveButton("OK", null);
alert.setCancelable(true);
alert.create().show();
}
});
}
}
@@ -37,7 +37,7 @@ public class RequestTask extends AsyncTask<String, String, String> {
return null; // See documentation for more info on response handling
}
} catch (IOException e) {
e.printStackTrace();
AlertManager.error(e);
}
return null;
}
@@ -51,13 +51,13 @@ public class RequestTask extends AsyncTask<String, String, String> {
response.append(line);
}
} catch (IOException e) {
e.printStackTrace();
AlertManager.error(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
AlertManager.error(e);
}
}
}
@@ -82,6 +82,8 @@ public final class fileEditor {
public static byte[] getByteBlock(byte[] bytes, int start, int end){
end = Math.min(end, bytes.length);
byte[] dataBlock = new byte[end-start];
for(int a=start;a<end;a++){
@@ -108,6 +110,44 @@ public final class fileEditor {
return outputStream.toByteArray();
}
public static byte[] blockCompress(byte[] inputData) {
List<byte[]> compiledData = new ArrayList<>();
for(int i=0;i<Math.ceil((double) inputData.length / fileEditor.maxCompressedBlockSize);i++){
final int start = i*fileEditor.maxCompressedBlockSize;
int end = ((i+1)*fileEditor.maxCompressedBlockSize);
if(end > inputData.length) {
end = inputData.length;
}
byte[] dataBlock = fileEditor.getByteBlock(inputData, start, end);
final byte[] compressedBlock = fileEditor.compress(dataBlock);
compiledData.add(fileEditor.toBytes(compressedBlock.length, 2));
compiledData.add(compressedBlock);
}
return combineByteArrays(compiledData);
}
public static byte[] blockUncompress(byte[] data) throws DataFormatException {
List<byte[]> uncompressedData = new ArrayList<>();
int curIndex = 0;
while (curIndex < data.length) {
final int blockLength = fileEditor.fromBytes(fileEditor.getByteBlock(data, curIndex, curIndex + 2), 2);
uncompressedData.add(
decompress(
fileEditor.getByteBlock(data, curIndex + 2, curIndex + blockLength + 2)
)
);
curIndex += blockLength + 2;
}
return combineByteArrays(uncompressedData);
}
public static byte[] decompress(byte[] input) throws DataFormatException {
Inflater inflater = new Inflater();
@@ -163,7 +203,7 @@ public final class fileEditor {
return true;
}
catch (IOException e) {
e.printStackTrace();
AlertManager.error(e);
return false;
}
}
@@ -177,7 +217,7 @@ public final class fileEditor {
return file.createNewFile();
}
catch (IOException e) {
e.printStackTrace();
AlertManager.error(e);
return false;
}
}
@@ -197,10 +237,10 @@ public final class fileEditor {
buf.close();
return bytes;
} catch (FileNotFoundException e) {
e.printStackTrace();
AlertManager.error(e);
return null;
} catch (IOException e) {
e.printStackTrace();
AlertManager.error(e);
return null;
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
[versions]
agp = "8.3.1"
agp = "8.5.0"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
+1 -1
View File
@@ -1,6 +1,6 @@
#Sun Mar 24 10:48:55 MDT 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists