515 lines
21 KiB
Java
515 lines
21 KiB
Java
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.Item;
|
|
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 StitchingFragment extends Fragment implements EasyPermissions.PermissionCallbacks,
|
|
ImageSelectionListener {
|
|
|
|
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<byte[]> imageList = new ArrayList<>();
|
|
EditText etPercentage, etRemarks;
|
|
List<ItemModel> itemModelList = new ArrayList<>();
|
|
ItemStepsAdapter adapter;
|
|
private int selectedPosition = -1;
|
|
private int deletePosition = -1;
|
|
|
|
// Activity Result Launcher for Gallery
|
|
private final ActivityResultLauncher<Intent> 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,
|
|
100, // Target size in KB
|
|
compressedImage -> {
|
|
// Handle the compressed image here, e.g., display it
|
|
requireActivity().runOnUiThread(() -> {
|
|
itemModelList.get(selectedPosition).setImageUri(compressedImage);
|
|
List<byte[]> 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<Intent> 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(() -> {
|
|
itemModelList.get(selectedPosition).setImageUri(compressedImage);
|
|
List<byte[]> 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) {
|
|
|
|
View view = inflater.inflate(R.layout.fragment_stitching, container, false);
|
|
|
|
initializeLayout(view);
|
|
|
|
// Set up RecyclerView
|
|
/*ItemStitchingAdapter adapter = new ItemStitchingAdapter(getActivity(), itemList, sharedViewModel);
|
|
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
|
recyclerView.setAdapter(adapter);*/
|
|
|
|
//New Implemented------------------
|
|
if (Helper.getArrayList(Helper.listStitching, getActivity()) != null) {
|
|
itemModelList.clear();
|
|
itemModelList.addAll(Helper.getArrayList(Helper.listStitching, 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(2,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(2,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);
|
|
|
|
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) {
|
|
|
|
List<ItemModel> 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.listStitching,getActivity());
|
|
|
|
//List<ItemModel> updatedItemListP = new ArrayList<>(Helper.getArrayList("ListStitching", getActivity()));
|
|
|
|
|
|
/*if (etRemarks.getText().toString().isEmpty()) {
|
|
Toast.makeText(getActivity(), "Please enter remarks", Toast.LENGTH_SHORT).show();
|
|
}
|
|
else {*/
|
|
/* sharedViewModel.setStitchingPercentage(etPercentage.getText().toString());
|
|
sharedViewModel.setStitchingRemarks(etRemarks.getText().toString());
|
|
if (!imageList.isEmpty()) {
|
|
sharedViewModel.setStitchingImageList(imageList);
|
|
}*/
|
|
((HomeActivity) getActivity()).navigateToFragment(new CheckingFragment(), true);
|
|
// }
|
|
}
|
|
});
|
|
|
|
return view;
|
|
}
|
|
|
|
@Override
|
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
|
super.onViewCreated(view, savedInstanceState);
|
|
}
|
|
|
|
private void initializeLayout(View view) {
|
|
|
|
//viewModel = new ViewModelProvider(requireActivity()).get(QualityControlViewModel.class);
|
|
|
|
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_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<String> perms) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
|
|
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
|
|
new AppSettingsDialog.Builder(this).build().show();
|
|
}
|
|
}
|
|
|
|
public void uriToByteArrayAsync(
|
|
Context context,
|
|
Uri uri,
|
|
int targetSizeInKB,
|
|
Consumer<byte[]> onSuccess,
|
|
Consumer<Exception> 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);
|
|
}
|
|
}
|
|
|
|
@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) { // Camera
|
|
openCamera();
|
|
} else { // Gallery
|
|
openGallery();
|
|
}
|
|
})
|
|
.show();
|
|
}
|
|
|
|
@Override
|
|
public void onDeleteImage(int position) {
|
|
deletePosition = position;
|
|
|
|
if (itemModelList.get(deletePosition).getImageArrayList() != null && !itemModelList.get(deletePosition).getImageArrayList().isEmpty()) {
|
|
itemModelList.get(deletePosition).setImageArrayList(null);
|
|
itemModelList.get(deletePosition).setImageUri(null);
|
|
adapter.notifyItemChanged(deletePosition);
|
|
}
|
|
|
|
}
|
|
} |