I Still Don't Know Android

This commit is contained in:
Astatin3
2024-03-28 10:21:54 -06:00
parent 363470a275
commit 8913c7391d
13 changed files with 446 additions and 171 deletions
+2
View File
@@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
@@ -14,6 +14,7 @@ import com.astatin3.scoutingapp2025.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
@Override
@@ -27,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_dashboard, R.id.navigation_notifications)
R.id.navigation_home, R.id.navigation_notifications, R.id.navigation_tba)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
@@ -0,0 +1,80 @@
package com.astatin3.scoutingapp2025;
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.MalformedURLException;
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 (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static String readStream(InputStream in) {
BufferedReader reader = null;
StringBuffer response = new StringBuffer();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
response.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
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,24 @@
package com.astatin3.scoutingapp2025.ui;
import org.json.JSONArray;
import java.util.ArrayList;
import java.util.Collections;
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));
}
Collections.sort(asList, c);
JSONArray res = new JSONArray();
for (Object o : asList){
res.put(o);
}
return res;
}
}
@@ -0,0 +1,291 @@
package com.astatin3.scoutingapp2025.ui.TBA;
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.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
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.Collections;
import java.util.Comparator;
import java.util.function.Function;
import kotlin.io.LineReader;
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;
private android.widget.ScrollView ScrollArea;
private android.widget.TableLayout Table;
private void alert(String title, String content) {
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage(content);
alert.setTitle(title);
alert.setPositiveButton("OK", null);
alert.setCancelable(true);
alert.create().show();
}
// abstract class TBATask extends RequestTask {
// public static void run(String... uri){
// super.execute(uri);
// }
// private void response(String result){
// alert("data", result);
// }
// }
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
TBAViewModel dashboardViewModel =
new ViewModelProvider(this).get(TBAViewModel.class);
binding = FragmentTbaBinding.inflate(inflater, container, false);
View root = binding.getRoot();
ScrollArea = binding.ScrollArea;
Table = binding.matchTable;
warnPopup();
return root;
}
public void warnPopup() {
// alert("App Title", "This is an alert with no consequence");
//
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage("This is an alert with no consequence");
alert.setTitle("App Title");
alert.setCancelable(true);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final RequestTask rq = new RequestTask();
rq.onResult(new Function<String, String>() {
@Override
public String apply(String s) {
eventTable(s);
return null;
}
});
rq.execute(TBAAddress + "events/2024", TBAHeader);
}
});
alert.create().show();
}
private void addTableText(TableRow tr, String textStr){
TextView text = new TextView(getContext());
text.setTextSize(18);
text.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); // Text align center
text.setText(textStr);
tr.addView(text);
}
public void eventTable(String dataString){
try {
JSONArray data = new JSONArray(dataString);
Table.setStretchAllColumns(true);
Table.bringToFront();
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++){
tr = new TableRow(getContext());
if (toggle) {
tr.setBackgroundColor(0x30000000);
}
JSONObject j = data.getJSONObject(i);
Button button = new Button(getContext());
String matchKey = j.getString("key");
button.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
final RequestTask rq = new RequestTask();
rq.onResult(new Function<String, String>() {
@Override
public String apply(String s) {
matchTable(s);
return null;
}
});
rq.execute((TBAAddress + "event/" + matchKey + "/matches"), TBAHeader);
}
});
button.setText(matchKey);
tr.addView(button);
String name = j.getString("short_name");
// Sometimes, a short name is not present on TBA Events
if(name.isEmpty()){
name = j.getString("name");
}
addTableText(tr, name);
addTableText(tr, j.getString("event_type_string"));
// tr.addView(text);
Table.addView(tr);
toggle = !toggle;
}
}catch (JSONException j){
alert("Error", "Invalid JSON");
}
}
class matchComparator implements Comparator<JSONObject>
{
public int compare(JSONObject a, JSONObject b)
{
try {
return a.getInt("match_number") - b.getInt("match_number");
}catch (JSONException j){
return 0;
}
}
}
public void matchTable(String dataString){
try {
JSONArray data = new JSONArray(dataString);
Table.removeAllViews();
Table.setStretchAllColumns(true);
Table.bringToFront();
if(data.length() == 0){
TableRow tr = new TableRow(getContext());
addTableText(tr, "This event has no matches released yet...");
Table.addView(tr);
tr = new TableRow(getContext());
addTableText(tr, "Try manually adding practice matches.");
Table.addView(tr);
return;
}
TableRow tr = new TableRow(getContext());
addTableText(tr, "#");
addTableText(tr, "Red-1");
addTableText(tr, "Red-2");
addTableText(tr, "Red-3");
addTableText(tr, "Blue-1");
addTableText(tr, "Blue-2");
addTableText(tr, "Blue-3");
Table.addView(tr);
data = JSONUtil.sort(data, 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;
}
}
});
boolean toggle = false;
int matchCount = 1;
for(int a=0;a<data.length();a++){
final JSONObject match = data.getJSONObject(a);
if(!match.getString("comp_level").equals("qm")){
continue;
}
final JSONObject alliances = match.getJSONObject("alliances");
final JSONArray redAlliance = alliances.getJSONObject("red").getJSONArray("team_keys");
final JSONArray blueAlliance = alliances.getJSONObject("blue").getJSONArray("team_keys");
tr = new TableRow(getContext());
if (toggle) {
tr.setBackgroundColor(0x30000000);
}
addTableText(tr, String.valueOf(matchCount));
// addTableText(tr, match.getString("key"));
for(int b=0;b<6;b++){
TextView text = new TextView(getContext());
text.setTextSize(18);
text.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); // Text align center
tr.addView(text);
if(b < 3){
text.setText(redAlliance.getString(b).substring(3));
text.setBackgroundColor(0x50ff0000);
}else{
text.setText(blueAlliance.getString(b-3).substring(3));
text.setBackgroundColor(0x500000ff);
}
}
Table.addView(tr);
matchCount += 1;
toggle = !toggle;
}
}catch (JSONException j){
alert("Error", "Invalid JSON");
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
@@ -0,0 +1,20 @@
package com.astatin3.scoutingapp2025.ui.TBA;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class TBAViewModel extends ViewModel {
private final MutableLiveData<String> mText;
public TBAViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is dashboard fragment");
}
public LiveData<String> getText() {
return mText;
}
}
@@ -1,90 +0,0 @@
package com.astatin3.scoutingapp2025.ui.dashboard;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.astatin3.scoutingapp2025.R;
import com.astatin3.scoutingapp2025.databinding.FragmentDashboardBinding;
public class DashboardFragment extends Fragment {
private FragmentDashboardBinding binding;
private TableLayout Table;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
DashboardViewModel dashboardViewModel =
new ViewModelProvider(this).get(DashboardViewModel.class);
binding = FragmentDashboardBinding.inflate(inflater, container, false);
View root = binding.getRoot();
Table = binding.matchTable;
warnPopup();
return root;
}
public void warnPopup(){
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage("This is an alert with no consequence");
alert.setTitle("App Title");
alert.setPositiveButton("OK", null);
alert.setCancelable(false);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
showTableLayout();
}
});
alert.create().show();
}
public void showTableLayout(){
// Date date = new Date();
int rows = 200;
int columns = 10;
Table.setStretchAllColumns(true);
Table.bringToFront();
for(int i = 0; i < rows; i++){
TableRow tr = new TableRow(getContext());
Button button = new Button(getContext());
button.setText("test");
tr.addView(button);
TextView text = new TextView(getContext());
text.setTextSize(18);
text.setText("eee");
tr.addView(text);
Table.addView(tr);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
@@ -1,50 +0,0 @@
package com.astatin3.scoutingapp2025.ui.dashboard;
import android.graphics.Color;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.TableRow;
import android.widget.TextView;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class DashboardViewModel extends ViewModel {
// private class row {
// public row() {
//
// }
// }
private final MutableLiveData<String> mText;
public DashboardViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is dashboard fragment");
//
// final TextView row = new TextView(getContext());
//// setContentView()
//
// row.setLayoutParams(new
// TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
// TableRow.LayoutParams.WRAP_CONTENT));
//
//// TableLayout list = (TableLayout) this.findViewById(R.id.matchTable);
//// View list = inflater.inflate(inflater, container, findViewById(R.id.toastViewGroup));
//
//
// row.setGravity(Gravity.END);
// row.setTextSize(TypedValue.COMPLEX_UNIT_PX, 10);
// row.setPadding(5, 1, 0, 5);
// row.setTextColor(Color.parseColor("#aaaaaa"));
// row.setBackgroundColor(Color.parseColor("#f8f8f8"));
// row.setText("testing!!");
// .addView(row);
}
public LiveData<String> getText() {
return mText;
}
}
+1 -16
View File
@@ -4,19 +4,4 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<TextView
android:id="@+id/text_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
tools:context=".ui.home.HomeFragment"/>
@@ -4,12 +4,18 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.dashboard.DashboardFragment">
tools:context=".ui.TBA.TBAFragment">
<ScrollView
android:id="@+id/ScrollArea"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
android:layout_marginBottom="57dp"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
+4 -6
View File
@@ -6,14 +6,12 @@
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
<item
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_notifications" />
<item
android:id="@+id/navigation_tba"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
</menu>
@@ -11,21 +11,21 @@
android:label="@string/title_home"
tools:layout="@layout/fragment_home" >
<action
android:id="@+id/action_navigation_home_to_navigation_dashboard"
app:destination="@id/navigation_dashboard" />
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_dashboard" />
app:destination="@id/navigation_tba" />
</fragment>
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.astatin3.scoutingapp2025.ui.dashboard.DashboardFragment"
android:id="@+id/navigation_tba"
android:name="com.astatin3.scoutingapp2025.ui.TBA.TBAFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" >
tools:layout="@layout/fragment_tba" >
<action
android:id="@+id/action_navigation_dashboard_to_navigation_notifications"
app:destination="@id/navigation_notifications" />