diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d272599..5b82e4f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ android:name="android.hardware.camera" android:required="false" /> + isUserAuthenticated( - @Query("username") String username, - @Query("password") String password - ); + @GET("rest/uic/quality-control/get-quality-control-data") + Call isUserAuthenticated(); /*@POST("rest/application/save-truck-load") diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/apiservice/RetrofitClient.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/apiservice/RetrofitClient.java index 82a3ecf..b6efeb7 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/apiservice/RetrofitClient.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/apiservice/RetrofitClient.java @@ -11,7 +11,7 @@ import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitClient { - private final static String BASE_URL = "http://192.168.90.228:8080/cosmos/"; + private final static String BASE_URL = "http://192.168.91.44:8081/uind/"; private static Retrofit retrofit; diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/CheckingFragment.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/CheckingFragment.java index bfba586..e11cef8 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/CheckingFragment.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/CheckingFragment.java @@ -1,17 +1,37 @@ package com.utopiaindustries.qualitycontrol.fragments; +import android.Manifest; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.core.content.FileProvider; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import android.os.Environment; +import android.provider.MediaStore; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.ImageButton; +import android.widget.TextView; +import android.widget.Toast; import com.utopiaindustries.qualitycontrol.R; import com.utopiaindustries.qualitycontrol.activities.HomeActivity; @@ -19,14 +39,101 @@ import com.utopiaindustries.qualitycontrol.adapters.ImageAdapter; import com.utopiaindustries.qualitycontrol.adapters.ItemAdapter; import com.utopiaindustries.qualitycontrol.models.Item; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; -public class CheckingFragment extends Fragment { +import pub.devrel.easypermissions.AfterPermissionGranted; +import pub.devrel.easypermissions.AppSettingsDialog; +import pub.devrel.easypermissions.EasyPermissions; + +public class CheckingFragment extends Fragment implements EasyPermissions.PermissionCallbacks{ RecyclerView recyclerView, imageRecyclerView; ImageAdapter imageAdapter; + private static final int CAMERA_REQUEST = 101; + private static final int GALLERY_REQUEST = 201; + String filePath = "no_pic"; + ArrayList imageList = new ArrayList<>(); + Button nextButton; + ImageButton imagePicker, deleteImage; + + // Activity Result Launcher for Gallery + private final ActivityResultLauncher imagePickerLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result.getResultCode() == requireActivity().RESULT_OK && result.getData() != null) { + Uri selectedImage = result.getData().getData(); + if (selectedImage != null) { + //imageView.setImageURI(selectedImage); + Log.e("Selected-Image: ", "" + selectedImage); + + uriToByteArrayAsync( + getContext(), + selectedImage, + 100, // Target size in KB + compressedImage -> { + // Handle the compressed image here, e.g., display it + requireActivity().runOnUiThread(() -> { + //store.getReport().getItems().get(0).getCheckPoints().get(requestCode).addImageList(compressedImage); + imageList.add(compressedImage); + imageAdapter.notifyDataSetChanged(); + }); + }, + error -> { + // Handle any errors + requireActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), "Error compressing image: " + error.getMessage(), Toast.LENGTH_SHORT).show(); + }); + } + ); + } + } + }); + + // Activity Result Launcher for Camera + private final ActivityResultLauncher cameraLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + Uri contentUri = Uri.fromFile(new File((filePath))); + + uriToByteArrayAsync( + getContext(), + contentUri, + 100, // Target size in KB + compressedImage -> { + // Handle the compressed image here, e.g., display it + requireActivity().runOnUiThread(() -> { + //store.getReport().getItems().get(0).getCheckPoints().get(requestCode).addImageList(compressedImage); + imageList.add(compressedImage); + imageAdapter.notifyDataSetChanged(); + }); + }, + error -> { + // Handle any errors + requireActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), "Error compressing image: " + error.getMessage(), Toast.LENGTH_SHORT).show(); + }); + } + ); + + Log.e("contentUri: ", "" + contentUri); + if (result.getResultCode() == requireActivity().RESULT_OK && result.getData() != null) { + + Uri selectedImage = result.getData().getData(); + if (selectedImage != null) { + //imageView.setImageURI(selectedImage); + Log.e("Selected-Image: ", "" + selectedImage); + } + } + }); + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -48,13 +155,28 @@ public class CheckingFragment extends Fragment { recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(adapter); - Button nextButton = view.findViewById(R.id.btn_next); + imageAdapter = new ImageAdapter(imageList, getActivity()); + imageRecyclerView.setAdapter(imageAdapter); + nextButton.setOnClickListener(v -> { if (getActivity() instanceof HomeActivity) { ((HomeActivity) getActivity()).navigateToFragment(new PackingFragment(), true); } }); + imagePicker.setOnClickListener(v -> { + showAlertDialog(view); + }); + + deleteImage.setOnClickListener(v -> { + if (!imageList.isEmpty()) { + imageList.remove(imageList.size() - 1); + } else { + System.out.println("The list is empty"); + } + imageAdapter.notifyDataSetChanged(); + }); + return view; } @@ -65,8 +187,225 @@ public class CheckingFragment extends Fragment { private void initializeLayout(View view) { + imagePicker = view.findViewById(R.id.image_picker); + deleteImage = view.findViewById(R.id.delete_image); + nextButton = view.findViewById(R.id.btn_next); recyclerView = view.findViewById(R.id.recycler_view_checking); imageRecyclerView = view.findViewById(R.id.imageRecyclerView); imageRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false)); } + + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + // EasyPermissions handles the request result. + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { + new AppSettingsDialog.Builder(this).build().show(); + } + } + + public void showAlertDialog(View view) { + ViewGroup viewGroup = view.findViewById(android.R.id.content); + + TextView txt_camera, txt_gallery, txt_cancel; + + AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); + View view1 = LayoutInflater.from(getActivity()).inflate(R.layout.custom_layout, viewGroup, false); + builder.setCancelable(false); + builder.setView(view1); + + txt_camera = view1.findViewById(R.id.txt_camera); + txt_gallery = view1.findViewById(R.id.txt_gallery); + txt_cancel = view1.findViewById(R.id.txt_cancel); + + AlertDialog alertDialog = builder.create(); + Objects.requireNonNull(alertDialog.getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + + txt_camera.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + openCamera(); + } + }); + + txt_gallery.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + openGallery(); + } + }); + + txt_cancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + } + }); + + alertDialog.show(); + } + + public void uriToByteArrayAsync( + Context context, + Uri uri, + int targetSizeInKB, + Consumer onSuccess, + Consumer onError + ) { + new Thread(() -> { + try { + int targetSizeInBytes = targetSizeInKB * 1024; + + // Load the image as a Bitmap without scaling + Bitmap bitmap; + try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) { + bitmap = BitmapFactory.decodeStream(inputStream); + } + + if (bitmap == null) { + throw new IOException("Failed to decode image from URI."); + } + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + int minQuality = 10; + int maxQuality = 100; + int quality = maxQuality; + + // Binary search for the best quality that meets the target size + while (minQuality <= maxQuality) { + byteArrayOutputStream.reset(); + bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream); + + int byteSize = byteArrayOutputStream.size(); + if (byteSize > targetSizeInBytes) { + maxQuality = quality - 1; + } else { + minQuality = quality + 1; + } + quality = (minQuality + maxQuality) / 2; + } + + onSuccess.accept(byteArrayOutputStream.toByteArray()); + } catch (IOException e) { + onError.accept(e); + } + }).start(); + } + + private boolean hasGalleryPermission() { + String[] perms = {}; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + } + + return EasyPermissions.hasPermissions(requireActivity(), perms); + } + + private boolean hasCameraPermission() { + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + //Log.e("TIRAMISU: ","***"); + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.CAMERA}; + } else { + //Log.e("Not-TIRAMISU: ","***"); + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; + + } + + //Log.e("perms: ",""+perms); + return EasyPermissions.hasPermissions(requireActivity(), perms); + } + + private File createImageFile() throws IOException { + // Create an image file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + String imageFileName = "JPEG_" + timeStamp + "_"; + File storageDir = requireActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES); + File image = File.createTempFile( + imageFileName, /* prefix */ + ".jpg", /* suffix */ + storageDir /* directory */ + ); + + filePath = image.getAbsolutePath(); + return image; + } + + @AfterPermissionGranted(CAMERA_REQUEST) + public void openCamera() { + if (hasCameraPermission()) { + try { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + File photoFile = null; + try { + photoFile = createImageFile(); + } catch (IOException ex) { + // Error occurred while creating the File + } + + if (photoFile != null) { + Uri photoURI = FileProvider.getUriForFile(requireActivity(), + "com.utopiaindustries.qualitycontrol", + photoFile); + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); + //startActivityForResult(takePictureIntent, CAMERA_REQUEST); + cameraLauncher.launch(takePictureIntent); + } + } catch (ActivityNotFoundException e) { + Toast.makeText(getContext(), "Camera app not found", Toast.LENGTH_SHORT).show(); + } + } else { + // Ask for one permission + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.CAMERA}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; + } + + EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera), CAMERA_REQUEST, perms); + } + } + + @AfterPermissionGranted(GALLERY_REQUEST) + public void openGallery() { + if (hasGalleryPermission()) { + // Have permission, do the thing! + Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + // Start the Intent + //startActivityForResult(galleryIntent, GALLERY_REQUEST); + imagePickerLauncher.launch(galleryIntent); + } else { + // Ask for one permission + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + } + EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera), GALLERY_REQUEST, perms); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/CuttingFragment.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/CuttingFragment.java index af5a59b..8de2377 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/CuttingFragment.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/CuttingFragment.java @@ -3,6 +3,7 @@ package com.utopiaindustries.qualitycontrol.fragments; import static android.app.Activity.RESULT_OK; import android.Manifest; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; @@ -38,7 +39,10 @@ import com.utopiaindustries.qualitycontrol.R; import com.utopiaindustries.qualitycontrol.activities.HomeActivity; import com.utopiaindustries.qualitycontrol.adapters.ImageAdapter; import com.utopiaindustries.qualitycontrol.adapters.ItemAdapter; +import com.utopiaindustries.qualitycontrol.helper.Helper; import com.utopiaindustries.qualitycontrol.models.Item; +import com.utopiaindustries.qualitycontrol.models.QualityControlProcessStep; +import com.utopiaindustries.qualitycontrol.models.QualityControlResponse; import java.io.ByteArrayOutputStream; import java.io.File; @@ -54,9 +58,10 @@ import java.util.Objects; import java.util.function.Consumer; import pub.devrel.easypermissions.AfterPermissionGranted; +import pub.devrel.easypermissions.AppSettingsDialog; import pub.devrel.easypermissions.EasyPermissions; -public class CuttingFragment extends Fragment { +public class CuttingFragment extends Fragment implements EasyPermissions.PermissionCallbacks { RecyclerView recyclerView, imageRecyclerView; ImageAdapter imageAdapter; @@ -66,6 +71,8 @@ public class CuttingFragment extends Fragment { private static final int GALLERY_REQUEST = 200; String filePath = "no_pic"; ArrayList imageList = new ArrayList<>(); + ArrayList qualityControlProcessStepList = new ArrayList<>(); + QualityControlResponse qualityControlResponse; // Activity Result Launcher for Gallery private final ActivityResultLauncher imagePickerLauncher = @@ -169,7 +176,12 @@ public class CuttingFragment extends Fragment { }); deleteImage.setOnClickListener(v -> { - + if (!imageList.isEmpty()) { + imageList.remove(imageList.size() - 1); + } else { + System.out.println("The list is empty"); + } + imageAdapter.notifyDataSetChanged(); }); return view; @@ -183,6 +195,12 @@ public class CuttingFragment extends Fragment { recyclerView = view.findViewById(R.id.recycler_view_cutting); imageRecyclerView = view.findViewById(R.id.imageRecyclerView); imageRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false)); + + qualityControlResponse = Helper.getPreferenceObjectJson(getActivity().getApplicationContext(), "qcResponse"); + + if (!qualityControlResponse.getQualityControlProcessSteps().isEmpty()) { + qualityControlProcessStepList.addAll(qualityControlResponse.getQualityControlProcessSteps()); + } } @Override @@ -236,23 +254,18 @@ public class CuttingFragment extends Fragment { alertDialog.show(); } - @AfterPermissionGranted(GALLERY_REQUEST) + @AfterPermissionGranted(CAMERA_REQUEST) public void openCamera() { if (hasCameraPermission()) { - Log.e("hasCameraPermission: ", "true"); - // Have permission, do the thing! - Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - // Ensure that there's a camera activity to handle the intent - if (takePictureIntent.resolveActivity(requireActivity().getPackageManager()) != null) { - // Create the File where the photo should go + try { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File photoFile = null; try { photoFile = createImageFile(); } catch (IOException ex) { // Error occurred while creating the File - } - // Continue only if the File was successfully created + if (photoFile != null) { Uri photoURI = FileProvider.getUriForFile(requireActivity(), "com.utopiaindustries.qualitycontrol", @@ -261,25 +274,23 @@ public class CuttingFragment extends Fragment { //startActivityForResult(takePictureIntent, CAMERA_REQUEST); cameraLauncher.launch(takePictureIntent); } + } catch (ActivityNotFoundException e) { + Toast.makeText(getContext(), "Camera app not found", Toast.LENGTH_SHORT).show(); } } else { // Ask for one permission String[] perms = {}; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - Log.e("TIRAMISU: ", "***"); perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.CAMERA}; } else { - Log.e("Not-TIRAMISU: ", "***"); perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; - } - //Log.e("perms: ",""+perms.length); - EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera), CAMERA_REQUEST, perms); } } + @AfterPermissionGranted(GALLERY_REQUEST) public void openGallery() { if (hasGalleryPermission()) { // Have permission, do the thing! @@ -342,42 +353,6 @@ public class CuttingFragment extends Fragment { return image; } - /*public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (resultCode == RESULT_OK) { - - if (requestCode == GALLERY_REQUEST) { - Log.e("=====From Gallery", "========="); - Uri contentUri = data.getData(); - //filePath = Helper.getPath(contentUri, this); - *//*try { - //For Cropping purposes - String currentTimeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); - File destinationFile = new File(getCacheDir(), "croppedImage.png" + currentTimeStamp); - Uri destinationUri = Uri.fromFile(destinationFile); - - } catch (Exception e) { - Log.e("=====From Gallery error", "=========" + e.getMessage()); - e.printStackTrace(); - }*//* - - - } else if (requestCode == CAMERA_REQUEST) { - //Log.e("=====From Camera", "=========" + filePath); - - // rotatedBitmap = Helper.getBitmap(filePath); - - //For Cropping purposes - *//*String currentTimeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); - File destinationFile = new File(getCacheDir(), "croppedImage.png" + currentTimeStamp); - Uri destinationUri = Uri.fromFile(destinationFile); - Uri contentUri = Uri.fromFile(new File((filePath)));*//* - - } - } - - }*/ - public void uriToByteArrayAsync( Context context, Uri uri, @@ -424,4 +399,26 @@ public class CuttingFragment extends Fragment { } }).start(); } + + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + // EasyPermissions handles the request result. + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { + new AppSettingsDialog.Builder(this).build().show(); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/HomeFragment.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/HomeFragment.java index 53c836a..53b4af7 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/HomeFragment.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/HomeFragment.java @@ -1,10 +1,12 @@ package com.utopiaindustries.qualitycontrol.fragments; +import android.content.Intent; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; import android.util.Log; import android.view.LayoutInflater; @@ -14,11 +16,22 @@ import android.widget.AdapterView; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.TextView; +import android.widget.Toast; import com.utopiaindustries.qualitycontrol.R; import com.utopiaindustries.qualitycontrol.activities.HomeActivity; +import com.utopiaindustries.qualitycontrol.helper.Helper; +import com.utopiaindustries.qualitycontrol.helper.Preference; +import com.utopiaindustries.qualitycontrol.models.Department; +import com.utopiaindustries.qualitycontrol.models.LocationFloor; +import com.utopiaindustries.qualitycontrol.models.LocationSite; +import com.utopiaindustries.qualitycontrol.models.QualityControlProcess; +import com.utopiaindustries.qualitycontrol.models.QualityControlProcessStep; +import com.utopiaindustries.qualitycontrol.utils.ProgressDialogFragment; +import com.utopiaindustries.qualitycontrol.viewmodels.LoginViewModel; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; import java.util.Locale; @@ -26,6 +39,13 @@ public class HomeFragment extends Fragment { AutoCompleteTextView locationTextview, departmentTextView, floorTextview; TextView txtCurrentDate; + LoginViewModel loginViewModel; + + ArrayList locationFloorList = new ArrayList<>(); + ArrayList locationSiteList = new ArrayList<>(); + ArrayList departmentList = new ArrayList<>(); + ArrayList qualityControlProcessList = new ArrayList<>(); + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -87,5 +107,60 @@ public class HomeFragment extends Fragment { locationTextview = view.findViewById(R.id.location_textview); departmentTextView = view.findViewById(R.id.department_textview); floorTextview = view.findViewById(R.id.floor_textview); + + loginViewModel = new ViewModelProvider(getActivity()).get(LoginViewModel.class); + + loginViewModel.getLoadingState().observe(getActivity(), isLoading -> { + if (isLoading != null && isLoading) { + showProgressDialog(); + } else { + dismissProgressDialog(); + } + }); + + loginViewModel.getErrorMessage().observe(getActivity(), errorResponse -> { + Toast.makeText(getActivity(), errorResponse, Toast.LENGTH_SHORT).show(); + }); + + loginViewModel.getUserLiveData().observe(getActivity(), qcResponse -> { + if (qcResponse != null) { + + Helper.setPreferenceObject(getActivity().getApplicationContext(), qcResponse, "qcResponse"); + + if (!qcResponse.getLocationSites().isEmpty()) { + locationSiteList.addAll(qcResponse.getLocationSites()); + Log.e("locationSiteList-size: ",""+locationSiteList.size()); + } + + if (!qcResponse.getDepartments().isEmpty()) { + departmentList.addAll(qcResponse.getDepartments()); + Log.e("departmentList-size: ",""+departmentList.size()); + } + + if (!qcResponse.getLocationFloors().isEmpty()) { + locationFloorList.addAll(qcResponse.getLocationFloors()); + Log.e("locationFloorList-size: ",""+locationFloorList.size()); + } + + } else { + Toast.makeText(getActivity(), "Login Failed", Toast.LENGTH_SHORT).show(); + } + }); + + loginViewModel.getQualityControlData(); + } + + public void showProgressDialog() { + ProgressDialogFragment progressDialog = new ProgressDialogFragment(); + progressDialog.setCancelable(false); + progressDialog.show(getActivity().getSupportFragmentManager(), "progressDialog"); + } + + public void dismissProgressDialog() { + ProgressDialogFragment progressDialog = (ProgressDialogFragment) + getActivity().getSupportFragmentManager().findFragmentByTag("progressDialog"); + if (progressDialog != null) { + progressDialog.dismiss(); + } } } \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/PackingFragment.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/PackingFragment.java index 5e3f798..7d8c000 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/PackingFragment.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/PackingFragment.java @@ -1,17 +1,37 @@ package com.utopiaindustries.qualitycontrol.fragments; +import android.Manifest; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.core.content.FileProvider; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import android.os.Environment; +import android.provider.MediaStore; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.ImageButton; +import android.widget.TextView; +import android.widget.Toast; import com.utopiaindustries.qualitycontrol.R; import com.utopiaindustries.qualitycontrol.activities.HomeActivity; @@ -19,13 +39,101 @@ import com.utopiaindustries.qualitycontrol.adapters.ImageAdapter; import com.utopiaindustries.qualitycontrol.adapters.ItemAdapter; import com.utopiaindustries.qualitycontrol.models.Item; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; -public class PackingFragment extends Fragment { +import pub.devrel.easypermissions.AfterPermissionGranted; +import pub.devrel.easypermissions.AppSettingsDialog; +import pub.devrel.easypermissions.EasyPermissions; + +public class PackingFragment extends Fragment implements EasyPermissions.PermissionCallbacks{ RecyclerView recyclerView, imageRecyclerView; ImageAdapter imageAdapter; + String filePath = "no_pic"; + + private static final int CAMERA_REQUEST = 102; + private static final int GALLERY_REQUEST = 202; + Button nextButton; + ImageButton imagePicker, deleteImage; + + ArrayList imageList = new ArrayList<>(); + + // Activity Result Launcher for Gallery + private final ActivityResultLauncher imagePickerLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result.getResultCode() == requireActivity().RESULT_OK && result.getData() != null) { + Uri selectedImage = result.getData().getData(); + if (selectedImage != null) { + //imageView.setImageURI(selectedImage); + Log.e("Selected-Image: ", "" + selectedImage); + + uriToByteArrayAsync( + getContext(), + selectedImage, + 100, // Target size in KB + compressedImage -> { + // Handle the compressed image here, e.g., display it + requireActivity().runOnUiThread(() -> { + //store.getReport().getItems().get(0).getCheckPoints().get(requestCode).addImageList(compressedImage); + imageList.add(compressedImage); + imageAdapter.notifyDataSetChanged(); + }); + }, + error -> { + // Handle any errors + requireActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), "Error compressing image: " + error.getMessage(), Toast.LENGTH_SHORT).show(); + }); + } + ); + } + } + }); + + // Activity Result Launcher for Camera + private final ActivityResultLauncher cameraLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + Uri contentUri = Uri.fromFile(new File((filePath))); + + uriToByteArrayAsync( + getContext(), + contentUri, + 100, // Target size in KB + compressedImage -> { + // Handle the compressed image here, e.g., display it + requireActivity().runOnUiThread(() -> { + //store.getReport().getItems().get(0).getCheckPoints().get(requestCode).addImageList(compressedImage); + imageList.add(compressedImage); + imageAdapter.notifyDataSetChanged(); + }); + }, + error -> { + // Handle any errors + requireActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), "Error compressing image: " + error.getMessage(), Toast.LENGTH_SHORT).show(); + }); + } + ); + + Log.e("contentUri: ", "" + contentUri); + if (result.getResultCode() == requireActivity().RESULT_OK && result.getData() != null) { + + Uri selectedImage = result.getData().getData(); + if (selectedImage != null) { + //imageView.setImageURI(selectedImage); + Log.e("Selected-Image: ", "" + selectedImage); + } + } + }); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -48,7 +156,22 @@ public class PackingFragment extends Fragment { recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(adapter); - Button nextButton = view.findViewById(R.id.btn_next); + imageAdapter = new ImageAdapter(imageList, getActivity()); + imageRecyclerView.setAdapter(imageAdapter); + + imagePicker.setOnClickListener(v -> { + showAlertDialog(view); + }); + + deleteImage.setOnClickListener(v -> { + if (!imageList.isEmpty()) { + imageList.remove(imageList.size() - 1); + } else { + System.out.println("The list is empty"); + } + imageAdapter.notifyDataSetChanged(); + }); + nextButton.setOnClickListener(v -> { if (getActivity() instanceof HomeActivity) { ((HomeActivity) getActivity()).navigateToFragment(new SubStoreFragment(), true); @@ -65,8 +188,225 @@ public class PackingFragment extends Fragment { private void initializeLayout(View view) { + imagePicker = view.findViewById(R.id.image_picker); + deleteImage = view.findViewById(R.id.delete_image); + nextButton = view.findViewById(R.id.btn_next); recyclerView = view.findViewById(R.id.recycler_view_packing); imageRecyclerView = view.findViewById(R.id.imageRecyclerView); imageRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false)); } + + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + // EasyPermissions handles the request result. + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { + new AppSettingsDialog.Builder(this).build().show(); + } + } + + public void uriToByteArrayAsync( + Context context, + Uri uri, + int targetSizeInKB, + Consumer onSuccess, + Consumer onError + ) { + new Thread(() -> { + try { + int targetSizeInBytes = targetSizeInKB * 1024; + + // Load the image as a Bitmap without scaling + Bitmap bitmap; + try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) { + bitmap = BitmapFactory.decodeStream(inputStream); + } + + if (bitmap == null) { + throw new IOException("Failed to decode image from URI."); + } + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + int minQuality = 10; + int maxQuality = 100; + int quality = maxQuality; + + // Binary search for the best quality that meets the target size + while (minQuality <= maxQuality) { + byteArrayOutputStream.reset(); + bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream); + + int byteSize = byteArrayOutputStream.size(); + if (byteSize > targetSizeInBytes) { + maxQuality = quality - 1; + } else { + minQuality = quality + 1; + } + quality = (minQuality + maxQuality) / 2; + } + + onSuccess.accept(byteArrayOutputStream.toByteArray()); + } catch (IOException e) { + onError.accept(e); + } + }).start(); + } + + private boolean hasGalleryPermission() { + String[] perms = {}; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + } + + return EasyPermissions.hasPermissions(requireActivity(), perms); + } + + private boolean hasCameraPermission() { + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + //Log.e("TIRAMISU: ","***"); + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.CAMERA}; + } else { + //Log.e("Not-TIRAMISU: ","***"); + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; + + } + + //Log.e("perms: ",""+perms); + return EasyPermissions.hasPermissions(requireActivity(), perms); + } + + private File createImageFile() throws IOException { + // Create an image file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + String imageFileName = "JPEG_" + timeStamp + "_"; + File storageDir = requireActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES); + File image = File.createTempFile( + imageFileName, /* prefix */ + ".jpg", /* suffix */ + storageDir /* directory */ + ); + + filePath = image.getAbsolutePath(); + return image; + } + + public void showAlertDialog(View view) { + ViewGroup viewGroup = view.findViewById(android.R.id.content); + + TextView txt_camera, txt_gallery, txt_cancel; + + AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); + View view1 = LayoutInflater.from(getActivity()).inflate(R.layout.custom_layout, viewGroup, false); + builder.setCancelable(false); + builder.setView(view1); + + txt_camera = view1.findViewById(R.id.txt_camera); + txt_gallery = view1.findViewById(R.id.txt_gallery); + txt_cancel = view1.findViewById(R.id.txt_cancel); + + AlertDialog alertDialog = builder.create(); + Objects.requireNonNull(alertDialog.getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + + txt_camera.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + openCamera(); + } + }); + + txt_gallery.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + openGallery(); + } + }); + + txt_cancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + } + }); + + alertDialog.show(); + } + + @AfterPermissionGranted(CAMERA_REQUEST) + public void openCamera() { + if (hasCameraPermission()) { + try { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + File photoFile = null; + try { + photoFile = createImageFile(); + } catch (IOException ex) { + // Error occurred while creating the File + } + + if (photoFile != null) { + Uri photoURI = FileProvider.getUriForFile(requireActivity(), + "com.utopiaindustries.qualitycontrol", + photoFile); + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); + //startActivityForResult(takePictureIntent, CAMERA_REQUEST); + cameraLauncher.launch(takePictureIntent); + } + } catch (ActivityNotFoundException e) { + Toast.makeText(getContext(), "Camera app not found", Toast.LENGTH_SHORT).show(); + } + } else { + // Ask for one permission + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.CAMERA}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; + } + + EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera), CAMERA_REQUEST, perms); + } + } + + @AfterPermissionGranted(GALLERY_REQUEST) + public void openGallery() { + if (hasGalleryPermission()) { + // Have permission, do the thing! + Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + // Start the Intent + //startActivityForResult(galleryIntent, GALLERY_REQUEST); + imagePickerLauncher.launch(galleryIntent); + } else { + // Ask for one permission + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + } + EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera), GALLERY_REQUEST, perms); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/StitchingFragment.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/StitchingFragment.java index cc18749..5684772 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/StitchingFragment.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/StitchingFragment.java @@ -1,17 +1,37 @@ package com.utopiaindustries.qualitycontrol.fragments; +import android.Manifest; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.core.content.FileProvider; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import android.os.Environment; +import android.provider.MediaStore; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.ImageButton; +import android.widget.TextView; +import android.widget.Toast; import com.utopiaindustries.qualitycontrol.R; import com.utopiaindustries.qualitycontrol.activities.HomeActivity; @@ -19,13 +39,102 @@ import com.utopiaindustries.qualitycontrol.adapters.ImageAdapter; import com.utopiaindustries.qualitycontrol.adapters.ItemAdapter; import com.utopiaindustries.qualitycontrol.models.Item; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; -public class StitchingFragment extends Fragment { +import pub.devrel.easypermissions.AfterPermissionGranted; +import pub.devrel.easypermissions.AppSettingsDialog; +import pub.devrel.easypermissions.EasyPermissions; + +public class StitchingFragment extends Fragment implements EasyPermissions.PermissionCallbacks{ RecyclerView recyclerView, imageRecyclerView; ImageAdapter imageAdapter; + String filePath = "no_pic"; + + private static final int CAMERA_REQUEST = 103; + private static final int GALLERY_REQUEST = 203; + Button nextButton; + + ImageButton imagePicker, deleteImage; + + ArrayList imageList = new ArrayList<>(); + + // Activity Result Launcher for Gallery + private final ActivityResultLauncher imagePickerLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result.getResultCode() == requireActivity().RESULT_OK && result.getData() != null) { + Uri selectedImage = result.getData().getData(); + if (selectedImage != null) { + //imageView.setImageURI(selectedImage); + Log.e("Selected-Image: ", "" + selectedImage); + + uriToByteArrayAsync( + getContext(), + selectedImage, + 100, // Target size in KB + compressedImage -> { + // Handle the compressed image here, e.g., display it + requireActivity().runOnUiThread(() -> { + //store.getReport().getItems().get(0).getCheckPoints().get(requestCode).addImageList(compressedImage); + imageList.add(compressedImage); + imageAdapter.notifyDataSetChanged(); + }); + }, + error -> { + // Handle any errors + requireActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), "Error compressing image: " + error.getMessage(), Toast.LENGTH_SHORT).show(); + }); + } + ); + } + } + }); + + // Activity Result Launcher for Camera + private final ActivityResultLauncher cameraLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + Uri contentUri = Uri.fromFile(new File((filePath))); + + uriToByteArrayAsync( + getContext(), + contentUri, + 100, // Target size in KB + compressedImage -> { + // Handle the compressed image here, e.g., display it + requireActivity().runOnUiThread(() -> { + //store.getReport().getItems().get(0).getCheckPoints().get(requestCode).addImageList(compressedImage); + imageList.add(compressedImage); + imageAdapter.notifyDataSetChanged(); + }); + }, + error -> { + // Handle any errors + requireActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), "Error compressing image: " + error.getMessage(), Toast.LENGTH_SHORT).show(); + }); + } + ); + + Log.e("contentUri: ", "" + contentUri); + if (result.getResultCode() == requireActivity().RESULT_OK && result.getData() != null) { + + Uri selectedImage = result.getData().getData(); + if (selectedImage != null) { + //imageView.setImageURI(selectedImage); + Log.e("Selected-Image: ", "" + selectedImage); + } + } + }); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -48,7 +157,22 @@ public class StitchingFragment extends Fragment { recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(adapter); - Button nextButton = view.findViewById(R.id.btn_next); + imageAdapter = new ImageAdapter(imageList, getActivity()); + imageRecyclerView.setAdapter(imageAdapter); + + imagePicker.setOnClickListener(v -> { + showAlertDialog(view); + }); + + deleteImage.setOnClickListener(v -> { + if (!imageList.isEmpty()) { + imageList.remove(imageList.size() - 1); + } else { + System.out.println("The list is empty"); + } + imageAdapter.notifyDataSetChanged(); + }); + nextButton.setOnClickListener(v -> { if (getActivity() instanceof HomeActivity) { ((HomeActivity) getActivity()).navigateToFragment(new CheckingFragment(), true); @@ -65,8 +189,225 @@ public class StitchingFragment extends Fragment { private void initializeLayout(View view) { + imagePicker = view.findViewById(R.id.image_picker); + deleteImage = view.findViewById(R.id.delete_image); + nextButton = view.findViewById(R.id.btn_next); recyclerView = view.findViewById(R.id.recycler_view_stitching); imageRecyclerView = view.findViewById(R.id.imageRecyclerView); imageRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false)); } + + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + // EasyPermissions handles the request result. + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { + new AppSettingsDialog.Builder(this).build().show(); + } + } + + public void uriToByteArrayAsync( + Context context, + Uri uri, + int targetSizeInKB, + Consumer onSuccess, + Consumer onError + ) { + new Thread(() -> { + try { + int targetSizeInBytes = targetSizeInKB * 1024; + + // Load the image as a Bitmap without scaling + Bitmap bitmap; + try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) { + bitmap = BitmapFactory.decodeStream(inputStream); + } + + if (bitmap == null) { + throw new IOException("Failed to decode image from URI."); + } + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + int minQuality = 10; + int maxQuality = 100; + int quality = maxQuality; + + // Binary search for the best quality that meets the target size + while (minQuality <= maxQuality) { + byteArrayOutputStream.reset(); + bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream); + + int byteSize = byteArrayOutputStream.size(); + if (byteSize > targetSizeInBytes) { + maxQuality = quality - 1; + } else { + minQuality = quality + 1; + } + quality = (minQuality + maxQuality) / 2; + } + + onSuccess.accept(byteArrayOutputStream.toByteArray()); + } catch (IOException e) { + onError.accept(e); + } + }).start(); + } + + private boolean hasGalleryPermission() { + String[] perms = {}; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + } + + return EasyPermissions.hasPermissions(requireActivity(), perms); + } + + private boolean hasCameraPermission() { + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + //Log.e("TIRAMISU: ","***"); + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.CAMERA}; + } else { + //Log.e("Not-TIRAMISU: ","***"); + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; + + } + + //Log.e("perms: ",""+perms); + return EasyPermissions.hasPermissions(requireActivity(), perms); + } + + private File createImageFile() throws IOException { + // Create an image file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + String imageFileName = "JPEG_" + timeStamp + "_"; + File storageDir = requireActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES); + File image = File.createTempFile( + imageFileName, /* prefix */ + ".jpg", /* suffix */ + storageDir /* directory */ + ); + + filePath = image.getAbsolutePath(); + return image; + } + + public void showAlertDialog(View view) { + ViewGroup viewGroup = view.findViewById(android.R.id.content); + + TextView txt_camera, txt_gallery, txt_cancel; + + AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); + View view1 = LayoutInflater.from(getActivity()).inflate(R.layout.custom_layout, viewGroup, false); + builder.setCancelable(false); + builder.setView(view1); + + txt_camera = view1.findViewById(R.id.txt_camera); + txt_gallery = view1.findViewById(R.id.txt_gallery); + txt_cancel = view1.findViewById(R.id.txt_cancel); + + AlertDialog alertDialog = builder.create(); + Objects.requireNonNull(alertDialog.getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + + txt_camera.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + openCamera(); + } + }); + + txt_gallery.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + openGallery(); + } + }); + + txt_cancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + } + }); + + alertDialog.show(); + } + + @AfterPermissionGranted(CAMERA_REQUEST) + public void openCamera() { + if (hasCameraPermission()) { + try { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + File photoFile = null; + try { + photoFile = createImageFile(); + } catch (IOException ex) { + // Error occurred while creating the File + } + + if (photoFile != null) { + Uri photoURI = FileProvider.getUriForFile(requireActivity(), + "com.utopiaindustries.qualitycontrol", + photoFile); + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); + //startActivityForResult(takePictureIntent, CAMERA_REQUEST); + cameraLauncher.launch(takePictureIntent); + } + } catch (ActivityNotFoundException e) { + Toast.makeText(getContext(), "Camera app not found", Toast.LENGTH_SHORT).show(); + } + } else { + // Ask for one permission + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.CAMERA}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; + } + + EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera), CAMERA_REQUEST, perms); + } + } + + @AfterPermissionGranted(GALLERY_REQUEST) + public void openGallery() { + if (hasGalleryPermission()) { + // Have permission, do the thing! + Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + // Start the Intent + //startActivityForResult(galleryIntent, GALLERY_REQUEST); + imagePickerLauncher.launch(galleryIntent); + } else { + // Ask for one permission + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + } + EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera), GALLERY_REQUEST, perms); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/SubStoreFragment.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/SubStoreFragment.java index bb1916f..8d3aa94 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/SubStoreFragment.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/fragments/SubStoreFragment.java @@ -1,18 +1,37 @@ package com.utopiaindustries.qualitycontrol.fragments; +import android.Manifest; +import android.content.ActivityNotFoundException; +import android.content.Context; import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.core.content.FileProvider; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import android.os.Environment; +import android.provider.MediaStore; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.ImageButton; +import android.widget.TextView; +import android.widget.Toast; import com.utopiaindustries.qualitycontrol.R; import com.utopiaindustries.qualitycontrol.activities.HomeActivity; @@ -21,13 +40,100 @@ import com.utopiaindustries.qualitycontrol.adapters.ImageAdapter; import com.utopiaindustries.qualitycontrol.adapters.ItemAdapter; import com.utopiaindustries.qualitycontrol.models.Item; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; -public class SubStoreFragment extends Fragment { +import pub.devrel.easypermissions.AfterPermissionGranted; +import pub.devrel.easypermissions.AppSettingsDialog; +import pub.devrel.easypermissions.EasyPermissions; + +public class SubStoreFragment extends Fragment implements EasyPermissions.PermissionCallbacks{ RecyclerView recyclerView, imageRecyclerView; ImageAdapter imageAdapter; + String filePath = "no_pic"; + + private static final int CAMERA_REQUEST = 104; + private static final int GALLERY_REQUEST = 204; + + Button nextButton; + ImageButton imagePicker, deleteImage; + + ArrayList imageList = new ArrayList<>(); + + // Activity Result Launcher for Gallery + private final ActivityResultLauncher imagePickerLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result.getResultCode() == requireActivity().RESULT_OK && result.getData() != null) { + Uri selectedImage = result.getData().getData(); + if (selectedImage != null) { + //imageView.setImageURI(selectedImage); + + uriToByteArrayAsync( + getContext(), + selectedImage, + 100, // Target size in KB + compressedImage -> { + // Handle the compressed image here, e.g., display it + requireActivity().runOnUiThread(() -> { + //store.getReport().getItems().get(0).getCheckPoints().get(requestCode).addImageList(compressedImage); + imageList.add(compressedImage); + imageAdapter.notifyDataSetChanged(); + }); + }, + error -> { + // Handle any errors + requireActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), "Error compressing image: " + error.getMessage(), Toast.LENGTH_SHORT).show(); + }); + } + ); + } + } + }); + + // Activity Result Launcher for Camera + private final ActivityResultLauncher cameraLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + Uri contentUri = Uri.fromFile(new File((filePath))); + + uriToByteArrayAsync( + getContext(), + contentUri, + 100, // Target size in KB + compressedImage -> { + // Handle the compressed image here, e.g., display it + requireActivity().runOnUiThread(() -> { + //store.getReport().getItems().get(0).getCheckPoints().get(requestCode).addImageList(compressedImage); + imageList.add(compressedImage); + imageAdapter.notifyDataSetChanged(); + }); + }, + error -> { + // Handle any errors + requireActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), "Error compressing image: " + error.getMessage(), Toast.LENGTH_SHORT).show(); + }); + } + ); + + if (result.getResultCode() == requireActivity().RESULT_OK && result.getData() != null) { + + Uri selectedImage = result.getData().getData(); + if (selectedImage != null) { + //imageView.setImageURI(selectedImage); + Log.e("Selected-Image: ", "" + selectedImage); + } + } + }); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -50,7 +156,22 @@ public class SubStoreFragment extends Fragment { recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(adapter); - Button nextButton = view.findViewById(R.id.btn_next); + imageAdapter = new ImageAdapter(imageList, getActivity()); + imageRecyclerView.setAdapter(imageAdapter); + + imagePicker.setOnClickListener(v -> { + showAlertDialog(view); + }); + + deleteImage.setOnClickListener(v -> { + if (!imageList.isEmpty()) { + imageList.remove(imageList.size() - 1); + } else { + System.out.println("The list is empty"); + } + imageAdapter.notifyDataSetChanged(); + }); + nextButton.setOnClickListener(v -> { Intent intent = new Intent(getActivity(), SummaryActivity.class); startActivity(intent); @@ -67,8 +188,225 @@ public class SubStoreFragment extends Fragment { private void initializeLayout(View view) { + imagePicker = view.findViewById(R.id.image_picker); + deleteImage = view.findViewById(R.id.delete_image); + nextButton = view.findViewById(R.id.btn_next); recyclerView = view.findViewById(R.id.recycler_view_substore); imageRecyclerView = view.findViewById(R.id.imageRecyclerView); imageRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false)); } + + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + // EasyPermissions handles the request result. + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { + new AppSettingsDialog.Builder(this).build().show(); + } + } + + public void uriToByteArrayAsync( + Context context, + Uri uri, + int targetSizeInKB, + Consumer onSuccess, + Consumer onError + ) { + new Thread(() -> { + try { + int targetSizeInBytes = targetSizeInKB * 1024; + + // Load the image as a Bitmap without scaling + Bitmap bitmap; + try (InputStream inputStream = context.getContentResolver().openInputStream(uri)) { + bitmap = BitmapFactory.decodeStream(inputStream); + } + + if (bitmap == null) { + throw new IOException("Failed to decode image from URI."); + } + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + int minQuality = 10; + int maxQuality = 100; + int quality = maxQuality; + + // Binary search for the best quality that meets the target size + while (minQuality <= maxQuality) { + byteArrayOutputStream.reset(); + bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream); + + int byteSize = byteArrayOutputStream.size(); + if (byteSize > targetSizeInBytes) { + maxQuality = quality - 1; + } else { + minQuality = quality + 1; + } + quality = (minQuality + maxQuality) / 2; + } + + onSuccess.accept(byteArrayOutputStream.toByteArray()); + } catch (IOException e) { + onError.accept(e); + } + }).start(); + } + + private boolean hasGalleryPermission() { + String[] perms = {}; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + } + + return EasyPermissions.hasPermissions(requireActivity(), perms); + } + + private boolean hasCameraPermission() { + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + //Log.e("TIRAMISU: ","***"); + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.CAMERA}; + } else { + //Log.e("Not-TIRAMISU: ","***"); + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; + + } + + //Log.e("perms: ",""+perms); + return EasyPermissions.hasPermissions(requireActivity(), perms); + } + + private File createImageFile() throws IOException { + // Create an image file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + String imageFileName = "JPEG_" + timeStamp + "_"; + File storageDir = requireActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES); + File image = File.createTempFile( + imageFileName, /* prefix */ + ".jpg", /* suffix */ + storageDir /* directory */ + ); + + filePath = image.getAbsolutePath(); + return image; + } + + public void showAlertDialog(View view) { + ViewGroup viewGroup = view.findViewById(android.R.id.content); + + TextView txt_camera, txt_gallery, txt_cancel; + + AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); + View view1 = LayoutInflater.from(getActivity()).inflate(R.layout.custom_layout, viewGroup, false); + builder.setCancelable(false); + builder.setView(view1); + + txt_camera = view1.findViewById(R.id.txt_camera); + txt_gallery = view1.findViewById(R.id.txt_gallery); + txt_cancel = view1.findViewById(R.id.txt_cancel); + + AlertDialog alertDialog = builder.create(); + Objects.requireNonNull(alertDialog.getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + + txt_camera.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + openCamera(); + } + }); + + txt_gallery.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + openGallery(); + } + }); + + txt_cancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + alertDialog.dismiss(); + } + }); + + alertDialog.show(); + } + + @AfterPermissionGranted(CAMERA_REQUEST) + public void openCamera() { + if (hasCameraPermission()) { + try { + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + File photoFile = null; + try { + photoFile = createImageFile(); + } catch (IOException ex) { + // Error occurred while creating the File + } + + if (photoFile != null) { + Uri photoURI = FileProvider.getUriForFile(requireActivity(), + "com.utopiaindustries.qualitycontrol", + photoFile); + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); + //startActivityForResult(takePictureIntent, CAMERA_REQUEST); + cameraLauncher.launch(takePictureIntent); + } + } catch (ActivityNotFoundException e) { + Toast.makeText(getContext(), "Camera app not found", Toast.LENGTH_SHORT).show(); + } + } else { + // Ask for one permission + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.CAMERA}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; + } + + EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera), CAMERA_REQUEST, perms); + } + } + + @AfterPermissionGranted(GALLERY_REQUEST) + public void openGallery() { + if (hasGalleryPermission()) { + // Have permission, do the thing! + Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + // Start the Intent + //startActivityForResult(galleryIntent, GALLERY_REQUEST); + imagePickerLauncher.launch(galleryIntent); + } else { + // Ask for one permission + String[] perms = {}; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + perms = new String[]{Manifest.permission.READ_MEDIA_IMAGES}; + } else { + perms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + } + EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera), GALLERY_REQUEST, perms); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/helper/Helper.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/helper/Helper.java index 29094b6..6260de7 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/helper/Helper.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/helper/Helper.java @@ -8,6 +8,7 @@ import android.preference.PreferenceManager; import android.text.TextUtils; import com.google.gson.Gson; +import com.utopiaindustries.qualitycontrol.models.QualityControlResponse; public class Helper { @@ -22,4 +23,26 @@ public class Helper { NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); } + + static public void setPreferenceObject(Context c, Object modal, String key) { + + SharedPreferences appSharedPrefs = PreferenceManager.getDefaultSharedPreferences(c.getApplicationContext()); + SharedPreferences.Editor prefsEditor = appSharedPrefs.edit(); + + Gson gson = new Gson(); + String jsonObject = gson.toJson(modal); + prefsEditor.putString(key, jsonObject); + prefsEditor.commit(); + + } + + static public QualityControlResponse getPreferenceObjectJson(Context c, String key) { + + SharedPreferences appSharedPrefs = PreferenceManager.getDefaultSharedPreferences(c.getApplicationContext()); + + String json = appSharedPrefs.getString(key, ""); + Gson gson = new Gson(); + QualityControlResponse selectedUser = gson.fromJson(json, QualityControlResponse.class); + return selectedUser; + } } diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/models/Department.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/Department.java new file mode 100644 index 0000000..429d0eb --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/Department.java @@ -0,0 +1,176 @@ + +package com.utopiaindustries.qualitycontrol.models; + +import java.util.List; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Department { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("companyId") + @Expose + private Integer companyId; + @SerializedName("functionId") + @Expose + private Integer functionId; + @SerializedName("title") + @Expose + private String title; + @SerializedName("organization") + @Expose + private String organization; + @SerializedName("code") + @Expose + private Integer code; + @SerializedName("email") + @Expose + private Object email; + @SerializedName("isActive") + @Expose + private Boolean isActive; + @SerializedName("sections") + @Expose + private Object sections; + @SerializedName("hierarchyString") + @Expose + private Object hierarchyString; + @SerializedName("costCenters") + @Expose + private Object costCenters; + @SerializedName("locationSites") + @Expose + private Object locationSites; + @SerializedName("departmentLocationSites") + @Expose + private Object departmentLocationSites; + @SerializedName("utilitySubMeterDepartments") + @Expose + private List utilitySubMeterDepartments; + @SerializedName("capitalizedTitle") + @Expose + private String capitalizedTitle; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getCompanyId() { + return companyId; + } + + public void setCompanyId(Integer companyId) { + this.companyId = companyId; + } + + public Integer getFunctionId() { + return functionId; + } + + public void setFunctionId(Integer functionId) { + this.functionId = functionId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getOrganization() { + return organization; + } + + public void setOrganization(String organization) { + this.organization = organization; + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public Object getEmail() { + return email; + } + + public void setEmail(Object email) { + this.email = email; + } + + public Boolean getIsActive() { + return isActive; + } + + public void setIsActive(Boolean isActive) { + this.isActive = isActive; + } + + public Object getSections() { + return sections; + } + + public void setSections(Object sections) { + this.sections = sections; + } + + public Object getHierarchyString() { + return hierarchyString; + } + + public void setHierarchyString(Object hierarchyString) { + this.hierarchyString = hierarchyString; + } + + public Object getCostCenters() { + return costCenters; + } + + public void setCostCenters(Object costCenters) { + this.costCenters = costCenters; + } + + public Object getLocationSites() { + return locationSites; + } + + public void setLocationSites(Object locationSites) { + this.locationSites = locationSites; + } + + public Object getDepartmentLocationSites() { + return departmentLocationSites; + } + + public void setDepartmentLocationSites(Object departmentLocationSites) { + this.departmentLocationSites = departmentLocationSites; + } + + public List getUtilitySubMeterDepartments() { + return utilitySubMeterDepartments; + } + + public void setUtilitySubMeterDepartments(List utilitySubMeterDepartments) { + this.utilitySubMeterDepartments = utilitySubMeterDepartments; + } + + public String getCapitalizedTitle() { + return capitalizedTitle; + } + + public void setCapitalizedTitle(String capitalizedTitle) { + this.capitalizedTitle = capitalizedTitle; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/models/LocationFloor.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/LocationFloor.java new file mode 100644 index 0000000..0b02f84 --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/LocationFloor.java @@ -0,0 +1,65 @@ + +package com.utopiaindustries.qualitycontrol.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class LocationFloor { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("title") + @Expose + private String title; + @SerializedName("siteId") + @Expose + private Integer siteId; + @SerializedName("unitId") + @Expose + private Integer unitId; + @SerializedName("stores") + @Expose + private Object stores; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Integer getSiteId() { + return siteId; + } + + public void setSiteId(Integer siteId) { + this.siteId = siteId; + } + + public Integer getUnitId() { + return unitId; + } + + public void setUnitId(Integer unitId) { + this.unitId = unitId; + } + + public Object getStores() { + return stores; + } + + public void setStores(Object stores) { + this.stores = stores; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/models/LocationSite.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/LocationSite.java new file mode 100644 index 0000000..183bd9b --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/LocationSite.java @@ -0,0 +1,76 @@ + +package com.utopiaindustries.qualitycontrol.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class LocationSite { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("title") + @Expose + private String title; + @SerializedName("shortTitle") + @Expose + private String shortTitle; + @SerializedName("address") + @Expose + private String address; + @SerializedName("hasColony") + @Expose + private Boolean hasColony; + @SerializedName("units") + @Expose + private Object units; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getShortTitle() { + return shortTitle; + } + + public void setShortTitle(String shortTitle) { + this.shortTitle = shortTitle; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public Boolean getHasColony() { + return hasColony; + } + + public void setHasColony(Boolean hasColony) { + this.hasColony = hasColony; + } + + public Object getUnits() { + return units; + } + + public void setUnits(Object units) { + this.units = units; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlProcess.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlProcess.java new file mode 100644 index 0000000..1aab8cd --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlProcess.java @@ -0,0 +1,32 @@ + +package com.utopiaindustries.qualitycontrol.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class QualityControlProcess { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("name") + @Expose + private String name; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlProcessStep.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlProcessStep.java new file mode 100644 index 0000000..5d75efd --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlProcessStep.java @@ -0,0 +1,43 @@ + +package com.utopiaindustries.qualitycontrol.models; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class QualityControlProcessStep { + + @SerializedName("id") + @Expose + private Integer id; + @SerializedName("title") + @Expose + private String title; + @SerializedName("description") + @Expose + private String description; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlResponse.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlResponse.java index 09ef247..5d00a08 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlResponse.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/models/QualityControlResponse.java @@ -1,4 +1,65 @@ package com.utopiaindustries.qualitycontrol.models; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.List; + public class QualityControlResponse { + + @SerializedName("locationFloors") + @Expose + private List locationFloors; + @SerializedName("qualityControlProcessSteps") + @Expose + private List qualityControlProcessSteps; + @SerializedName("locationSites") + @Expose + private List locationSites; + @SerializedName("departments") + @Expose + private List departments; + @SerializedName("qualityControlProcessList") + @Expose + private List qualityControlProcessList; + + public List getLocationFloors() { + return locationFloors; + } + + public void setLocationFloors(List locationFloors) { + this.locationFloors = locationFloors; + } + + public List getQualityControlProcessSteps() { + return qualityControlProcessSteps; + } + + public void setQualityControlProcessSteps(List qualityControlProcessSteps) { + this.qualityControlProcessSteps = qualityControlProcessSteps; + } + + public List getLocationSites() { + return locationSites; + } + + public void setLocationSites(List locationSites) { + this.locationSites = locationSites; + } + + public List getDepartments() { + return departments; + } + + public void setDepartments(List departments) { + this.departments = departments; + } + + public List getQualityControlProcessList() { + return qualityControlProcessList; + } + + public void setQualityControlProcessList(List qualityControlProcessList) { + this.qualityControlProcessList = qualityControlProcessList; + } } diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/utils/ProgressDialogFragment.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/utils/ProgressDialogFragment.java new file mode 100644 index 0000000..1b5c89b --- /dev/null +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/utils/ProgressDialogFragment.java @@ -0,0 +1,37 @@ +package com.utopiaindustries.qualitycontrol.utils; + +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; + +import com.utopiaindustries.qualitycontrol.R; + +public class ProgressDialogFragment extends DialogFragment { + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.dialog_progress, container, false); + } + + @Override + public void onStart() { + super.onStart(); + if (getDialog() != null && getDialog().getWindow() != null) { + getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent); + } + } + + @Override + public void onCancel(@NonNull DialogInterface dialog) { + // Prevent the dialog from being canceled when touched outside + setCancelable(false); + } +} diff --git a/app/src/main/java/com/utopiaindustries/qualitycontrol/viewmodels/LoginViewModel.java b/app/src/main/java/com/utopiaindustries/qualitycontrol/viewmodels/LoginViewModel.java index 5d26343..6ca2e7f 100644 --- a/app/src/main/java/com/utopiaindustries/qualitycontrol/viewmodels/LoginViewModel.java +++ b/app/src/main/java/com/utopiaindustries/qualitycontrol/viewmodels/LoginViewModel.java @@ -39,9 +39,9 @@ public class LoginViewModel extends ViewModel { return errorLiveData; } - public void authenticateUser(String user, String password) { + public void getQualityControlData() { isLoading.setValue(true); - apiService.isUserAuthenticated(user, password).enqueue(new Callback() { + apiService.isUserAuthenticated().enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { isLoading.setValue(false); diff --git a/app/src/main/res/layout/dialog_progress.xml b/app/src/main/res/layout/dialog_progress.xml new file mode 100644 index 0000000..c82c3e7 --- /dev/null +++ b/app/src/main/res/layout/dialog_progress.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file