Work on Data Transfer

This commit is contained in:
Astatin3
2024-03-29 17:37:05 -06:00
parent 8913c7391d
commit bd98af9baa
16 changed files with 324 additions and 109 deletions
+10
View File
@@ -2,6 +2,12 @@ plugins {
alias(libs.plugins.androidApplication)
}
//allprojects {
// repositories {
// maven ( url = "https://jitpack.io" )
// }
//}
android {
namespace = "com.astatin3.scoutingapp2025"
compileSdk = 34
@@ -40,7 +46,11 @@ dependencies {
implementation(libs.lifecycle.viewmodel.ktx)
implementation(libs.navigation.fragment)
implementation(libs.navigation.ui)
// implementation(libs.support.annotations)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
implementation("com.github.yuriy-budiyev:code-scanner:2.3.0")
implementation("com.github.kenglxn.QRGen:android:3.0.1")
}
+1
View File
@@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
@@ -61,8 +61,8 @@ public class TBAFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
TBAViewModel dashboardViewModel =
new ViewModelProvider(this).get(TBAViewModel.class);
// TBAViewModel dashboardViewModel =
// new ViewModelProvider(this).get(TBAViewModel.class);
binding = FragmentTbaBinding.inflate(inflater, container, false);
View root = binding.getRoot();
@@ -1,20 +0,0 @@
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,38 +1,202 @@
package com.astatin3.scoutingapp2025.ui.home;
import android.app.AlertDialog;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.astatin3.scoutingapp2025.databinding.FragmentHomeBinding;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
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.ByteBuffer;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.Map;
public class HomeFragment extends Fragment {
private FragmentHomeBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
HomeViewModel homeViewModel =
new ViewModelProvider(this).get(HomeViewModel.class);
private final int maxQrCount = 256; //The max number that can be stored in a byte
private final int maxQrSpeed = 20;
private final int minQrSpeed = 300;
private int minQrSize = 0;
private final int maxQrSize = 600;
private int qrSize = 100;
private int curCodeIndex = 0;
private int qrDelay = 100;
private int qrIndex = 0;
private int qrCount = 0;
private ArrayList<Bitmap> qrBitmaps = new ArrayList<Bitmap>();
private void alert(String title, String content) {
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setMessage(content);
alert.setTitle(title);
alert.setPositiveButton("OK", null);
alert.setCancelable(true);
alert.create().show();
}
public static Bitmap generateQrCode(String myCodeText) throws WriterException {
// Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
QRCodeWriter qrCodeWriter = new QRCodeWriter();
Map<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // H = 30% damage
hints.put(EncodeHintType.MARGIN, 0); /* default = 4 */
int size = 200;
BitMatrix bitMatrix = qrCodeWriter.encode(myCodeText, BarcodeFormat.QR_CODE, size, size, hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentHomeBinding.inflate(inflater, container, false);
View root = binding.getRoot();
final TextView textView = binding.textHome;
homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
binding.qrSpeedSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// qrDelay = progress + minQrSpeed;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
binding.qrSpeedSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
qrDelay = maxQrSpeed - progress + 1;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
sendData("Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism");
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
private void getQr(int index){
byte[] bytes = ByteBuffer.allocate(1).putInt(index).array();
// new byte;
}
private void sendData(String data){
minQrSize = Math.round(data.length()/maxQrCount);
binding.qrSizeSlider.setMax(maxQrSize);
binding.qrSpeedSlider.setMax(maxQrSpeed-minQrSpeed);
binding.qrSizeSlider.setProgress(qrSize-minQrSize);
binding.qrSpeedSlider.setProgress(qrDelay-minQrSpeed);
qrCount = (data.length()/qrSize);
// alert("ee", ""+ qrDelay + "\n" + minQrSpeed);
for(int i=0;i<=(data.length()/qrSize);i++){
final int start = i*qrSize;
int end = (i+1)*qrSize;
if(end > data.length()){
end = data.length()-1;
}
// alertstr += "\n" + start + ", " + end;
try {
qrBitmaps.add(generateQrCode(
data.substring(start, end)
));
}catch (WriterException e){
e.printStackTrace();
}
}
qrIndex = 0;
qrLoop();
}
private void updateQr(){
// alert("qr", ""+qrIndex);
binding.qrImage.setImageBitmap(qrBitmaps.get(qrIndex));
this.qrIndex += 1;
if(this.qrIndex >= this.qrCount+1){
this.qrIndex = 0;
}
}
private void qrLoop(){
new CountDownTimer(qrDelay, 1000) {
public void onTick(long millisUntilFinished) {}
public void onFinish() {
updateQr();
qrLoop();
}
}.start();
}
// private void setQR(int curIndex){
// binding.qrImage.setImageBitmap(qrBitmaps.get(curIndex));
// final Handler handler = new Handler();
// handler.postDelayed(new Runnable() {
// @Override
// public void run() {
// if(qrIndex+1 > qrCount){
// qrIndex = 0;
// }
// setQR(curIndex+1);
// }
// }, qrDelay);
//
//
// }
}
@@ -1,19 +0,0 @@
package com.astatin3.scoutingapp2025.ui.home;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class HomeViewModel extends ViewModel {
private final MutableLiveData<String> mText;
public HomeViewModel() {
mText = new MutableLiveData<>();
mText.setValue("Testttt");
}
public LiveData<String> getText() {
return mText;
}
}
@@ -1,37 +1,58 @@
package com.astatin3.scoutingapp2025.ui.notifications;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.astatin3.scoutingapp2025.databinding.FragmentNotificationsBinding;
import com.astatin3.scoutingapp2025.R;
import com.budiyev.android.codescanner.CodeScanner;
import com.budiyev.android.codescanner.CodeScannerView;
import com.budiyev.android.codescanner.DecodeCallback;
import com.budiyev.android.codescanner.ScanMode;
import com.google.zxing.Result;
public class NotificationsFragment extends Fragment {
private CodeScanner mCodeScanner;
private FragmentNotificationsBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
NotificationsViewModel notificationsViewModel =
new ViewModelProvider(this).get(NotificationsViewModel.class);
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();
}
binding = FragmentNotificationsBinding.inflate(inflater, container, false);
View root = binding.getRoot();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
final Activity activity = getActivity();
View root = inflater.inflate(R.layout.fragment_notifications, container, false);
final TextView textView = binding.textNotifications;
notificationsViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
CodeScannerView scannerView = root.findViewById(R.id.scanner_view);
mCodeScanner = new CodeScanner(activity, scannerView);
mCodeScanner.setScanMode(ScanMode.CONTINUOUS);
mCodeScanner.setDecodeCallback(new DecodeCallback() {
@Override
public void onDecoded(@NonNull final Result result) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
alert("QR", result.getText());
}
});
}
});
mCodeScanner.startPreview();
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
@@ -1,20 +0,0 @@
package com.astatin3.scoutingapp2025.ui.notifications;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class NotificationsViewModel extends ViewModel {
private final MutableLiveData<String> mText;
public NotificationsViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is notifications fragment");
}
public LiveData<String> getText() {
return mText;
}
}
+57 -1
View File
@@ -2,6 +2,62 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootDiv"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment"/>
android:alpha="255"
android:focusable="false"
android:focusableInTouchMode="false"
tools:context=".MainActivity">
<SeekBar
android:id="@+id/qrSizeSlider"
android:layout_width="412dp"
android:layout_height="48dp"
android:layout_marginStart="34dp"
android:layout_marginBottom="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.971"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/testImg"
app:layout_constraintVertical_bias="0.838" />
<SeekBar
android:id="@+id/qrSpeedSlider"
android:layout_width="412dp"
android:layout_height="48dp"
app:layout_constraintBottom_toTopOf="@+id/qrSizeSlider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/testImg"
app:layout_constraintVertical_bias="0.93" />
<ImageView
android:id="@+id/qrImage"
android:layout_width="300dp"
android:layout_height="300dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/qrSpeedText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="QR Speed"
app:layout_constraintBottom_toTopOf="@+id/qrSpeedSlider"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/qrSizeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="QR Size"
app:layout_constraintBottom_toTopOf="@+id/qrSizeSlider"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -6,17 +6,30 @@
android:layout_height="match_parent"
tools:context=".ui.notifications.NotificationsFragment">
<TextView
android:id="@+id/text_notifications"
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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>
android:layout_height="match_parent">
<com.budiyev.android.codescanner.CodeScannerView
android:id="@+id/scanner_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:autoFocusButtonColor="@android:color/white"
app:autoFocusButtonVisible="true"
app:flashButtonColor="@android:color/white"
app:flashButtonVisible="true"
app:frameColor="@android:color/white"
app:frameCornersSize="50dp"
app:frameCornersRadius="0dp"
app:frameAspectRatioWidth="1"
app:frameAspectRatioHeight="1"
app:frameSize="0.75"
app:frameThickness="2dp"
app:frameVerticalBias="0.5"
app:maskColor="#77000000"/>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+1 -1
View File
@@ -13,5 +13,5 @@
<item
android:id="@+id/navigation_tba"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
android:title="@string/title_tba" />
</menu>
@@ -24,7 +24,7 @@
<fragment
android:id="@+id/navigation_tba"
android:name="com.astatin3.scoutingapp2025.ui.TBA.TBAFragment"
android:label="@string/title_dashboard"
android:label="@string/title_tba"
tools:layout="@layout/fragment_tba" >
<action
android:id="@+id/action_navigation_dashboard_to_navigation_notifications"
+1 -1
View File
@@ -1,6 +1,6 @@
<resources>
<string name="app_name">ScoutingApp2025</string>
<string name="title_home">Home</string>
<string name="title_dashboard">Dashboard</string>
<string name="title_notifications">Notifications</string>
<string name="title_tba">TBA</string>
</resources>