mirror of
https://github.com/Team4388/RidgeScout.git
synced 2026-06-09 00:37:59 -06:00
Attempt to get F-Droid working
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
public class AlertManager {
|
||||
public 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) {
|
||||
e.printStackTrace();
|
||||
((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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
public class AutoSaveManager {
|
||||
private static final long AUTO_SAVE_DELAY = 2000; // 2 seconds
|
||||
|
||||
private final Handler handler;
|
||||
private final Runnable autoSaveRunnable;
|
||||
private boolean isAutoSaveScheduled = false;
|
||||
private final AutoSaveFunction autoSaveFunction;
|
||||
public boolean isRunning = false;
|
||||
|
||||
// Functional interface for the auto-save function
|
||||
@FunctionalInterface
|
||||
public interface AutoSaveFunction {
|
||||
void save();
|
||||
}
|
||||
|
||||
public AutoSaveManager(AutoSaveFunction autoSaveFunction) {
|
||||
this.autoSaveFunction = autoSaveFunction;
|
||||
handler = new Handler(Looper.getMainLooper());
|
||||
autoSaveRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
performAutoSave();
|
||||
isAutoSaveScheduled = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void start() {
|
||||
isRunning = true;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
isRunning = false;
|
||||
handler.removeCallbacks(autoSaveRunnable);
|
||||
isAutoSaveScheduled = false;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (!isRunning) {
|
||||
return; // Don't schedule auto-saves when not running
|
||||
}
|
||||
|
||||
// Cancel any previously scheduled auto-save
|
||||
handler.removeCallbacks(autoSaveRunnable);
|
||||
|
||||
// Schedule a new auto-save
|
||||
handler.postDelayed(autoSaveRunnable, AUTO_SAVE_DELAY);
|
||||
isAutoSaveScheduled = true;
|
||||
}
|
||||
|
||||
private void performAutoSave() {
|
||||
if (isRunning) {
|
||||
// Call the provided auto-save function
|
||||
autoSaveFunction.save();
|
||||
}
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
// Remove any pending auto-save tasks when the activity or fragment is destroyed
|
||||
stop();
|
||||
}
|
||||
|
||||
public boolean isAutoSaveScheduled() {
|
||||
return isAutoSaveScheduled;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return isRunning;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class BuiltByteParser {
|
||||
public static final Integer boolType = 0;
|
||||
public static final Integer intType = 1;
|
||||
public static final Integer stringType = 2;
|
||||
public static final Integer intArrayType = 3;
|
||||
public static final Integer stringArrayType = 4;
|
||||
|
||||
public class byteParsingExeption extends Exception {
|
||||
public byteParsingExeption() {}
|
||||
public byteParsingExeption(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static String unBlankStrNull(String str){
|
||||
if(str.equals("ƒ")){
|
||||
return "";
|
||||
}
|
||||
else return str;
|
||||
}
|
||||
|
||||
public abstract class parsedObject {
|
||||
public abstract Integer getType();
|
||||
public abstract Object get();
|
||||
}
|
||||
|
||||
public class boolObject extends parsedObject{
|
||||
boolean val;
|
||||
public Integer getType(){return boolType;}
|
||||
public Object get(){return val;}
|
||||
}
|
||||
|
||||
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 intArrayObject extends parsedObject{
|
||||
int[] arr;
|
||||
public Integer getType(){return intArrayType;}
|
||||
public Object get(){return arr;}
|
||||
}
|
||||
public class stringArrayObject extends parsedObject{
|
||||
String[] arr;
|
||||
public Integer getType(){return stringArrayType;}
|
||||
public Object get(){return arr;}
|
||||
}
|
||||
|
||||
|
||||
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:
|
||||
boolObject bo = new boolObject();
|
||||
bo.val = block[0] == (byte) 1;
|
||||
objects.add(bo);
|
||||
break;
|
||||
case 1:
|
||||
intObject io = new intObject();
|
||||
io.num = fileEditor.fromBytes(block, length);
|
||||
objects.add(io);
|
||||
break;
|
||||
case 2:
|
||||
stringObject so = new stringObject();
|
||||
so.str = unBlankStrNull(new String(block, StandardCharsets.UTF_8));
|
||||
objects.add(so);
|
||||
break;
|
||||
case 3:
|
||||
BuiltByteParser int_bbp = new BuiltByteParser(block);
|
||||
ArrayList<parsedObject> intArrayObjects = int_bbp.parse();
|
||||
|
||||
int[] intArr = new int[intArrayObjects.size()];
|
||||
|
||||
for(int i = 0; i < intArrayObjects.size(); i ++){
|
||||
intArr[i] = (int) intArrayObjects.get(i).get();
|
||||
}
|
||||
|
||||
intArrayObject ia = new intArrayObject();
|
||||
ia.arr = intArr;
|
||||
objects.add(ia);
|
||||
break;
|
||||
case 4:
|
||||
|
||||
BuiltByteParser str_bbp = new BuiltByteParser(block);
|
||||
ArrayList<parsedObject> strArrayObjects = str_bbp.parse();
|
||||
|
||||
String[] StringArr = new String[strArrayObjects.size()];
|
||||
|
||||
for(int i = 0; i < strArrayObjects.size(); i ++){
|
||||
StringArr[i] = (String) strArrayObjects.get(i).get();
|
||||
}
|
||||
|
||||
stringArrayObject sa = new stringArrayObject();
|
||||
sa.arr = StringArr;
|
||||
objects.add(sa);
|
||||
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,214 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ByteBuilder {
|
||||
public static final int bool_id = 0;
|
||||
public static final int int_id = 1;
|
||||
public static final int string_id = 2;
|
||||
public static final int int_arr_id = 3;
|
||||
public static final int string_arr_id = 4;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public static String blankStrNull(String str){
|
||||
if(str.isEmpty() || str.isEmpty()){
|
||||
return "ƒ";
|
||||
}
|
||||
else return str;
|
||||
}
|
||||
|
||||
private class boolType extends byteType {
|
||||
public boolean val;
|
||||
public byte getType(){return bool_id;}
|
||||
public int length(){return 1;}
|
||||
public byte[] build(){
|
||||
return new byte[]{(byte) (val ? 1 : 0)};
|
||||
}
|
||||
}
|
||||
|
||||
public ByteBuilder addBool(boolean n) throws buildingException {
|
||||
boolType boolType = new boolType();
|
||||
boolType.val = n;
|
||||
|
||||
bytesToBuild.add(boolType);
|
||||
return this;
|
||||
}
|
||||
|
||||
private class intType extends byteType {
|
||||
public int precision;
|
||||
public int num;
|
||||
public byte getType(){return int_id;}
|
||||
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 string_id;}
|
||||
public int length(){return bytes.length;}
|
||||
public byte[] build(){
|
||||
return bytes;
|
||||
// return str.getBytes(charset);
|
||||
}
|
||||
}
|
||||
public ByteBuilder addString(String str) throws buildingException {
|
||||
str = blankStrNull(str);
|
||||
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 intArrayType extends byteType {
|
||||
public byte[] bytes;
|
||||
public byte getType(){return int_arr_id;}
|
||||
public int length(){return bytes.length;}
|
||||
public byte[] build(){
|
||||
return bytes;
|
||||
// return str.getBytes(charset);
|
||||
}
|
||||
}
|
||||
public ByteBuilder addIntArray(int[] arr) throws buildingException {
|
||||
intArrayType intArrayType = new intArrayType();
|
||||
|
||||
ByteBuilder bb = new ByteBuilder();
|
||||
|
||||
for(int i = 0; i < arr.length; i++){
|
||||
bb.addInt(arr[i]);
|
||||
}
|
||||
|
||||
intArrayType.bytes = bb.build();
|
||||
|
||||
bytesToBuild.add(intArrayType);
|
||||
return this;
|
||||
}
|
||||
|
||||
private class stringArrayType extends byteType {
|
||||
public byte[] bytes;
|
||||
public byte getType(){return string_arr_id;}
|
||||
public int length(){return bytes.length;}
|
||||
public byte[] build(){
|
||||
return bytes;
|
||||
// return str.getBytes(charset);
|
||||
}
|
||||
}
|
||||
public ByteBuilder addStringArray(String[] arr) throws buildingException {
|
||||
stringArrayType stringArrayType = new stringArrayType();
|
||||
|
||||
ByteBuilder bb = new ByteBuilder();
|
||||
|
||||
for(int i = 0; i < arr.length; i++){
|
||||
bb.addString(arr[i]);
|
||||
}
|
||||
|
||||
stringArrayType.bytes = bb.build();
|
||||
|
||||
bytesToBuild.add(stringArrayType);
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import com.ridgebotics.ridgescout.SettingsVersionStack.latestSettings;
|
||||
import com.ridgebotics.ridgescout.scoutingData.fields;
|
||||
import com.ridgebotics.ridgescout.scoutingData.transfer.transferType;
|
||||
import com.ridgebotics.ridgescout.types.frcEvent;
|
||||
import com.ridgebotics.ridgescout.types.input.inputType;
|
||||
|
||||
public class DataManager {
|
||||
public static String evcode;
|
||||
public static frcEvent event;
|
||||
public static void reload_event(){
|
||||
evcode = getevcode();
|
||||
event = frcEvent.decode(fileEditor.readFile(evcode + ".eventdata"));
|
||||
}
|
||||
|
||||
public static String getevcode() {
|
||||
return latestSettings.settings.get_evcode();
|
||||
}
|
||||
|
||||
public static inputType[][] match_values;
|
||||
public static inputType[] match_latest_values;
|
||||
public static transferType[][] match_transferValues;
|
||||
public static void reload_match_fields(){
|
||||
match_values = fields.load(fields.matchFieldsFilename);
|
||||
match_latest_values = match_values[match_values.length-1];
|
||||
match_transferValues = transferType.get_transfer_values(match_values);
|
||||
}
|
||||
|
||||
public static inputType[][] pit_values;
|
||||
public static inputType[] pit_latest_values;
|
||||
public static transferType[][] pit_transferValues;
|
||||
public static void reload_pit_fields(){
|
||||
pit_values = fields.load(fields.pitsFieldsFilename);
|
||||
pit_latest_values = pit_values[pit_values.length-1];
|
||||
pit_transferValues = transferType.get_transfer_values(pit_values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class JSONUtil {
|
||||
public static JSONArray sort(JSONArray array, Comparator c){
|
||||
List asList = new ArrayList(array.length());
|
||||
for (int i=0; i<array.length(); i++){
|
||||
asList.add(array.opt(i));
|
||||
}
|
||||
asList.sort(c);
|
||||
JSONArray res = new JSONArray();
|
||||
for (Object o : asList){
|
||||
res.put(o);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.TableLayout;
|
||||
|
||||
public class ReorderableTableLayout extends TableLayout {
|
||||
private boolean reorderingEnabled = false;
|
||||
private int draggedRowIndex = -1;
|
||||
private float lastY;
|
||||
private List<View> rows;
|
||||
private List<Integer> reorderedIndices;
|
||||
private int rowHeight;
|
||||
|
||||
public ReorderableTableLayout(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ReorderableTableLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
rows = new ArrayList<>();
|
||||
reorderedIndices = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (!reorderingEnabled) {
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
lastY = ev.getY();
|
||||
draggedRowIndex = getRowIndexAtY(lastY);
|
||||
if (draggedRowIndex != -1) {
|
||||
View draggedRow = getChildAt(draggedRowIndex);
|
||||
rowHeight = draggedRow.getHeight();
|
||||
saveOriginalOrder();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child) {
|
||||
super.addView(child);
|
||||
reorderedIndices.add(reorderedIndices.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllViews() {
|
||||
super.removeAllViews();
|
||||
reorderedIndices.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (!reorderingEnabled || draggedRowIndex == -1) {
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
float currentY = event.getY();
|
||||
int targetIndex = getRowIndexAtY(currentY);
|
||||
View child = getChildAt(targetIndex);
|
||||
if(child != null)
|
||||
getChildAt(targetIndex).callOnClick();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (targetIndex != -1 && targetIndex != draggedRowIndex) {
|
||||
updateRowOrder(draggedRowIndex, targetIndex);
|
||||
draggedRowIndex = targetIndex;
|
||||
}
|
||||
lastY = currentY;
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
draggedRowIndex = -1;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getRowIndexAtY(float y) {
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
View child = getChildAt(i);
|
||||
if (y >= child.getTop() && y <= child.getBottom()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void saveOriginalOrder() {
|
||||
rows.clear();
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
rows.add(getChildAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
public void updateRowOrder(int fromIndex, int toIndex) {
|
||||
saveOriginalOrder();
|
||||
if (fromIndex < toIndex) {
|
||||
for (int i = fromIndex; i < toIndex; i++) {
|
||||
Collections.swap(rows, i, i + 1);
|
||||
Collections.swap(reorderedIndices, i, i + 1);
|
||||
}
|
||||
} else {
|
||||
for (int i = fromIndex; i > toIndex; i--) {
|
||||
Collections.swap(rows, i, i - 1);
|
||||
Collections.swap(reorderedIndices, i, i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
removeAllViewsInLayout();
|
||||
for (View view : rows) {
|
||||
addViewInLayout(view, -1, view.getLayoutParams(), true);
|
||||
}
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setReorderingEnabled(boolean enabled) {
|
||||
reorderingEnabled = enabled;
|
||||
}
|
||||
|
||||
public List<Integer> getReorderedIndexes() {
|
||||
return reorderedIndices;
|
||||
}
|
||||
|
||||
public void removeElement(int unshuffledindex){
|
||||
System.out.println(Arrays.toString(new List[]{reorderedIndices}));
|
||||
|
||||
reorderedIndices.remove(unshuffledindex);
|
||||
|
||||
for (int i = 0; i < reorderedIndices.size(); i++) {
|
||||
if(reorderedIndices.get(i) > unshuffledindex)
|
||||
reorderedIndices.set(i, reorderedIndices.get(i) - 1);
|
||||
}
|
||||
|
||||
System.out.println(Arrays.toString(new List[]{reorderedIndices}));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
public class RequestTask extends AsyncTask<String, String, String> {
|
||||
|
||||
private Function<String, String> resultFunction = null;
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... uri) {
|
||||
try {
|
||||
URL url = new URL(uri[0]);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
String[] headers = uri[1].split(", ");
|
||||
for(String header : headers){
|
||||
String[] split = header.split(": ");
|
||||
conn.setRequestProperty(split[0], split[1]);
|
||||
}
|
||||
if(conn.getResponseCode() == HttpsURLConnection.HTTP_OK){
|
||||
// ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
|
||||
return readStream(conn.getInputStream());
|
||||
// Do normal input or output stream reading
|
||||
}
|
||||
else {
|
||||
return null; // See documentation for more info on response handling
|
||||
}
|
||||
} catch (IOException e) {
|
||||
AlertManager.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static String readStream(InputStream in) {
|
||||
BufferedReader reader = null;
|
||||
StringBuilder response = new StringBuilder();
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(in));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
AlertManager.error(e);
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
AlertManager.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return response.toString();
|
||||
}
|
||||
|
||||
public void onResult(Function<String, String> func) {
|
||||
this.resultFunction = func;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
super.onPostExecute(result);
|
||||
if(resultFunction != null){
|
||||
resultFunction.apply(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.tensorflow.lite.support.label.Category;
|
||||
import org.tensorflow.lite.task.text.nlclassifier.NLClassifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SentimentAnalysis {
|
||||
private static NLClassifier textClassifier;
|
||||
|
||||
public static void init(Context context){
|
||||
try {
|
||||
textClassifier = NLClassifier.createFromFile(context, "text_classification_v2.tflite");
|
||||
} catch (Exception e) {
|
||||
AlertManager.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public interface resultCallback {
|
||||
public void onFinish(float data);
|
||||
}
|
||||
|
||||
public static void analyse(String input, resultCallback result){
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<Category> results = textClassifier.classify(input);
|
||||
|
||||
for(int i = 0; i < results.size(); i++){
|
||||
Category cat = results.get(i);
|
||||
switch (cat.getLabel()){
|
||||
case "Positive":
|
||||
result.onFinish(cat.getScore());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static float analyse_sync(String input){
|
||||
List<Category> results = textClassifier.classify(input);
|
||||
|
||||
for(int i = 0; i < results.size(); i++){
|
||||
Category cat = results.get(i);
|
||||
switch (cat.getLabel()){
|
||||
case "Positive":
|
||||
return cat.getScore();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ridgebotics.ridgescout.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,371 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.ridgebotics.ridgescout.types.frcEvent;
|
||||
import com.ridgebotics.ridgescout.types.frcTeam;
|
||||
|
||||
import com.ridgebotics.ridgescout.SettingsVersionStack.latestSettings;
|
||||
|
||||
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.nio.BufferOverflowException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
public final class fileEditor {
|
||||
private final static String baseDir = "/data/data/com.ridgebotics.ridgescout/";
|
||||
public static final byte internalDataVersion = 0x01;
|
||||
public static final int maxCompressedBlockSize = 4096;
|
||||
|
||||
|
||||
|
||||
public static String binaryVisualize(byte[] bytes){
|
||||
String returnStr = "";
|
||||
for (byte aByte : bytes) {
|
||||
for (int b = 7; b >= 0; b--) {
|
||||
returnStr += String.valueOf((aByte >> b) & 1);
|
||||
}
|
||||
returnStr += " (" + (int) aByte + ")\n";
|
||||
}
|
||||
return returnStr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static char byteToChar(int num){
|
||||
return new String(toBytes(num, 1), StandardCharsets.ISO_8859_1).charAt(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static byte[] toBytes(int num, int byteCount){
|
||||
if(num > (Math.pow(2,byteCount*8)-1)){
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
byte[] bytes = new byte[byteCount];
|
||||
for(int i=0;i<byteCount;i++){
|
||||
bytes[i] = (byte)(num >> (i*8));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int fromBytes(byte[] bytes, int byteCount){
|
||||
int returnInt = 0;
|
||||
for(int i=0;i<byteCount;i++){
|
||||
returnInt |= (bytes[i] & 0xFF) << (i*8);
|
||||
}
|
||||
return returnInt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int byteFromChar(char c){
|
||||
byte[] bytes = (String.valueOf(c)).getBytes(Charset.defaultCharset());
|
||||
return Byte.toUnsignedInt(bytes[0]);
|
||||
}
|
||||
|
||||
|
||||
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++){
|
||||
// Log.i("test", start+", "+a+", "+end);
|
||||
dataBlock[a-start] = bytes[a];
|
||||
}
|
||||
|
||||
return dataBlock;
|
||||
}
|
||||
|
||||
public static byte[] compress(byte[] input) {
|
||||
Deflater deflater = new Deflater();
|
||||
deflater.setInput(input);
|
||||
deflater.finish();
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[maxCompressedBlockSize];
|
||||
|
||||
while (!deflater.finished()) {
|
||||
int compressedSize = deflater.deflate(buffer);
|
||||
outputStream.write(buffer, 0, compressedSize);
|
||||
}
|
||||
|
||||
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();
|
||||
inflater.setInput(input);
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[maxCompressedBlockSize];
|
||||
|
||||
|
||||
while (inflater.getRemaining() > 0) {
|
||||
int decompressedSize = inflater.inflate(buffer);
|
||||
if (decompressedSize == 0) {
|
||||
break;
|
||||
}
|
||||
outputStream.write(buffer, 0, decompressedSize);
|
||||
}
|
||||
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
public static byte[] combineByteArrays(List<byte[]> arrayList) {
|
||||
// Calculate the total length of the combined array
|
||||
int totalLength = arrayList.stream()
|
||||
.mapToInt(array -> array.length)
|
||||
.sum();
|
||||
|
||||
// Create a new byte array with the total length
|
||||
byte[] result = new byte[totalLength];
|
||||
|
||||
// Copy each array into the result array
|
||||
int offset = 0;
|
||||
for (byte[] array : arrayList) {
|
||||
System.arraycopy(array, 0, result, offset, array.length);
|
||||
offset += array.length;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static boolean writeFile(String filepath, byte[] data) {
|
||||
try {
|
||||
FileOutputStream output = new FileOutputStream(baseDir + filepath);
|
||||
output.write(data);
|
||||
output.close();
|
||||
return true;
|
||||
}
|
||||
catch (IOException e) {
|
||||
AlertManager.error(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean createFile(String filepath){
|
||||
if(fileExist(filepath)){
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
File file = new File(baseDir + filepath);
|
||||
return file.createNewFile();
|
||||
}
|
||||
catch (IOException e) {
|
||||
AlertManager.error(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean fileExist(String path){
|
||||
File f = new File(baseDir + path);
|
||||
return f.exists() && !f.isDirectory();
|
||||
}
|
||||
|
||||
public static byte[] readFile(String 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 {
|
||||
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
|
||||
buf.read(bytes, 0, bytes.length);
|
||||
buf.close();
|
||||
return bytes;
|
||||
} catch (FileNotFoundException e) {
|
||||
AlertManager.error(e);
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
AlertManager.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String intSplit(int[] intArr, String splitStr){
|
||||
String returnStr = "";
|
||||
for(int i=0;i<intArr.length;i++){
|
||||
returnStr += String.valueOf(intArr[i]);
|
||||
if(i != intArr.length-1){
|
||||
returnStr += splitStr;
|
||||
}
|
||||
}
|
||||
return returnStr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static boolean setEvent(frcEvent event){
|
||||
final String filename = (event.eventCode + ".eventdata");
|
||||
|
||||
if(latestSettings.settings.get_evcode().equals("unset")){
|
||||
latestSettings.settings.set_evcode(event.eventCode);
|
||||
}
|
||||
|
||||
return writeFile(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().substring(0,file.getName().length()-10));
|
||||
}
|
||||
}
|
||||
Collections.sort(outFiles);
|
||||
return outFiles;
|
||||
}
|
||||
|
||||
|
||||
public static String[] getMatchesByTeamNum(String evcode, int teamNum){
|
||||
File f = new File(baseDir);
|
||||
File[] files = f.listFiles();
|
||||
|
||||
ArrayList<String> outFiles = new ArrayList<>();
|
||||
|
||||
if(files == null){return new String[0];}
|
||||
|
||||
for (File file : files) {
|
||||
String name = file.getName();
|
||||
if(!file.isDirectory() && name.startsWith(evcode+"-") && name.endsWith("-"+teamNum+".matchscoutdata")) {
|
||||
outFiles.add(file.getName());
|
||||
}
|
||||
}
|
||||
|
||||
String[] filenames = outFiles.toArray(new String[0]);
|
||||
|
||||
Arrays.sort(filenames, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return Integer.valueOf(o1.split("-")[1]).compareTo(Integer.valueOf(o2.split("-")[1]));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return filenames;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static String[] getEventFiles(String evcode){
|
||||
File f = new File(baseDir);
|
||||
File[] files = f.listFiles();
|
||||
|
||||
if(files == null){return new String[0];}
|
||||
|
||||
ArrayList<String> outFiles = new ArrayList<>();
|
||||
outFiles.add("matches.fields");
|
||||
outFiles.add("pits.fields");
|
||||
// outFiles.add(evcode + ".eventdata");
|
||||
|
||||
for (File file : files) {
|
||||
String name = file.getName();
|
||||
if(!file.isDirectory() && name.startsWith(evcode)) {
|
||||
outFiles.add(file.getName());
|
||||
}
|
||||
}
|
||||
|
||||
String[] filenames = outFiles.toArray(new String[0]);
|
||||
|
||||
Arrays.sort(filenames, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
if(!o1.contains("-") || !o2.contains("-"))
|
||||
return 0;
|
||||
return Integer.valueOf(o1.split("-")[1]).compareTo(Integer.valueOf(o2.split("-")[1]));
|
||||
} catch (Exception e){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return filenames;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static boolean setTeams(Context context, String key, ArrayList<frcTeam> teams){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user