FINALLY get bluetooth to kind of work

This commit is contained in:
astatin3
2024-07-23 22:38:37 -06:00
parent fe92d4e27b
commit d063319c84
20 changed files with 1184 additions and 79 deletions
@@ -1,5 +1,6 @@
package com.astatin3.scoutingapp2025;
import android.app.AlertDialog;
import android.os.Bundle;
import com.astatin3.scoutingapp2025.scoutingData.fields;
@@ -25,6 +26,17 @@ public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
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) {
@@ -45,9 +57,8 @@ public class MainActivity extends AppCompatActivity {
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// try()
navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_scouting, R.id.navigation_transfer, R.id.navigation_settings)
.build();
@@ -1,5 +1,7 @@
package com.astatin3.scoutingapp2025.SettingsVersionStack;
import java.util.UUID;
public class sv1 extends sv0 {
@Override
public int getVersion() {
@@ -27,6 +29,7 @@ public class sv1 extends sv0 {
writeTag("match_num", "0");
writeTag("alliance_pos", "red-1");
writeTag("compiled_mode", "false");
writeTag("bt_uuid", UUID.randomUUID().toString());
}
public int get_match_num(){
@@ -70,4 +73,12 @@ public class sv1 extends sv0 {
public void set_compiled_mode(boolean state){
writeTag("compiled_mode", state ? "true" : "false");
}
public void setUUID(UUID uuid){
writeTag("bt_uuid", uuid.toString());
}
public UUID getUUID(){
return UUID.fromString(readTag("bt_uuid"));
}
}
@@ -1,5 +1,62 @@
package com.astatin3.scoutingapp2025.types;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.ByteBuilder;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import java.util.ArrayList;
import java.util.Objects;
public class file {
public static final int typecode = 255;
public String filename;
public byte[] data;
public file(){}
public file(String filename){
this(filename, fileEditor.readFile(filename));
}
public file(String filename, byte[] data){
this.filename = filename;
this.data = data;
}
public byte[] encode(){
try {
ByteBuilder bb = new ByteBuilder()
.addString(filename)
.addRaw(255, Objects.requireNonNull(fileEditor.readFile(filename)));
return bb.build();
} catch (ByteBuilder.buildingException e) {
e.printStackTrace();
return null;
}
}
public static file decode(byte[] bytes){
try{
ArrayList<BuiltByteParser.parsedObject> objects = new BuiltByteParser(bytes).parse();
file f = new file();
f.filename = (String) objects.get(0).get();
f.data = (byte[]) objects.get(1).get();
return f;
}catch (BuiltByteParser.byteParsingExeption e){
e.printStackTrace();
return null;
}
}
public boolean write(){
if(data == null || filename == null) return false;
return fileEditor.writeFile(filename, data);
}
}
@@ -58,15 +58,8 @@ public class fieldsView extends ConstraintLayout {
filename = fields.pitsFieldsFilename;
load_field_menu();
});
}
private TextView createTextView(String text) {
TextView textView = new TextView(getContext());
textView.setText(text);
textView.setPadding(10, 10, 10, 10);
return textView;
}
private void load_field_menu() {
values = fields.load(filename);
binding.fieldsArea.bringToFront();
@@ -74,24 +67,6 @@ public class fieldsView extends ConstraintLayout {
binding.fieldsArea.setReorderingEnabled(false);
if(values == null) return;
// List<TableRow> rows = new ArrayList<>();
//
//// Create and add rows
// TableRow row1 = new TableRow(getContext());
// row1.addView(createTextView("Cell 1,1"));
// row1.addView(createTextView("Cell 1,2"));
// rows.add(row1);
//
// TableRow row2 = new TableRow(getContext());
// row2.addView(createTextView("Cell 2,1"));
// row2.addView(createTextView("Cell 2,2"));
// rows.add(row2);
//
//// Set the rows
// binding.fieldsArea.setRows(rows);
//
//// Or add rows individually
for(int i = 0; i < values.length; i++){
TableRow tr = new TableRow(getContext());
@@ -103,7 +78,6 @@ public class fieldsView extends ConstraintLayout {
rowParams.setMargins(20,20,20,20);
tr.setLayoutParams(rowParams);
tr.setPadding(20,20,20,20);
// tr.setMinimumWidth();
tr.setBackgroundColor(background_color);
TextView tv = new TextView(getContext());
@@ -118,10 +92,8 @@ public class fieldsView extends ConstraintLayout {
binding.fieldsArea.addView(tr);
// frcTeam finalTeam = team;
int fi = i;
tr.setOnClickListener(v -> {
// loadTeam(finalTeam, latestSettings.settings.get_compiled_mode());
display_fields(values[fi]);
});
}
@@ -131,7 +103,10 @@ public class fieldsView extends ConstraintLayout {
binding.fieldsArea.removeAllViews();
binding.fieldsArea.setReorderingEnabled(true);
// ArrayList<TableRow> rows = new ArrayList<>();
TextView e = null;
binding.addButton.setOnClickListener(view -> {
e.setText("123");
});
for(int i = 0; i < version_values.length; i++){
TableRow tr = new TableRow(getContext());
@@ -154,17 +129,12 @@ public class fieldsView extends ConstraintLayout {
tv.setText(version_values[i].name);
tv.setTextSize(20);
tr.addView(tv);
// rows.add(tr);
// tr.addView(tv);
binding.fieldsArea.addView(tr);
tr.setOnClickListener(v -> {
trHighlight(tr);
});
}
// binding.fieldsArea.setSlidingEnabled(true);
// binding.fieldsArea.setRows(rows);
}
private void trHighlight(TableRow self){
@@ -39,6 +39,8 @@ public class teamsView extends ConstraintLayout {
com.astatin3.scoutingapp2025.databinding.FragmentDataBinding binding;
private static final int background_color = 0x5000ff00;
private static final int unsaved_background_color = 0x2000ff00;
String evcode;
frcEvent event;
File diff suppressed because one or more lines are too long
@@ -0,0 +1,157 @@
package com.astatin3.scoutingapp2025.ui.transfer.bluetooth;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class BluetoothReceiver {
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final String NAME = "BluetoothReceiverApp";
private static final int REQUEST_ENABLE_BT = 1;
private static final int REQUEST_PERMISSIONS = 2;
private Context context;
private BluetoothAdapter bluetoothAdapter;
private BluetoothServerSocket serverSocket;
private BluetoothSocket socket;
private InputStream inputStream;
private boolean listening = false;
private receivedData receiveddata;
public BluetoothReceiver(Context context, receivedData receiveddata) {
this.context = context;
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
this.receiveddata = receiveddata;
}
public boolean isBluetoothSupported() {
return bluetoothAdapter != null;
}
public boolean isBluetoothEnabled() {
return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
}
private static final int REQUEST_BLUETOOTH_PERMISSIONS = 1;
public static void requestBluetoothPermissions(Activity activity) {
List<String> permissionsNeeded = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// For Android 12 and above
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_SCAN);
}
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_CONNECT);
}
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_ADVERTISE) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_ADVERTISE);
}
} else {
// For Android 11 and below
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH);
}
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_ADMIN);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
}
}
if (!permissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(activity, permissionsNeeded.toArray(new String[0]), REQUEST_BLUETOOTH_PERMISSIONS);
}
}
public static boolean hasBluetoothPermissions(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADVERTISE) == PackageManager.PERMISSION_GRANTED;
} else {
boolean hasBasicPermissions = ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return hasBasicPermissions && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
} else {
return hasBasicPermissions;
}
}
}
public void startListening() throws IOException {
if(!hasBluetoothPermissions(context)){
requestBluetoothPermissions((Activity) context);
return;
}
serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
listening = true;
new Thread(new Runnable() {
@Override
public void run() {
while (listening) {
try {
socket = serverSocket.accept();
inputStream = socket.getInputStream();
// Handle incoming data here
handleIncomingData();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
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));
}
}
}
public interface receivedData {
public void processReceivedData(byte[] data, int bytes);
}
public void stopListening() throws IOException {
listening = false;
if (serverSocket != null) {
serverSocket.close();
}
if (socket != null) {
socket.close();
}
if (inputStream != null) {
inputStream.close();
}
}
}
@@ -0,0 +1,108 @@
package com.astatin3.scoutingapp2025.ui.transfer.bluetooth;
import android.content.Context;
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.R;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class BluetoothReceiverView extends LinearLayout {
private BluetoothReceiver bluetoothReceiver;
private Button startListeningButton;
private Button stopListeningButton;
private TextView statusTextView;
public BluetoothReceiverView(Context context) {
super(context);
init(context);
}
public BluetoothReceiverView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.view_bluetooth_receiver, this, true);
// bluetoothReceiver = new BluetoothReceiver(context);
bluetoothReceiver = new BluetoothReceiver(context, new BluetoothReceiver.receivedData() {
@Override
public void processReceivedData(byte[] data, int bytes) {
receiveFile(data,bytes);
}
});
startListeningButton = findViewById(R.id.startListeningButton);
stopListeningButton = findViewById(R.id.stopListeningButton);
statusTextView = findViewById(R.id.statusTextView);
if (!bluetoothReceiver.isBluetoothSupported()) {
Toast.makeText(context, "Bluetooth is not supported on this device", Toast.LENGTH_SHORT).show();
return;
}
if (!bluetoothReceiver.isBluetoothEnabled()) {
Toast.makeText(context, "Please enable Bluetooth", Toast.LENGTH_SHORT).show();
}
startListeningButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startListening();
}
});
stopListeningButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
stopListening();
}
});
}
private void startListening() {
try {
bluetoothReceiver.startListening();
statusTextView.setText("Listening for incoming connections...");
startListeningButton.setEnabled(false);
stopListeningButton.setEnabled(true);
} catch (IOException e) {
Toast.makeText(getContext(), "Failed to start listening: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void stopListening() {
try {
bluetoothReceiver.stopListening();
statusTextView.setText("Not listening");
startListeningButton.setEnabled(true);
stopListeningButton.setEnabled(false);
} catch (IOException e) {
Toast.makeText(getContext(), "Failed to stop listening: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void receiveFile(byte[] data, int bytes) {
System.out.println(Arrays.toString(data) + ", " + bytes);
}
public void onDestroy() {
try {
bluetoothReceiver.stopListening();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,129 @@
package com.astatin3.scoutingapp2025.ui.transfer.bluetooth;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class BluetoothSender {
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final int REQUEST_ENABLE_BT = 1;
private static final int REQUEST_PERMISSIONS = 2;
private Context context;
private BluetoothAdapter bluetoothAdapter;
private BluetoothSocket socket;
private OutputStream outputStream;
public BluetoothSender(Context context) {
this.context = context;
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
public boolean isBluetoothSupported() {
return bluetoothAdapter != null;
}
public boolean isBluetoothEnabled() {
return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
}
private static final int REQUEST_BLUETOOTH_PERMISSIONS = 1;
public static void requestBluetoothPermissions(Activity activity) {
List<String> permissionsNeeded = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// For Android 12 and above
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_SCAN);
}
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_CONNECT);
}
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_ADVERTISE) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_ADVERTISE);
}
} else {
// For Android 11 and below
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH);
}
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_ADMIN);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
}
}
if (!permissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(activity, permissionsNeeded.toArray(new String[0]), REQUEST_BLUETOOTH_PERMISSIONS);
}
}
public static boolean hasBluetoothPermissions(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADVERTISE) == PackageManager.PERMISSION_GRANTED;
} else {
boolean hasBasicPermissions = ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return hasBasicPermissions && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
} else {
return hasBasicPermissions;
}
}
}
public Set<BluetoothDevice> getPairedDevices() {
if(!hasBluetoothPermissions(context)){
requestBluetoothPermissions((Activity) context);
return null;
}
return bluetoothAdapter.getBondedDevices();
}
public void connectToDevice(BluetoothDevice device) throws IOException {
if(!hasBluetoothPermissions(context)){
requestBluetoothPermissions((Activity) context);
return;
}
socket = device.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
outputStream = socket.getOutputStream();
}
public void sendData(byte[] data) throws IOException {
if (outputStream != null) {
outputStream.write(data);
}
}
public void close() throws IOException {
if (outputStream != null) {
outputStream.close();
}
if (socket != null) {
socket.close();
}
}
}
@@ -0,0 +1,126 @@
package com.astatin3.scoutingapp2025.ui.transfer.bluetooth;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
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.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 {
private BluetoothSender bluetoothSender;
private ListView deviceListView;
private Button sendFileButton;
private ArrayAdapter<String> deviceArrayAdapter;
private ArrayList<BluetoothDevice> deviceList;
private byte[] data_to_send = new byte[0];
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);
bluetoothSender = new BluetoothSender(context);
deviceListView = findViewById(R.id.deviceListView);
sendFileButton = findViewById(R.id.sendFileButton);
deviceList = new ArrayList<>();
deviceArrayAdapter = new ArrayAdapter<>(context, 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();
return;
}
if (!bluetoothSender.isBluetoothEnabled()) {
Toast.makeText(context, "Please enable Bluetooth", Toast.LENGTH_SHORT).show();
} else {
listPairedDevices();
}
deviceListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
BluetoothDevice selectedDevice = deviceList.get(position);
try {
bluetoothSender.connectToDevice(selectedDevice);
Toast.makeText(context, "Connected to " + selectedDevice.getName(), Toast.LENGTH_SHORT).show();
sendFileButton.setEnabled(true);
} catch (IOException e) {
Toast.makeText(context, "Failed to connect: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
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();
}
});
}
private void listPairedDevices() {
Set<BluetoothDevice> pairedDevices = bluetoothSender.getPairedDevices();
if (pairedDevices != null && !pairedDevices.isEmpty()) {
deviceList.addAll(pairedDevices);
for (BluetoothDevice device : pairedDevices) {
deviceArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
Toast.makeText(getContext(), "No paired devices found", Toast.LENGTH_SHORT).show();
}
}
private void sendDummyFile() {
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));
}
Toast.makeText(getContext(), "File sent successfully", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getContext(), "Failed to send file: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
public void onDestroy() {
try {
bluetoothSender.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@@ -1,4 +1,4 @@
package com.astatin3.scoutingapp2025.ui.transfer;
package com.astatin3.scoutingapp2025.ui.transfer.codes;
import android.graphics.Bitmap;
import android.os.AsyncTask;
@@ -12,12 +12,8 @@ import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Reader;
import com.google.zxing.Result;
import com.google.zxing.aztec.AztecReader;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.datamatrix.DataMatrixReader;
import com.google.zxing.maxicode.MaxiCodeReader;
import com.google.zxing.pdf417.PDF417Reader;
import com.google.zxing.qrcode.QRCodeReader;
import java.util.EnumSet;
import java.util.HashMap;
@@ -1,4 +1,4 @@
package com.astatin3.scoutingapp2025.ui.transfer;
package com.astatin3.scoutingapp2025.ui.transfer.codes;
import android.app.AlertDialog;
import android.content.Context;
@@ -1,4 +1,4 @@
package com.astatin3.scoutingapp2025.ui.transfer;
package com.astatin3.scoutingapp2025.ui.transfer.codes;
// From https://github.com/dlazaro66/QRCodeReaderView/blob/master/samples/src/main/java/com/example/qr_readerexample/PointsOverlayView.java
@@ -1,4 +1,4 @@
package com.astatin3.scoutingapp2025.ui.transfer;
package com.astatin3.scoutingapp2025.ui.transfer.codes;
import static androidx.core.math.MathUtils.clamp;
@@ -26,11 +26,15 @@ import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;
import com.astatin3.scoutingapp2025.databinding.FragmentTransferBinding;
import com.astatin3.scoutingapp2025.types.file;
import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
import com.astatin3.scoutingapp2025.utility.fileEditor;
import com.google.common.util.concurrent.ListenableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -301,7 +305,24 @@ public class scannerView extends ConstraintLayout {
try {
byte[] compiledBytes = compiledString.getBytes(StandardCharsets.ISO_8859_1);
alert("completed", blockUncompress(compiledBytes));
byte[] resultBytes = blockUncompress(compiledBytes);
String result_filenames = "";
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)
if(f.write())
result_filenames += f.filename + "\n";
}
alert("Completed!", result_filenames);
}catch (Exception e){
e.printStackTrace();
}
@@ -309,20 +330,21 @@ public class scannerView extends ConstraintLayout {
prevQrIndex = qrIndex;
}
private static String blockUncompress(byte[] data) throws DataFormatException {
String uncompressedData = "";
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 += new String(
uncompressedData.add(
fileEditor.decompress(
fileEditor.getByteBlock(data, curIndex+2, curIndex+blockLength+2)
), StandardCharsets.ISO_8859_1);
)
);
curIndex += blockLength+2;
}
return uncompressedData;
return fileEditor.combineByteArrays(uncompressedData);
}
}
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
@@ -127,6 +128,33 @@ public final class fileEditor {
return outputStream.toByteArray();
}
public static byte[] combineByteArrays(List<byte[]> arrayList) {
// Calculate the total length of the combined array
int totalLength = arrayList.stream()
.mapToInt(array -> array.length)
.sum();
// Create a new byte array with the total length
byte[] result = new byte[totalLength];
// Copy each array into the result array
int offset = 0;
for (byte[] array : arrayList) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
public static boolean writeFile(String filepath, byte[] data) {
try {
FileOutputStream output = new FileOutputStream(baseDir + filepath);
@@ -251,6 +279,48 @@ public final class fileEditor {
public static String[] getEventFiles(String evcode){
File f = new File(baseDir);
File[] files = f.listFiles();
if(files == null){return new String[0];}
ArrayList<String> outFiles = new ArrayList<>();
outFiles.add("matches.fields");
outFiles.add("pits.fields");
// outFiles.add(evcode + ".eventdata");
for (File file : files) {
String name = file.getName();
if(!file.isDirectory() && name.startsWith(evcode)) {
outFiles.add(file.getName());
}
}
String[] filenames = outFiles.toArray(new String[0]);
Arrays.sort(filenames, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
try {
if(!o1.contains("-") || !o2.contains("-"))
return 0;
return Integer.valueOf(o1.split("-")[1]).compareTo(Integer.valueOf(o2.split("-")[1]));
} catch (Exception e){
return 0;
}
}
});
return filenames;
}
public static boolean setTeams(Context context, String key, ArrayList<frcTeam> teams){
return true;
}