Add ByteBuilder, start work on parsing stored data

This commit is contained in:
Astatin3
2024-05-03 21:10:08 -06:00
parent bf64f8f6d1
commit 1321aad34c
33 changed files with 769 additions and 411 deletions
@@ -0,0 +1,94 @@
package com.astatin3.scoutingapp2025;
import android.util.Log;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
public class BuiltByteParser {
public static final Integer intType = 0;
public static final Integer stringType = 1;
public class byteParsingExeption extends Exception {
public byteParsingExeption() {}
public byteParsingExeption(String message) {
super(message);
}
}
public abstract class parsedObject {
public abstract Integer getType();
public abstract Object get();
}
public class intObject extends parsedObject{
int num;
public Integer getType(){return intType;}
public Object get(){return num;}
}
public class stringObject extends parsedObject{
String str;
public Integer getType(){return stringType;}
public Object get(){return str;}
}
public class rawObject extends parsedObject {
private int type;
public rawObject(int type){this.type = type;}
byte[] bytes;
public Integer getType(){return type;}
public Object get(){return bytes;}
}
byte[] bytes;
ArrayList<parsedObject> objects = new ArrayList<>();
public BuiltByteParser(byte[] bytes){
this.bytes = bytes;
}
public ArrayList<parsedObject> parse() throws byteParsingExeption {
if(bytes.length < 3){throw new byteParsingExeption("Invalid length");}
int curIndex = 0;
while(true){
// Log.i("t", String.valueOf(curIndex));
final int length = fileEditor.fromBytes(fileEditor.getByteBlock(bytes, curIndex, curIndex+2), 2);
final int type = bytes[curIndex+2] & 0xFF;
if(length == 0){
curIndex += 3;
continue;
}
final byte[] block;
try {
block = fileEditor.getByteBlock(bytes, curIndex + 3, curIndex + length + 3);
} catch(Exception e){
throw new byteParsingExeption("Array out of bounds");
}
switch(type){
case 0:
intObject io = new intObject();
io.num = fileEditor.fromBytes(block, length);
objects.add(io);
break;
case 1:
stringObject so = new stringObject();
so.str = new String(block, StandardCharsets.UTF_8);
objects.add(so);
break;
default:
rawObject ro = new rawObject(type);
ro.bytes = block;
objects.add(ro);
break;
}
curIndex += length + 3;
if(curIndex == bytes.length){
break;
}else if(curIndex > bytes.length){
throw new byteParsingExeption("Block length problem");
}
}
return objects;
}
}
@@ -0,0 +1,139 @@
package com.astatin3.scoutingapp2025;
import android.util.Log;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
public class ByteBuilder {
ArrayList<byteType> bytesToBuild = new ArrayList<>();
public class buildingException extends Exception {
public buildingException() {}
public buildingException(String message) {
super(message);
}
}
private abstract static class byteType {
public abstract byte getType();
public abstract int length();
public abstract byte[] build();
}
private class intType extends byteType {
public int precision;
public int num;
public byte getType(){return 0;}
public int length(){return precision;}
public byte[] build(){
return fileEditor.toBytes(num, precision);
}
}
private int getLeastBytePrecision(int num){
if(num <= 1){return 1;}
return (int) Math.ceil(Math.log(Math.abs(num))/Math.log(8));
}
public ByteBuilder addInt(int num) throws buildingException {
// Get closest number of bytes
int precision = getLeastBytePrecision(num);
return addInt(num, precision);
}
public ByteBuilder addInt(int num, int precision) throws buildingException {
if(precision <= 0){throw new buildingException("Invalid precision: " + precision);}
if(precision > 65536){throw new buildingException("Precision too large (greter than 65536)");}
if(precision < getLeastBytePrecision(num)){throw new buildingException("Precision too small");}
if(num > Integer.MAX_VALUE){throw new buildingException("Integer overflow");}
if(num < Integer.MIN_VALUE){throw new buildingException("Integer overflow");}
intType intType = new intType();
intType.num = num;
intType.precision = precision;
bytesToBuild.add(intType);
return this;
}
private class stringType extends byteType {
public byte[] bytes;
public byte getType(){return 1;}
public int length(){return bytes.length;}
public byte[] build(){
return bytes;
// return str.getBytes(charset);
}
}
public ByteBuilder addString(String str) throws buildingException {
if(str.length() > 65536){throw new buildingException("String too long (greater than 65536)");}
stringType stringType = new stringType();
// To get the length correctly, the string bytes need to be precalculated
stringType.bytes = str.getBytes(StandardCharsets.UTF_8);
bytesToBuild.add(stringType);
return this;
}
private class rawType extends byteType {
public int type;
public byte[] bytes;
public byte getType(){return (byte) type;}
public int length(){return bytes.length;}
public byte[] build(){
return bytes;
}
}
public ByteBuilder addRaw(int type, byte[] bytes) throws buildingException {
if(bytes.length > 65536){throw new buildingException("Byte array length to long (greater than 65536)");}
rawType rawType = new rawType();
rawType.type = type;
rawType.bytes = bytes;
bytesToBuild.add(rawType);
return this;
}
public byte[] build() throws buildingException {
if(bytesToBuild.size() == 0){throw new buildingException("Cannot build null data");}
int length = bytesToBuild.size() * 3;
for(byteType bt : bytesToBuild){
length += bt.length();
}
byte[] bytes = new byte[length];
int bytesFilled = 0;
for(byteType bt : bytesToBuild){
byte[] blockLength = fileEditor.toBytes(bt.length(), 2);
bytes[bytesFilled] = blockLength[0];
bytesFilled += 1;
bytes[bytesFilled] = blockLength[1];
bytesFilled += 1;
bytes[bytesFilled] = bt.getType();
bytesFilled += 1;
// if(bt.length == 0)
// continue;
int i = 1;
byte[] newBytes = bt.build();
for(byte b : newBytes){
// Log.i("i", (bytesFilled+1) + "/" + length + " (" + i + "/" + bt.length() + ")");
bytes[bytesFilled] = b;
bytesFilled += 1;
i++;
}
}
return bytes;
}
}
@@ -28,7 +28,7 @@ public class MainActivity extends AppCompatActivity {
// 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_home, R.id.navigation_notifications, R.id.navigation_tba)
R.id.navigation_scouting, R.id.navigation_transfer, R.id.navigation_settings)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
@@ -1,13 +1,6 @@
package com.astatin3.scoutingapp2025;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;
import java.io.BufferedReader;
import java.io.IOException;
@@ -43,8 +36,6 @@ public class RequestTask extends AsyncTask<String, String, String> {
else {
return null; // See documentation for more info on response handling
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
@@ -52,10 +43,10 @@ public class RequestTask extends AsyncTask<String, String, String> {
}
private static String readStream(InputStream in) {
BufferedReader reader = null;
StringBuffer response = new StringBuffer();
StringBuilder response = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
@@ -1,10 +0,0 @@
package com.astatin3.scoutingapp2025.Utils;
import java.util.ArrayList;
public class frcEvent {
public String eventCode;
public String name;
public ArrayList<frcMatch> matches;
public ArrayList<frcTeam> teams;
}
@@ -1,8 +0,0 @@
package com.astatin3.scoutingapp2025.Utils;
public class frcMatch {
public frcMatch(){}
public int matchIndex = 0;
public int[] blueAlliance;
public int[] redAlliance;
}
@@ -1,22 +0,0 @@
package com.astatin3.scoutingapp2025.Utils;
public class frcTeam {
public int teamNumber = 0;
public String teamName = null;
public String city = null;
public String stateOrProv = null;
public String school = null;
public String country = null;
public int startingYear = 0;
public String getDescription(){
return teamName + " Started in " + startingYear + ", and is from " + school + " in " + city + ", " + stateOrProv + ", " + country;
}
public frcTeam encode(){
return this;
}
public frcTeam decode(){
return this;
}
}
@@ -1,11 +1,17 @@
package com.astatin3.scoutingapp2025;
import android.content.Context;
import android.util.Log;
import com.astatin3.scoutingapp2025.Utils.frcMatch;
import com.astatin3.scoutingapp2025.Utils.frcTeam;
import com.astatin3.scoutingapp2025.types.frcEvent;
import com.astatin3.scoutingapp2025.types.frcMatch;
import com.astatin3.scoutingapp2025.types.frcTeam;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.BufferOverflowException;
@@ -17,7 +23,7 @@ import java.util.zip.Deflater;
import java.util.zip.Inflater;
public final class fileEditor {
// private final static String baseDir = android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
private final static String baseDir = "/data/data/com.astatin3.scoutingapp2025/files/";
public static final byte internalDataVersion = 0x01;
public static final int maxCompressedBlockSize = 4096;
@@ -25,11 +31,11 @@ public final class fileEditor {
public static String binaryVisualize(byte[] bytes){
String returnStr = "";
for(int a=0;a<bytes.length;a++){
for(int b=0;b<8;b++){
returnStr += String.valueOf((bytes[a] >> b) & 1);
for (byte aByte : bytes) {
for (int b = 7; b >= 0; b--) {
returnStr += String.valueOf((aByte >> b) & 1);
}
returnStr += " (" + (int)bytes[a] + ")\n";
returnStr += " (" + (int) aByte + ")\n";
}
return returnStr;
}
@@ -43,7 +49,7 @@ public final class fileEditor {
public static byte[] toBytes(int num, int byteCount){
if(num < 0 || num > (Math.pow(2,byteCount*8)-1)){
if(num > (Math.pow(2,byteCount*8)-1)){
throw new BufferOverflowException();
}
byte[] bytes = new byte[byteCount];
@@ -118,11 +124,11 @@ public final class fileEditor {
return outputStream.toByteArray();
}
private static boolean writeToFile(Context context, String filepath, String data) {
private static boolean writeToFile(String filepath, byte[] data) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput(filepath, Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
FileOutputStream output = new FileOutputStream(filepath);
output.write(data);
output.close();
return true;
}
catch (IOException e) {
@@ -131,6 +137,24 @@ public final class fileEditor {
}
}
public static byte[] readFile(String path){
File file = new File(path);
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(bytes, 0, bytes.length);
buf.close();
return bytes;
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static String intSplit(int[] intArr, String splitStr){
String returnStr = "";
for(int i=0;i<intArr.length;i++){
@@ -142,24 +166,32 @@ public final class fileEditor {
return returnStr;
}
public static boolean setMatches(Context context, String key, String matchName, ArrayList<frcMatch> matches){
final String filename = (key + "-matches.csv");
String csvData = "";
csvData += key + "\n";
csvData += matchName + "\n";
for(int i=0;i<matches.size();i++){
final frcMatch match = matches.get(i);
csvData += String.valueOf(match.matchIndex)
+ "," + intSplit(match.redAlliance, ",")
+ "," + intSplit(match.blueAlliance, ",") + "\n";
}
return writeToFile(context, filename, csvData);
public static boolean setEvent(frcEvent event){
final String filename = (baseDir + event.eventCode + ".eventdata");
return writeToFile(filename, event.encode());
}
public static ArrayList<String> getEventList(){
File f = new File(baseDir);
File[] files = f.listFiles();
ArrayList<String> outFiles = new ArrayList<>();
if(files == null){return outFiles;}
for (File file : files) {
if(!file.isDirectory() && file.getName().endsWith(".eventdata")) {
outFiles.add(file.getName());
}
}
return outFiles;
}
public static boolean setTeams(Context context, String key, ArrayList<frcTeam> teams){
return true;
}
@@ -0,0 +1,5 @@
package com.astatin3.scoutingapp2025.types;
public class file {
public static final int typecode = 255;
}
@@ -0,0 +1,71 @@
package com.astatin3.scoutingapp2025.types;
import android.util.Log;
import androidx.annotation.NonNull;
import com.astatin3.scoutingapp2025.BuiltByteParser;
import com.astatin3.scoutingapp2025.ByteBuilder;
import java.util.ArrayList;
public class frcEvent {
public static final int typecode = 254;
public String eventCode;
public String name;
public ArrayList<frcMatch> matches;
public ArrayList<frcTeam> teams;
public byte[] encode(){
try {
ByteBuilder bb = new ByteBuilder()
.addString(eventCode)
.addString(name);
for(frcTeam teams : teams){
bb.addRaw(frcTeam.typecode, teams.encode());
}
for(frcMatch match : matches){
bb.addRaw(frcMatch.typecode, match.encode());
}
return bb.build();
} catch (ByteBuilder.buildingException e) {
e.printStackTrace();
return null;
}
}
public static frcEvent decode(byte[] bytes){
try{
ArrayList<BuiltByteParser.parsedObject> objects = new BuiltByteParser(bytes).parse();
frcEvent frc = new frcEvent();
frc.eventCode = (String) objects.get(0).get();
frc.name = (String) objects.get(1).get();
frc.matches = new ArrayList<>();
frc.teams = new ArrayList<>();
for(BuiltByteParser.parsedObject object : objects){
if(object.getType() == frcTeam.typecode){
frc.teams.add(frcTeam.decode((byte[]) object.get()));
}else if(object.getType() == frcMatch.typecode){
frc.matches.add(frcMatch.decode((byte[]) object.get()));
}
}
return frc;
}catch (BuiltByteParser.byteParsingExeption e){
e.printStackTrace();
return null;
}
}
@NonNull
public String toString(){
return "Name: " + name + ", Code: " + eventCode + " numTeams: " + teams.size() + " numMatches: " + matches.size();
}
}
@@ -0,0 +1,55 @@
package com.astatin3.scoutingapp2025.types;
import com.astatin3.scoutingapp2025.BuiltByteParser;
import com.astatin3.scoutingapp2025.ByteBuilder;
import java.util.ArrayList;
public class frcMatch {
public static final int typecode = 253;
public frcMatch(){}
public int matchIndex = 0;
public int[] blueAlliance = new int[3];
public int[] redAlliance = new int[3];
public byte[] encode(){
try {
return new ByteBuilder()
.addInt(matchIndex)
.addInt(blueAlliance[0])
.addInt(blueAlliance[1])
.addInt(blueAlliance[2])
.addInt(redAlliance[0])
.addInt(redAlliance[1])
.addInt(redAlliance[2])
.build();
} catch (ByteBuilder.buildingException e) {
e.printStackTrace();
return new byte[1];
}
}
public static frcMatch decode(byte[] bytes){
try {
ArrayList<BuiltByteParser.parsedObject> objects = new BuiltByteParser(bytes).parse();
frcMatch frc = new frcMatch();
frc.matchIndex = (int) objects.get(0).get();
frc.blueAlliance[0] = (int) objects.get(1).get();
frc.blueAlliance[1] = (int) objects.get(2).get();
frc.blueAlliance[2] = (int) objects.get(3).get();
frc.redAlliance[0] = (int) objects.get(4).get();
frc.redAlliance[1] = (int) objects.get(5).get();
frc.redAlliance[2] = (int) objects.get(6).get();
return frc;
} catch (BuiltByteParser.byteParsingExeption e) {
e.printStackTrace();
return null;
}
}
}
@@ -0,0 +1,59 @@
package com.astatin3.scoutingapp2025.types;
import com.astatin3.scoutingapp2025.BuiltByteParser;
import com.astatin3.scoutingapp2025.ByteBuilder;
import java.util.ArrayList;
public class frcTeam {
public static final int typecode = 252;
public int teamNumber = 0;
public String teamName = "null";
public String city = "null";
public String stateOrProv = "null";
public String school = "null";
public String country = "null";
public int startingYear = 0;
public String getDescription(){
return teamName + " Started in " + startingYear + ", and is from " + school + " in " + city + ", " + stateOrProv + ", " + country;
}
public byte[] encode(){
try {
return new ByteBuilder()
.addInt(teamNumber)
.addString(teamName)
.addString(city)
.addString(stateOrProv)
.addString(school)
.addString(country)
.addInt(startingYear)
.build();
} catch (ByteBuilder.buildingException e) {
e.printStackTrace();
return null;
}
}
public static frcTeam decode(byte[] bytes){
try {
ArrayList<BuiltByteParser.parsedObject> objects = new BuiltByteParser(bytes).parse();
frcTeam frc = new frcTeam();
frc.teamNumber = (int) objects.get(0).get();
frc.teamName = (String) objects.get(1).get();
frc.city = (String) objects.get(2).get();
frc.stateOrProv = (String) objects.get(3).get();
frc.school = (String) objects.get(4).get();
frc.country = (String) objects.get(5).get();
frc.startingYear = (int) objects.get(6).get();
return frc;
} catch (BuiltByteParser.byteParsingExeption e) {
e.printStackTrace();
return null;
}
}
}
@@ -13,7 +13,7 @@ public class JSONUtil {
for (int i=0; i<array.length(); i++){
asList.add(array.opt(i));
}
Collections.sort(asList, c);
asList.sort(c);
JSONArray res = new JSONArray();
for (Object o : asList){
res.put(o);
@@ -1,37 +1,19 @@
package com.astatin3.scoutingapp2025.ui.TBA;
package com.astatin3.scoutingapp2025.ui.Settings;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TableRow;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.astatin3.scoutingapp2025.RequestTask;
import com.astatin3.scoutingapp2025.databinding.FragmentTbaBinding;
import com.astatin3.scoutingapp2025.ui.JSONUtil;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Comparator;
import java.util.function.Function;
import com.astatin3.scoutingapp2025.databinding.FragmentSettingsBinding;
public class TBAFragment extends Fragment {
// private final String
private final String TBAAddress = "https://www.thebluealliance.com/api/v3/";
private final String TBAHeader = "X-TBA-Auth-Key: tjEKSZojAU2pgbs2mBt06SKyOakVhLutj3NwuxLTxPKQPLih11aCIwRIVFXKzY4e";
private FragmentTbaBinding binding;
public class Settings extends Fragment {
private FragmentSettingsBinding binding;
private android.widget.ScrollView ScrollArea;
private android.widget.TableLayout Table;
@@ -48,7 +30,7 @@ public class TBAFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentTbaBinding.inflate(inflater, container, false);
binding = FragmentSettingsBinding.inflate(inflater, container, false);
View root = binding.getRoot();
return root;
@@ -0,0 +1,35 @@
package com.astatin3.scoutingapp2025.ui.scouting;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.astatin3.scoutingapp2025.databinding.FragmentDataBinding;
import com.astatin3.scoutingapp2025.fileEditor;
public class dataFragment extends Fragment {
private FragmentDataBinding binding;
private void setDropdownItems(Spinner dropdown, String[] items){
ArrayAdapter<String> adapter = new ArrayAdapter<>(requireActivity(), android.R.layout.simple_spinner_item, items);
dropdown.setAdapter(adapter);
}
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentDataBinding.inflate(inflater, container, false);
View root = binding.getRoot();
return root;
}
}
@@ -1,26 +0,0 @@
package com.astatin3.scoutingapp2025.ui.home;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.astatin3.scoutingapp2025.databinding.FragmentHomeBinding;
public class HomeFragment extends Fragment {
private FragmentHomeBinding binding;
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentHomeBinding.inflate(inflater, container, false);
View root = binding.getRoot();
return root;
}
}
@@ -0,0 +1,40 @@
z1package com.astatin3.scoutingapp2025.ui.scouting;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.astatin3.scoutingapp2025.databinding.FragmentScoutingBinding;
import com.astatin3.scoutingapp2025.fileEditor;
public class scoutingFragment extends Fragment {
private FragmentScoutingBinding binding;
private void setDropdownItems(Spinner dropdown, String[] items){
ArrayAdapter<String> adapter = new ArrayAdapter<>(requireActivity(), android.R.layout.simple_spinner_item, items);
dropdown.setAdapter(adapter);
}
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentScoutingBinding.inflate(inflater, container, false);
View root = binding.getRoot();
Spinner dropdown = binding.eventDropdown;
setDropdownItems(dropdown, fileEditor.getEventList().toArray(new String[0]));
return root;
}
}
@@ -13,8 +13,9 @@ import android.widget.TableRow;
import android.widget.TextView;
import com.astatin3.scoutingapp2025.RequestTask;
import com.astatin3.scoutingapp2025.Utils.frcMatch;
import com.astatin3.scoutingapp2025.Utils.frcTeam;
import com.astatin3.scoutingapp2025.types.frcEvent;
import com.astatin3.scoutingapp2025.types.frcMatch;
import com.astatin3.scoutingapp2025.types.frcTeam;
import com.astatin3.scoutingapp2025.databinding.FragmentTransferBinding;
import com.astatin3.scoutingapp2025.fileEditor;
import com.astatin3.scoutingapp2025.ui.JSONUtil;
@@ -29,7 +30,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.function.Function;
import java.util.Objects;
public class TBAView extends ScrollView {
private final String TBAAddress = "https://www.thebluealliance.com/api/v3/";
@@ -66,12 +67,9 @@ public class TBAView extends ScrollView {
Table.addView(tr);
final RequestTask rq = new RequestTask();
rq.onResult(new Function<String, String>() {
@Override
public String apply(String s) {
eventTable(s);
return null;
}
rq.onResult(s -> {
eventTable(s);
return null;
});
rq.execute(TBAAddress + "events/"+yearStr, TBAHeader);
@@ -100,13 +98,6 @@ public class TBAView extends ScrollView {
boolean toggle = false;
// TableRow tr = new TableRow(getContext());
// addTableText(tr, "Key");
// addTableText(tr, "Title");
// addTableText(tr, "Type");
//
// Table.addView(tr);
for(int i=0;i<data.length();i++){
TableRow tr = new TableRow(getContext());
TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams(
@@ -156,39 +147,30 @@ public class TBAView extends ScrollView {
}
tr.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
Table.removeAllViews();
Table.setStretchAllColumns(true);
Table.bringToFront();
tr.setOnClickListener(v -> {
Table.removeAllViews();
Table.setStretchAllColumns(true);
Table.bringToFront();
TableRow tr = new TableRow(getContext());
addTableText(tr, "Downloading Teams...");
Table.addView(tr);
TableRow tr1 = new TableRow(getContext());
addTableText(tr1, "Downloading Teams...");
Table.addView(tr1);
final RequestTask rq = new RequestTask();
rq.onResult(new Function<String, String>() {
@Override
public String apply(String teamsStr) {
TableRow tr = new TableRow(getContext());
addTableText(tr, "Downloading Matches...");
Table.addView(tr);
final RequestTask rq = new RequestTask();
rq.onResult(teamsStr -> {
TableRow tr11 = new TableRow(getContext());
addTableText(tr11, "Downloading Matches...");
Table.addView(tr11);
final RequestTask rq = new RequestTask();
rq.onResult(new Function<String, String>() {
@Override
public String apply(String matchesStr) {
matchTable(matchesStr, teamsStr, j);
return null;
}
});
rq.execute((TBAAddress + "event/" + matchKey + "/matches"), TBAHeader);
return null;
}
final RequestTask rq1 = new RequestTask();
rq1.onResult(matchesStr -> {
matchTable(matchesStr, teamsStr, j);
return null;
});
rq.execute((TBAAddress + "event/" + matchKey + "/teams"), TBAHeader);
}
rq1.execute((TBAAddress + "event/" + matchKey + "/matches"), TBAHeader);
return null;
});
rq.execute((TBAAddress + "event/" + matchKey + "/teams"), TBAHeader);
});
// tr.addView(cl);
@@ -201,7 +183,7 @@ public class TBAView extends ScrollView {
}
}
class matchComparator implements Comparator<JSONObject>
static class matchComparator implements Comparator<JSONObject>
{
public int compare(JSONObject a, JSONObject b)
@@ -286,20 +268,18 @@ public class TBAView extends ScrollView {
Table.addView(tr);
final JSONArray sortedMatchData = JSONUtil.sort(matchData, new Comparator(){
public int compare(Object a, Object b){
JSONObject ja = (JSONObject)a;
JSONObject jb = (JSONObject)b;
try {
return ja.getInt("match_number") - jb.getInt("match_number");
}catch (JSONException j){
return 0;
}
final JSONArray sortedMatchData = JSONUtil.sort(matchData, (a, b) -> {
JSONObject ja = (JSONObject)a;
JSONObject jb = (JSONObject)b;
try {
return ja.getInt("match_number") - jb.getInt("match_number");
}catch (JSONException j){
return 0;
}
});
final ArrayList<frcMatch> matchesOBJ = new ArrayList<frcMatch>();
final ArrayList<frcMatch> matchesOBJ = new ArrayList<>();
boolean toggle = false;
int matchCount = 1;
@@ -334,12 +314,12 @@ public class TBAView extends ScrollView {
if(b < 3){
String str = redAlliance.getString(b).substring(3);
redKeys[b] = (int)Integer.parseInt(str);
redKeys[b] = Integer.parseInt(str);
text.setText(str);
text.setBackgroundColor(0x50ff0000);
}else{
String str = blueAlliance.getString(b-3).substring(3);
blueKeys[b-3] = (int)Integer.parseInt(str);
blueKeys[b-3] = Integer.parseInt(str);
text.setText(str);
text.setBackgroundColor(0x500000ff);
}
@@ -357,14 +337,11 @@ public class TBAView extends ScrollView {
toggle = !toggle;
}
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(saveData(matchesOBJ, teamData, eventData)){
alert("Info", "Saved!");
}else{
alert("Error", "Error saving files.");
}
btn.setOnClickListener(v -> {
if(saveData(matchesOBJ, teamData, eventData)){
alert("Info", "Saved!");
}else{
alert("Error", "Error saving files.");
}
});
@@ -385,7 +362,7 @@ public class TBAView extends ScrollView {
}
ArrayList<frcTeam> teams = new ArrayList<frcTeam>();
ArrayList<frcTeam> teams = new ArrayList<>();
for(int i=0;i<teamData.length();i++){
frcTeam teamObj = new frcTeam();
JSONObject team = teamData.getJSONObject(i);
@@ -401,8 +378,13 @@ public class TBAView extends ScrollView {
teams.add(teamObj);
}
return fileEditor.setMatches(getContext(), matchKey, matchName, matchData) &&
fileEditor.setTeams(getContext(), matchKey, teams);
frcEvent event = new frcEvent();
event.name = matchName;
event.eventCode = matchKey;
event.teams = teams;
event.matches = matchData;
return fileEditor.setEvent(event);
}catch (JSONException j){
j.printStackTrace();
alert("Error", "Invalid JSON");
File diff suppressed because one or more lines are too long
@@ -1,12 +1,10 @@
package com.astatin3.scoutingapp2025.ui.transfer;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
@@ -15,13 +13,11 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import com.astatin3.scoutingapp2025.databinding.FragmentTransferBinding;
import com.astatin3.scoutingapp2025.fileEditor;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.nio.charset.StandardCharsets;
@@ -47,8 +43,6 @@ public class generatorView extends ConstraintLayout {
private final int maxQrSize = 500;
private int qrSize = 200;
private int curCodeIndex = 0;
private final int defaultQrDelay = 419;
private int qrDelay = 0;
private int qrIndex = 0;
@@ -74,7 +68,7 @@ public class generatorView extends ConstraintLayout {
return null;
}
Map<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
// The Charset must be UTF-8, Or data will not be transferred properly. IDK why.
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
@@ -117,10 +111,6 @@ public class generatorView extends ConstraintLayout {
qrIndexN = binding.qrIndexN;
qrIndexD = binding.qrIndexD;
// byte[] randomData = new byte[4596];
// new Random().nextBytes(randomData);
// inputData = randomData;
String compiledData = "";
@@ -148,21 +138,9 @@ public class generatorView extends ConstraintLayout {
}
// byte[] tempData = fileEditor.compress(inputData);
// String compiledData = new String(tempData, StandardCharsets.ISO_8859_1);
sendData(compiledData);
}
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 sendData(String data){
// minQrSize = 0;
@@ -196,7 +174,7 @@ public class generatorView extends ConstraintLayout {
public void onStopTrackingTouch(SeekBar seekBar) {
qrSize = seekBar.getProgress() + minQrSize;
// qrCount = (int)Math.ceil((double) (data.length()+1)/qrSize);
qrCount = (int)((data.length()+1)/qrSize)+1;
qrCount = ((data.length()+1)/qrSize) +1;
qrIndexD.setText(String.valueOf(qrCount));
sendData(data);
}
@@ -204,7 +182,7 @@ public class generatorView extends ConstraintLayout {
qrSpeedSlider.setProgress(defaultQrDelay+5);
qrBitmaps = new ArrayList<Bitmap>();
qrBitmaps = new ArrayList<>();
int randID = new Random().nextInt(255);
@@ -217,10 +195,10 @@ public class generatorView extends ConstraintLayout {
try {
// alert("test", ""+Math.ceil((double)data.length()/(double)qrSize));
qrBitmaps.add(generateQrCode(
String.valueOf(fileEditor.byteToChar(fileEditor.internalDataVersion)) +
fileEditor.byteToChar(fileEditor.internalDataVersion) +
String.valueOf(fileEditor.byteToChar(randID)) +
String.valueOf(fileEditor.byteToChar(i)) +
String.valueOf(fileEditor.byteToChar(qrCount-1)) +
fileEditor.byteToChar(i) +
fileEditor.byteToChar(qrCount - 1) +
data.substring(start, end)
));
// alert("title", ""+(qrCount-1));
@@ -11,6 +11,8 @@ import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;
public class qrOverlayView extends View {
PointF[] points;
@@ -50,7 +52,7 @@ public class qrOverlayView extends View {
}
@Override
public void draw(Canvas canvas) {
public void draw(@NonNull Canvas canvas) {
super.draw(canvas);
if (points != null) {
for (PointF pointF : points) {
@@ -58,11 +60,10 @@ public class qrOverlayView extends View {
}
}
if(barColors != null){
final int width = (int)(getWidth()/barColors.length);
final int width = getWidth()/barColors.length;
final int top = 0;
final int bottom = barHeight;
final int margin = 5*(int)((double)width/getWidth());
for(int i=0;i<barColors.length;i++){
@@ -7,7 +7,6 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.media.Image;
import android.os.Handler;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Surface;
@@ -29,9 +28,7 @@ import androidx.lifecycle.LifecycleOwner;
import com.astatin3.scoutingapp2025.databinding.FragmentTransferBinding;
import com.astatin3.scoutingapp2025.fileEditor;
import com.astatin3.scoutingapp2025.qrScanTask;
import com.dlazaro66.qrcodereaderview.QRCodeReaderView;
import com.google.common.util.concurrent.ListenableFuture;
import java.nio.ByteBuffer;
@@ -40,38 +37,12 @@ import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.zip.DataFormatException;
//public class scannerView extends androidx.appcompat.widget.AppCompatImageView {
public class scannerView extends ConstraintLayout {
// public static class fixedQRCodeReaderView extends QRCodeReaderView {
// public fixedQRCodeReaderView(Context context) {
// super(context, null);
// }
// }
private QRCodeReaderView qrCodeReaderView;
private qrOverlayView qrOverlayView;
private Handler uiHandler;
private ScriptIntrinsicYuvToRGB script;
// private class codeReadListener implements QRCodeReaderView.OnQRCodeReadListener {
// @Override
// public void onQRCodeRead(String text, PointF[] points) {
// qrOverlayView.setPoints(points);
//
//// alert("Info", ""+(fileEditor.byteFromChar(text.charAt(3))+1));
//
// compileData(
// fileEditor.byteFromChar(text.charAt(0)),
// fileEditor.byteFromChar(text.charAt(1)),
// fileEditor.byteFromChar(text.charAt(2)),
// (fileEditor.byteFromChar(text.charAt(3))+1),
// text.substring(4)
// );
// }
// }
private void alert(String title, String content) {
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
@@ -99,8 +70,6 @@ public class scannerView extends ConstraintLayout {
scale = ((float) getWidth() / bmp.getWidth()) * ((float) 16 / 9);
binding.scannerImage.setTranslationX(0);
binding.scannerImage.setTranslationY(0);
// binding.scannerImage.setScaleX(scale);
// binding.scannerImage.setScaleY(scale);
}
scanQRCode(bmp);
binding.scannerImage.setImageBitmap(bmp);
@@ -130,16 +99,8 @@ public class scannerView extends ConstraintLayout {
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// int L = levelMap[clamp((yBuffer.get() & 0xff) - thresholdOffset, 0, 255)];
// int L = clamp(levelMap[yBuffer.get() & 0xff]-thresholdOffset, 0, 255);
int L = levelMap[yBuffer.get() & 0xff];
pixels[y * width + x] = 0xff000000 | (L << 16) | (L << 8) | L;
// if(L > threshold) {
// pixels[y * width + x] = 0xffffffff;
// }else{
// pixels[y * width + x] = 0xff000000;
// }
// pixels[y * width + x] = levelMap[L];
}
}
@@ -152,21 +113,18 @@ public class scannerView extends ConstraintLayout {
qrScanTask async = new qrScanTask();
async.setImage(bitmap);
async.onResult(new Function<String, String>() {
@Override
public String apply(String data) {
if(data != null){
async.onResult(data -> {
if(data != null){
// alert("test", ""+fileEditor.byteFromChar(data.charAt(0)));
compileData(
fileEditor.byteFromChar(data.charAt(0)),
fileEditor.byteFromChar(data.charAt(1)),
fileEditor.byteFromChar(data.charAt(2)),
(fileEditor.byteFromChar(data.charAt(3))+1),
data.substring(4)
);
}
return null;
compileData(
fileEditor.byteFromChar(data.charAt(0)),
fileEditor.byteFromChar(data.charAt(1)),
fileEditor.byteFromChar(data.charAt(2)),
(fileEditor.byteFromChar(data.charAt(3))+1),
data.substring(4)
);
}
return null;
});
async.execute();
@@ -242,16 +200,13 @@ public class scannerView extends ConstraintLayout {
ListenableFuture<ProcessCameraProvider> cameraProviderFuture
= ProcessCameraProvider.getInstance(this.getContext());
cameraProviderFuture.addListener(new Runnable() {
@Override
public void run() {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
bindPreview(cameraProvider);
} catch (ExecutionException | InterruptedException e) {
// No errors need to be handled for this Future.
// This should never be reached.
}
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
bindPreview(cameraProvider);
} catch (ExecutionException | InterruptedException e) {
// No errors need to be handled for this Future.
// This should never be reached.
}
}, ContextCompat.getMainExecutor(this.getContext()));
}
@@ -282,25 +237,22 @@ public class scannerView extends ConstraintLayout {
@OptIn(markerClass = ExperimentalGetImage.class) @Override
public void analyze(@NonNull ImageProxy image) {
Image img = Objects.requireNonNull(image.getImage());
// Log.i("test", img.getWidth() + ", " + img.getHeight());
// final Bitmap bmp = yuvConvertor.toBitmap(img);
if(img != null) {
uiHandler.post(new Runnable() {
Bitmap bmp = toGreyscale(img);
@Override
public void run() {
uiHandler.post(new Runnable() {
final Bitmap bmp = toGreyscale(img);
@Override
public void run() {
// setImage(toGreyscale(bmp));
setImage(bmp);
}
});
}
setImage(bmp);
}
});
image.close();
}
});
cameraProvider.unbindAll();
Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)lifecycle,
cameraProvider.bindToLifecycle(lifecycle,
cameraSelector, imageAnalysis, preview);
// preview.setSurfaceProvider(binding.previewView.getSurfaceProvider());
@@ -350,8 +302,6 @@ public class scannerView extends ConstraintLayout {
try {
byte[] compiledBytes = compiledString.getBytes(StandardCharsets.ISO_8859_1);
// alert(count+", "+compiledData.length()+", "+compiledBytes.length, ""+fileEditor.fromBytes(fileEditor.getByteBlock(compiledBytes, 0,2),2));
// alert("completed", new String(fileEditor.decompress(compiledBytes), StandardCharsets.ISO_8859_1));
alert("completed", blockUncompress(compiledBytes));
}catch (Exception e){
e.printStackTrace();
+13
View File
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M18,12V17C18,18.657 15.314,20 12,20C8.686,20 6,18.657 6,17V12M18,12V7M18,12C18,13.657 15.314,15 12,15C8.686,15 6,13.657 6,12M18,7C18,5.343 15.314,4 12,4C8.686,4 6,5.343 6,7M18,7C18,8.657 15.314,10 12,10C8.686,10 6,8.657 6,7M6,12V7"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</vector>
+13
View File
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M7,14H12.5M7,10H17M10,19H6.2C5.08,19 4.52,19 4.092,18.782C3.716,18.59 3.41,18.284 3.218,17.908C3,17.48 3,16.92 3,15.8V8.2C3,7.08 3,6.52 3.218,6.092C3.41,5.716 3.716,5.41 4.092,5.218C4.52,5 5.08,5 6.2,5H17.8C18.92,5 19.48,5 19.908,5.218C20.284,5.41 20.59,5.716 20.782,6.092C21,6.52 21,7.08 21,8.2V8.5M14,20L16.025,19.595C16.201,19.56 16.29,19.542 16.372,19.51C16.445,19.481 16.515,19.444 16.579,19.399C16.652,19.348 16.715,19.285 16.843,19.157L21,15C21.552,14.448 21.552,13.552 21,13C20.448,12.448 19.552,12.448 19,13L14.843,17.157C14.715,17.285 14.652,17.348 14.601,17.421C14.556,17.485 14.519,17.555 14.49,17.628C14.458,17.71 14.44,17.799 14.405,17.975L14,20Z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</vector>
+12
View File
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="30"
android:viewportHeight="30">
<path
android:pathData="M27.52,21.134L26.528,22.866C26.254,23.345 25.648,23.508 25.173,23.232L22.418,21.628C21.02,23.219 19.129,24.359 16.983,24.799L16.983,27C16.983,27.553 16.54,28 15.992,28L14.008,28C13.46,28 13.017,27.553 13.017,27L13.017,24.799C10.871,24.359 8.98,23.219 7.582,21.628L4.827,23.232C4.352,23.508 3.746,23.345 3.472,22.866L2.48,21.134C2.206,20.656 2.369,20.044 2.843,19.769L5.609,18.157C5.28,17.163 5.083,16.106 5.083,15C5.083,13.894 5.28,12.838 5.609,11.843L2.843,10.232C2.369,9.956 2.206,9.345 2.48,8.866L3.472,7.134C3.746,6.656 4.352,6.492 4.827,6.768L7.582,8.372C8.98,6.781 10.871,5.641 13.017,5.201L13.017,3C13.017,2.447 13.46,2 14.008,2L15.992,2C16.54,2 16.983,2.447 16.983,3L16.983,5.201C19.129,5.641 21.02,6.781 22.418,8.372L25.173,6.768C25.648,6.492 26.254,6.656 26.528,7.134L27.52,8.866C27.794,9.345 27.631,9.956 27.157,10.232L24.391,11.843C24.72,12.838 24.917,13.894 24.917,15C24.917,16.106 24.72,17.163 24.391,18.157L27.157,19.769C27.631,20.044 27.794,20.656 27.52,21.134L27.52,21.134ZM29.008,18.536L26.685,17.184C26.815,16.474 26.901,15.749 26.901,15C26.901,14.252 26.815,13.526 26.685,12.816L29.008,11.464C29.957,10.912 30.281,9.688 29.733,8.732L27.75,5.268C27.203,4.312 25.989,3.983 25.041,4.536L22.694,5.901C21.598,4.961 20.352,4.192 18.967,3.697L18.967,2C18.967,0.896 18.079,0 16.983,0L13.017,0C11.921,0 11.033,0.896 11.033,2L11.033,3.697C9.648,4.192 8.402,4.961 7.306,5.901L4.959,4.536C4.011,3.983 2.797,4.312 2.25,5.268L0.267,8.732C-0.281,9.688 0.044,10.912 0.992,11.464L3.315,12.816C3.185,13.526 3.099,14.252 3.099,15C3.099,15.749 3.185,16.474 3.315,17.184L0.992,18.536C0.044,19.088 -0.281,20.312 0.267,21.268L2.25,24.732C2.797,25.688 4.011,26.017 4.959,25.464L7.306,24.099C8.402,25.039 9.648,25.809 11.033,26.303L11.033,28C11.033,29.104 11.921,30 13.017,30L16.983,30C18.079,30 18.967,29.104 18.967,28L18.967,26.303C20.352,25.809 21.598,25.039 22.694,24.099L25.041,25.464C25.989,26.017 27.203,25.688 27.75,24.732L29.733,21.268C30.281,20.312 29.957,19.088 29.008,18.536L29.008,18.536ZM15,18C13.357,18 12.025,16.657 12.025,15C12.025,13.344 13.357,12 15,12C16.643,12 17.975,13.344 17.975,15C17.975,16.657 16.643,18 15,18L15,18ZM15,10C12.261,10 10.042,12.238 10.042,15C10.042,17.762 12.261,20 15,20C17.739,20 19.959,17.762 19.959,15C19.959,12.238 17.739,10 15,10L15,10Z"
android:strokeWidth="1"
android:fillColor="#000000"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -11,4 +11,10 @@
tools:context=".MainActivity">
<Spinner
android:id="@+id/eventDropdown"
android:layout_width="409dp"
android:layout_height="wrap_content"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="32dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.TBA.TBAFragment">
tools:context=".ui.Settings.Settings">
<ScrollView
android:id="@+id/ScrollArea"
+11 -8
View File
@@ -10,6 +10,7 @@
android:id="@+id/selectLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
tools:visibility="gone">
<Button
@@ -137,7 +138,7 @@
android:visibility="gone"
app:layout_constraintTop_toBottomOf="parent"
tools:layout_editor_absoluteX="-62dp"
tools:visibility="visible">
tools:visibility="gone">
<SeekBar
@@ -145,25 +146,25 @@
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="15dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<SeekBar
android:id="@+id/scannerThreshold"
android:layout_width="match_parent"
android:layout_height="48dp"
app:layout_constraintTop_toBottomOf="@id/scannerColors"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/scannerColors" />
<SeekBar
android:id="@+id/scannerBrightness"
android:layout_width="match_parent"
android:layout_height="48dp"
app:layout_constraintTop_toBottomOf="@id/scannerThreshold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/scannerThreshold" />
<TextView
android:id="@+id/scannerColorsLabel"
@@ -220,12 +221,14 @@
android:id="@+id/TBAView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="60dp"
android:fillViewport="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="gone">
tools:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
+11 -8
View File
@@ -2,16 +2,19 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
android:id="@+id/navigation_scouting"
android:icon="@drawable/scouting"
android:title="@string/title_scouting" />
<item
android:id="@+id/navigation_notifications"
android:id="@+id/navigation_data"
android:icon="@drawable/data"
android:title="@string/title_data" />
<item
android:id="@+id/navigation_transfer"
android:icon="@drawable/transfer_icon"
android:title="@string/title_transfer" />
<item
android:id="@+id/navigation_tba"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_tba" />
android:id="@+id/navigation_settings"
android:icon="@drawable/settings"
android:title="@string/title_settings" />
</menu>
@@ -3,40 +3,33 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_home">
app:startDestination="@+id/navigation_scouting">
<fragment
android:id="@+id/navigation_home"
android:name="com.astatin3.scoutingapp2025.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" >
<action
android:id="@+id/action_navigation_home_to_navigation_tba"
app:destination="@id/navigation_tba" />
<action
android:id="@+id/action_navigation_home_to_navigation_notifications"
app:destination="@id/navigation_notifications" />
<action
android:id="@+id/action_navigation_home_to_navigation_dashboard2"
app:destination="@id/navigation_tba" />
android:id="@+id/navigation_scouting"
android:name="com.astatin3.scoutingapp2025.ui.scouting.scoutingFragment"
android:label="@string/title_scouting"
tools:layout="@layout/fragment_scouting" >
</fragment>
<fragment
android:id="@+id/navigation_tba"
android:name="com.astatin3.scoutingapp2025.ui.TBA.TBAFragment"
android:label="@string/title_tba"
tools:layout="@layout/fragment_tba" >
<action
android:id="@+id/action_navigation_dashboard_to_navigation_notifications"
app:destination="@id/navigation_notifications" />
<action
android:id="@+id/action_navigation_dashboard_to_navigation_home"
app:destination="@id/navigation_home" />
android:id="@+id/navigation_data"
android:name="com.astatin3.scoutingapp2025.ui.scouting.dataFragment"
android:label="@string/title_data"
tools:layout="@layout/fragment_data" >
</fragment>
<fragment
android:id="@+id/navigation_notifications"
android:id="@+id/navigation_settings"
android:name="com.astatin3.scoutingapp2025.ui.Settings.Settings"
android:label="@string/title_settings"
tools:layout="@layout/fragment_settings" >
</fragment>
<fragment
android:id="@+id/navigation_transfer"
android:name="com.astatin3.scoutingapp2025.ui.transfer.TransferFragment"
android:label="@string/title_transfer"
tools:layout="@layout/fragment_transfer" />
</navigation>
+3 -2
View File
@@ -1,6 +1,7 @@
<resources>
<string name="app_name">ScoutingApp2025</string>
<string name="title_home">Home</string>
<string name="title_scouting">Scouting</string>
<string name="title_data">Data</string>
<string name="title_transfer">Transfer</string>
<string name="title_tba">TBA</string>
<string name="title_settings">Settings</string>
</resources>