mirror of
https://github.com/Team4388/RidgeScout.git
synced 2026-06-09 00:37:59 -06:00
Make bluetooth work, Make alert() better, and more formal errors
This commit is contained in:
@@ -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);
|
||||
|
||||
+2
-1
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+20
-9
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+85
-20
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-1
@@ -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();
|
||||
}
|
||||
|
||||
+28
-29
@@ -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;
|
||||
|
||||
+8
-42
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user