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.lifecycle.ViewModelProvider; 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.EditText; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; import com.utopiaindustries.qualitycontrol.R; import com.utopiaindustries.qualitycontrol.activities.HomeActivity; import com.utopiaindustries.qualitycontrol.adapters.ImageAdapter; import com.utopiaindustries.qualitycontrol.adapters.ItemStepsAdapter; import com.utopiaindustries.qualitycontrol.helper.Helper; import com.utopiaindustries.qualitycontrol.models.QualityControlProcessStep; import com.utopiaindustries.qualitycontrol.models.QualityControlResponse; import com.utopiaindustries.qualitycontrol.utils.ImageSelectionListener; import com.utopiaindustries.qualitycontrol.utils.QualityControlViewModel; import com.utopiaindustries.qualitycontrol.viewmodels.ItemModel; 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.Arrays; import java.util.Date; import java.util.List; 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 implements EasyPermissions.PermissionCallbacks, ImageSelectionListener { RecyclerView recyclerView, imageRecyclerView; ImageAdapter imageAdapter; Button nextButton; ImageButton imagePicker, deleteImage; private static final int CAMERA_REQUEST = 100; private static final int GALLERY_REQUEST = 200; String filePath = "no_pic"; ArrayList imageList = new ArrayList<>(); ArrayList qualityControlProcessStepList = new ArrayList<>(); EditText etPercentage, etRemarks; List itemModelList = new ArrayList<>(); ItemStepsAdapter adapter; private int selectedPosition = -1; private int deletePosition = -1; // 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 (selectedPosition != -1 && selectedImage != null) { //imageView.setImageURI(selectedImage); //Log.e("Selected-Image: ", "" + selectedImage); uriToByteArrayAsync( getContext(), selectedImage, 60, // Target size in KB compressedImage -> { // Handle the compressed image here, e.g., display it requireActivity().runOnUiThread(() -> { itemModelList.get(selectedPosition).setImageUri(compressedImage); List tempList = new ArrayList<>(); tempList.add(compressedImage); itemModelList.get(selectedPosition).setImageArrayList(tempList); adapter.notifyItemChanged(selectedPosition); }); }, 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, 60, // Target size in KB compressedImage -> { // Handle the compressed image here, e.g., display it requireActivity().runOnUiThread(() -> { itemModelList.get(selectedPosition).setImageUri(compressedImage); List tempList = new ArrayList<>(); tempList.add(compressedImage); itemModelList.get(selectedPosition).setImageArrayList(tempList); adapter.notifyItemChanged(selectedPosition); }); }, 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) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_cutting, container, false); initializeLayout(view); /* List itemList = new ArrayList<>(); itemList.add(new Item("Sort", 0)); itemList.add(new Item("Set in Order", 0)); itemList.add(new Item("Shine", 0)); itemList.add(new Item("Standardize", 0)); itemList.add(new Item("Sustain", 0)); itemList.add(new Item("Safety", 0));*/ // Set up RecyclerView /*ItemCuttingAdapter adapter = new ItemCuttingAdapter(getActivity(), itemList, sharedViewModel); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(adapter);*/ //New Implemented------------------ //Log.e("Check-Cut: ",""+Helper.getArrayList("ListCutting", getActivity())); if (Helper.getArrayList(Helper.listCutting, getActivity()) != null) { itemModelList.clear(); itemModelList.addAll(Helper.getArrayList(Helper.listCutting, getActivity())); //Log.e("itemModelList-size: ", "" + itemModelList.size()); if (itemModelList != null) { adapter = new ItemStepsAdapter(getActivity(), itemModelList, this); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(adapter); } else { for (int i = 1; i < 7; i++) { itemModelList.add(new ItemModel(1, i, 0, "0", "", 0, null,null)); } adapter = new ItemStepsAdapter(getActivity(), itemModelList, this); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(adapter); } } else { for (int i = 1; i < 7; i++) { itemModelList.add(new ItemModel(1,i,0,"0","",0, null, null)); } adapter = new ItemStepsAdapter(getActivity(), itemModelList, this); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(adapter); } //---------------------------------- imageAdapter = new ImageAdapter(imageList, getActivity()); imageRecyclerView.setAdapter(imageAdapter); nextButton.setOnClickListener(v -> { if (getActivity() instanceof HomeActivity) { List updatedItemList = itemModelList; // Or adapter.getItemList() /*for (ItemModel item : updatedItemList) { Log.e("AdapterData", "ProcessId: " + item.getProcessId() + ", StepId: " + item.getStepId() + ", SpinnerSelection: " + item.getSelectedOption() + ", Rating: " + item.getRating() + ", Percentage: " + item.getPercentage() + ", Remarks: " + item.getRemarks() + ", ImageList: " + item.getImageArrayList()); }*/ Helper.saveArrayList(itemModelList, Helper.listCutting, getActivity()); /*Log.e("Cutting: ","----------------"); Log.e("Sort: ",""+sharedViewModel.getCuttingSort()); Log.e("Set-Order: ",""+sharedViewModel.getCuttingSetInOrder()); Log.e("Shine: ",""+sharedViewModel.getCuttingShine()); Log.e("Standardize: ",""+sharedViewModel.getCuttingStandardize()); Log.e("Sustain: ",""+sharedViewModel.getCuttingSustain()); Log.e("Safety: ",""+sharedViewModel.getCuttingSafety()); Log.e("Cutting-Remarks: ",""+sharedViewModel.getCuttingRemarks()); List tempList = new ArrayList<>(); for (int i = 1 ; i < 6 ; i++) { ItemModel itemModel = new ItemModel(); itemModel.setProcessId(1); itemModel.setStepId(i); switch (i) { case 1: itemModel.setSort(sharedViewModel.getCuttingSort()); break; case 2: itemModel.setSetInOrder(sharedViewModel.getCuttingSetInOrder()); break; case 3: itemModel.setShine(sharedViewModel.getCuttingShine()); break; case 4: itemModel.setStandardize(sharedViewModel.getCuttingStandardize()); break; case 5: itemModel.setSustain(sharedViewModel.getCuttingSustain()); break; case 6: itemModel.setSafety(sharedViewModel.getCuttingSafety()); break; } itemModel.setPercentage(sharedViewModel.getCuttingPercentage()); itemModel.setRemarks(sharedViewModel.getCuttingRemarks()); tempList.add(itemModel); } sharedViewModel.setItemList(tempList);*/ /*if (etRemarks.getText().toString().isEmpty()) { Toast.makeText(getActivity(), "Please enter remarks", Toast.LENGTH_SHORT).show(); } else {*/ //sharedViewModel.setCuttingPercentage(etPercentage.getText().toString()); //sharedViewModel.setCuttingRemarks(etRemarks.getText().toString()); //click to next fragment /*if (imageList.size() > 0) { sharedViewModel.setCuttingImageList(imageList); }*/ ((HomeActivity) getActivity()).navigateToFragment(new StitchingFragment(), 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; } private void initializeLayout(View view) { etPercentage = view.findViewById(R.id.et_percentage); etRemarks = view.findViewById(R.id.et_remarks); 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_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 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); } 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); } } 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 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(); } @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(); } } @Override public void onSelectImage(int position) { selectedPosition = position; // Show dialog to choose between camera and gallery AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()); builder.setTitle("Select Image") .setItems(new String[]{"Camera", "Gallery"}, (dialog, which) -> { if (which == 0) { openCamera(); } else { openGallery(); } }) .show(); } @Override public void onDeleteImage(int position) { deletePosition = position; Log.e("delete-position: ",""+deletePosition); if (itemModelList.get(deletePosition).getImageArrayList() != null && !itemModelList.get(deletePosition).getImageArrayList().isEmpty()) { itemModelList.get(deletePosition).setImageArrayList(null); itemModelList.get(deletePosition).setImageUri(null); adapter.notifyItemChanged(deletePosition); } } public boolean isValidate(int rateCutting, int rateStitching, int rateChecking, int ratePacking, int rateSub) { boolean returnValue = true; String message = ""; if (rateSub == 0) { message = "Please rate SubStore Process."; returnValue = false; } if (ratePacking == 0) { message = "Please rate Packing Process."; returnValue = false; } if (rateChecking == 0) { message = "Please rate Checking Process."; returnValue = false; } if (rateStitching == 0) { message = "Please rate Stitching Process."; returnValue = false; } if (rateCutting == 0) { message = "Please rate Cutting Process."; returnValue = false; } if (!returnValue) { Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show(); } return returnValue; } }