diff --git a/README.md b/README.md
index 24ce9af..5fc85f4 100644
--- a/README.md
+++ b/README.md
@@ -6,27 +6,25 @@ Ridgebotics 2025 scouting app in Android
- Make the "Report" menu, A tool that lets users select data to display from the the teams and compare menus.
- Make practice mode
#### Data Analysis:
-- Statbotics intigration
+- Statbotics intigration???
- AI overview of scouting data for a team???
- Make the "Compare" menu, cross comparing team's stats.
#### Functionality:
-- Make the system for blank and unselected fields better.
- Add more types of data fields.
-- Make server software to allow for easy sync over wifi
- Test the scouting app
- Deploy to F-Droid
## In Progress:
#### Scouting:
-- When a field is created, make updated scouting data return null values, not the default value
-- Fix scouting offset bug
#### Data Analysis:
#### Functionality:
-
+- Make server software to allow for easy sync over wifi - FTP
## Done:
#### Scouting:
- Add an "unselect" option to all of the scouting fields
+- When a field is created, make updated scouting data return null values, not the default value
+- Fix scouting offset bug
#### Data Analysis:
- Add "history" view type to the teams view menu.
- Sentiment analysis of text input type
@@ -39,3 +37,4 @@ Ridgebotics 2025 scouting app in Android
- Bluetooth data sync
- Formalize error messages & stacktraces
- Make pit and match data field builder UIs. I don't want to have to keep editing a variable
+- Make the system for blank and unselected fields better.
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0756344..3ceff53 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,9 @@
android:name="android.hardware.camera"
android:required="true" />
+
+
+
@@ -36,10 +39,14 @@
android:label="@string/app_name">
-
+
+
+
+
entries = new ArrayList<>();
for (int a = 0; a < data.length; a++) {
- if(data[a] == null) continue;
+ if(data[a].isNull()) continue;
entries.add(
new Entry(a,
diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/types/input/sliderType.java b/app/src/main/java/com/astatin3/scoutingapp2025/types/input/sliderType.java
index 0016519..85dd479 100644
--- a/app/src/main/java/com/astatin3/scoutingapp2025/types/input/sliderType.java
+++ b/app/src/main/java/com/astatin3/scoutingapp2025/types/input/sliderType.java
@@ -186,7 +186,7 @@ public class sliderType extends inputType {
int[] values = new int[max-min+1];
for (int i = 0; i < data.length; i++)
- if(intType.isNull((int) data[i].get()))
+ if(!data[i].isNull())
values[(int) data[i].get()-min]++;
@@ -262,6 +262,7 @@ public class sliderType extends inputType {
List entries = new ArrayList<>();
for (int i = 0; i < data.length; i++){
if(data[i] == null) continue;
+ if(data[i].isNull()) continue;
entries.add(new Entry(i, (float)(int) data[i].get()));
}
diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/types/input/tallyType.java b/app/src/main/java/com/astatin3/scoutingapp2025/types/input/tallyType.java
index a2643f2..6339b68 100644
--- a/app/src/main/java/com/astatin3/scoutingapp2025/types/input/tallyType.java
+++ b/app/src/main/java/com/astatin3/scoutingapp2025/types/input/tallyType.java
@@ -98,7 +98,7 @@ public class tallyType extends inputType {
public void add_individual_view(LinearLayout parent, dataType data){
- if((int)data.get() == 0) return;
+ if(data.isNull()) return;
TextView tv = new TextView(parent.getContext());
tv.setLayoutParams(new FrameLayout.LayoutParams(
@@ -176,7 +176,7 @@ public class tallyType extends inputType {
int[] values = new int[max-min+1];
for (int i = 0; i < data.length; i++)
- if(intType.isNull((int) data[i].get()))
+ if(data[i] != null && data[i].isNull())
values[(int) data[i].get()-min]++;
@@ -255,6 +255,7 @@ public class tallyType extends inputType {
List entries = new ArrayList<>();
for (int i = 0; i < data.length; i++){
if(data[i] == null) continue;
+ if(data[i].isNull()) continue;
entries.add(new Entry(i, (float)(int) data[i].get()));
}
diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/types/input/textType.java b/app/src/main/java/com/astatin3/scoutingapp2025/types/input/textType.java
index e932ffc..4b4dd5c 100644
--- a/app/src/main/java/com/astatin3/scoutingapp2025/types/input/textType.java
+++ b/app/src/main/java/com/astatin3/scoutingapp2025/types/input/textType.java
@@ -183,6 +183,7 @@ public class textType extends inputType {
List entries = new ArrayList<>();
for (int i = 0; i < data.length; i++) {
if(data[i] == null) continue;
+ if(data[i].isNull()) continue;
entries.add(
new Entry(i,
diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/CSVExport.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/CSVExport.java
index 99208b7..78e3060 100644
--- a/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/CSVExport.java
+++ b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/CSVExport.java
@@ -4,6 +4,7 @@ import static com.astatin3.scoutingapp2025.utility.DataManager.evcode;
import static com.astatin3.scoutingapp2025.utility.DataManager.event;
import static com.astatin3.scoutingapp2025.utility.DataManager.match_latest_values;
import static com.astatin3.scoutingapp2025.utility.DataManager.pit_latest_values;
+import static com.astatin3.scoutingapp2025.utility.SharePrompt.shareContent;
import android.content.Context;
import android.content.Intent;
@@ -122,29 +123,4 @@ public class CSVExport {
shareContent(c, evcode+"-pits.csv", data, "text/plain");
}
-
-
-
-
-
-
- public static void shareContent(Context context, String fileName, String content, String mimeType) {
- try {
- File file = new File(context.getCacheDir(), fileName);
- FileOutputStream fos = new FileOutputStream(file);
- fos.write(content.getBytes());
- fos.close();
-
- Uri fileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", file);
-
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.setType(mimeType);
- shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
- shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
- context.startActivity(Intent.createChooser(shareIntent, "Share using"));
- } catch (IOException e) {
- AlertManager.error(e);
- }
- }
}
diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/FileBundle.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/FileBundle.java
new file mode 100644
index 0000000..76155c2
--- /dev/null
+++ b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/FileBundle.java
@@ -0,0 +1,107 @@
+package com.astatin3.scoutingapp2025.ui.transfer;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+import com.astatin3.scoutingapp2025.MainActivity;
+import com.astatin3.scoutingapp2025.types.file;
+import com.astatin3.scoutingapp2025.utility.AlertManager;
+import com.astatin3.scoutingapp2025.utility.BuiltByteParser;
+import com.astatin3.scoutingapp2025.utility.ByteBuilder;
+import com.astatin3.scoutingapp2025.utility.DataManager;
+import com.astatin3.scoutingapp2025.utility.SharePrompt;
+import com.astatin3.scoutingapp2025.utility.fileEditor;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FileBundle {
+ private static final Intent FILE_SELECT_CODE = new Intent();
+
+ public static void send(String[] files, Context c){
+ try {
+ ByteBuilder b = new ByteBuilder();
+
+ for(int i = 0; i < files.length; i++){
+ if(!fileEditor.fileExist(files[i])) continue;
+ // byte[] data = fileEditor.readFile(files[i]);
+ file f = new file(files[i]);
+ b.addRaw(file.typecode, f.encode());
+ }
+
+ byte[] data = b.build();
+ send(data, c);
+
+ } catch (ByteBuilder.buildingException e) {
+ AlertManager.error(e);
+ }
+ }
+
+ public static void send(byte[] data, Context c){
+ String filename = DataManager.getevcode() + "-" + System.currentTimeMillis() + ".scoutbundle";
+ SharePrompt.shareContent(c, filename, data, "application/ridgescout");
+ }
+
+
+ public static void receive(Activity b){
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.setType("*/*");
+
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
+
+ MainActivity.setResultRelay(new MainActivity.activityResultRelay() {
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ Uri uri = data.getData();
+ if(uri == null) return;
+
+ try (InputStream is = b.getContentResolver().openInputStream(uri)) {
+ ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
+ int bufferSize = 1024;
+ byte[] buffer = new byte[bufferSize];
+ int len = 0;
+ while ((len = is.read(buffer)) != -1) {
+ byteBuffer.write(buffer, 0, len);
+ }
+ byte[] bytes = byteBuffer.toByteArray();
+ saveFiles(bytes);
+// AlertManager.error(""+(bytes.length));
+ } catch (IOException e) {
+ // Handle the exception
+ }
+ }
+ });
+ b.startActivityForResult(intent, 1);
+ }
+
+
+ private static void saveFiles(byte[] data){
+ BuiltByteParser bbp = new BuiltByteParser(data);
+ try{
+ List parsedObjectList = bbp.parse();
+
+ ArrayList filenames = new ArrayList<>();
+
+ for(int i = 0; i < parsedObjectList.size(); i++){
+ BuiltByteParser.parsedObject pa = parsedObjectList.get(i);
+ if(pa.getType() != file.typecode) continue;
+ file f = file.decode((byte[]) pa.get());
+ if(f == null) continue;
+ filenames.add(f.filename);
+ fileEditor.writeFile(f.filename, f.data);
+ }
+
+ AlertManager.alert("Saved",
+ String.join("\n", filenames));
+
+ }catch (BuiltByteParser.byteParsingExeption e){
+ AlertManager.error(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TransferFragment.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TransferFragment.java
index f22a947..8f1c371 100644
--- a/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TransferFragment.java
+++ b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TransferFragment.java
@@ -34,12 +34,14 @@ public class TransferFragment extends Fragment {
private static final int background_color = 0x5000ff00;
private static final int unselected_background_color = 0x2000ff00;
+// private Bundle b;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
+// b = savedInstanceState;
binding = FragmentTransferBinding.inflate(inflater, container, false);
@@ -114,19 +116,21 @@ public class TransferFragment extends Fragment {
private void start_upload() {
FileSelectorFragment.setOnSelect(data -> {
- CodeGeneratorView.setData(data);
- BluetoothSenderFragment.set_data(data);
TransferSelectorFragment.setOnSelect(new TransferSelectorFragment.onSelect() {
@Override
public void onSelectCodes(TransferSelectorFragment self) {
+ CodeGeneratorView.setData(data);
findNavController(self).navigate(R.id.action_navigation_transfer_selector_to_navigation_code_generator);
}
@Override
public void onSelectBluetooth(TransferSelectorFragment self) {
+ BluetoothSenderFragment.set_data(data);
findNavController(self).navigate(R.id.action_navigation_transfer_selector_to_navigation_bluetooth_sender);
}
@Override
- public void onSelectWifi(TransferSelectorFragment self) {}
+ public void onSelectFileBundle(TransferSelectorFragment self) {
+ FileBundle.send(data, getContext());
+ }
});
findNavController(this).navigate(R.id.action_navigation_file_selector_to_navigation_transfer_selector);
});
@@ -137,6 +141,7 @@ public class TransferFragment extends Fragment {
private void start_download(){
+
TransferSelectorFragment.setOnSelect(new TransferSelectorFragment.onSelect() {
@Override
public void onSelectCodes(TransferSelectorFragment self) {
@@ -149,7 +154,9 @@ public class TransferFragment extends Fragment {
}
@Override
- public void onSelectWifi(TransferSelectorFragment self) {}
+ public void onSelectFileBundle(TransferSelectorFragment self) {
+ FileBundle.receive(getActivity());
+ }
});
findNavController(this).navigate(R.id.action_navigation_transfer_to_navigation_transfer_selector);
}
diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TransferSelectorFragment.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TransferSelectorFragment.java
index ef69111..5c41ad6 100644
--- a/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TransferSelectorFragment.java
+++ b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TransferSelectorFragment.java
@@ -14,7 +14,7 @@ import com.astatin3.scoutingapp2025.databinding.FragmentTransferSelectorBinding;
public class TransferSelectorFragment extends Fragment {
// Declaring three blank funcs in one line lol
- private static onSelect onselect = new onSelect() {@Override public void onSelectCodes(TransferSelectorFragment self) {}@Override public void onSelectBluetooth(TransferSelectorFragment self) {} @Override public void onSelectWifi(TransferSelectorFragment self) {}};
+ private static onSelect onselect = new onSelect() {@Override public void onSelectCodes(TransferSelectorFragment self) {}@Override public void onSelectBluetooth(TransferSelectorFragment self) {} @Override public void onSelectFileBundle(TransferSelectorFragment self) {}};
public static void setOnSelect(onSelect tmp) {
onselect = tmp;
@@ -23,7 +23,7 @@ public class TransferSelectorFragment extends Fragment {
public interface onSelect {
void onSelectCodes(TransferSelectorFragment self);
void onSelectBluetooth(TransferSelectorFragment self);
- void onSelectWifi(TransferSelectorFragment self);
+ void onSelectFileBundle(TransferSelectorFragment self);
}
FragmentTransferSelectorBinding binding;
@@ -38,8 +38,8 @@ public class TransferSelectorFragment extends Fragment {
onselect.onSelectBluetooth(this);
});
- binding.wifiButton.setOnClickListener(view -> {
- onselect.onSelectWifi(this);
+ binding.fileBundleButton.setOnClickListener(view -> {
+ onselect.onSelectFileBundle(this);
});
return binding.getRoot();
diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/utility/SharePrompt.java b/app/src/main/java/com/astatin3/scoutingapp2025/utility/SharePrompt.java
new file mode 100644
index 0000000..07d5870
--- /dev/null
+++ b/app/src/main/java/com/astatin3/scoutingapp2025/utility/SharePrompt.java
@@ -0,0 +1,37 @@
+package com.astatin3.scoutingapp2025.utility;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+import androidx.core.content.FileProvider;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class SharePrompt {
+ public static void shareContent(Context context, String fileName, String content, String mimeType) {
+ shareContent(context, fileName, content.getBytes(), mimeType);
+ }
+
+ public static void shareContent(Context context, String fileName, byte[] content, String mimeType) {
+ try {
+ File file = new File(context.getCacheDir(), fileName);
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.write(content);
+ fos.close();
+
+ Uri fileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", file);
+
+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
+ shareIntent.setType(mimeType);
+ shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
+ shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ context.startActivity(Intent.createChooser(shareIntent, "Share using"));
+ } catch (IOException e) {
+ AlertManager.error(e);
+ }
+ }
+}
diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/utility/fileEditor.java b/app/src/main/java/com/astatin3/scoutingapp2025/utility/fileEditor.java
index 7e45b27..c0718ff 100644
--- a/app/src/main/java/com/astatin3/scoutingapp2025/utility/fileEditor.java
+++ b/app/src/main/java/com/astatin3/scoutingapp2025/utility/fileEditor.java
@@ -228,7 +228,10 @@ public final class fileEditor {
}
public static byte[] readFile(String path){
- File file = new File(baseDir + path);
+ return readFileExact(baseDir + path);
+ }
+ public static byte[] readFileExact(String path){
+ File file = new File(path);
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
diff --git a/app/src/main/res/layout/fragment_transfer.xml b/app/src/main/res/layout/fragment_transfer.xml
index dd984f2..2a78f1b 100644
--- a/app/src/main/res/layout/fragment_transfer.xml
+++ b/app/src/main/res/layout/fragment_transfer.xml
@@ -33,28 +33,28 @@
android:layout_height="wrap_content"
android:text="Upload"
android:textSize="34sp"
- app:layout_constraintBottom_toTopOf="@+id/downloadButton"
+ app:layout_constraintBottom_toTopOf="@+id/CSVButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
-
+
+
+ app:layout_constraintTop_toBottomOf="@+id/CSVButton" />
diff --git a/app/src/main/res/layout/fragment_transfer_selector.xml b/app/src/main/res/layout/fragment_transfer_selector.xml
index cbff426..24df824 100644
--- a/app/src/main/res/layout/fragment_transfer_selector.xml
+++ b/app/src/main/res/layout/fragment_transfer_selector.xml
@@ -21,16 +21,16 @@
android:layout_height="wrap_content"
android:text="Bluetooth"
android:textSize="34sp"
- app:layout_constraintBottom_toTopOf="@+id/wifiButton"
+ app:layout_constraintBottom_toTopOf="@+id/fileBundleButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/codes_button" />