- bug fixed after testing

main
saif 2024-06-03 16:25:49 +05:00
parent 360ce2dd24
commit 30526b3dab
8 changed files with 308 additions and 86 deletions

View File

@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.INTERNET" /> <!-- If your app needs to access network state -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"/>

View File

@ -3,6 +3,9 @@ package com.utopiaindustries.qualitychecker.apiservice;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@ -19,8 +22,15 @@ public class RetrofitClient {
.create();
if ( retrofit == null ) {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl( BASE_URL )
.client( okHttpClient )
.addConverterFactory( GsonConverterFactory.create( gson ) )
.build();
}

View File

@ -0,0 +1,99 @@
package com.utopiaindustries.qualitychecker.async;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ImageProcessor {
private ExecutorService executorService;
private Handler backgroundHandler;
private Handler mainHandler;
public ImageProcessor() {
executorService = Executors.newSingleThreadExecutor();
HandlerThread handlerThread = new HandlerThread("ImageProcessorThread");
handlerThread.start();
backgroundHandler = new Handler(handlerThread.getLooper());
mainHandler = new Handler(Looper.getMainLooper());
}
public void compressImageFromUriAsync(final Context context, final Uri uri, final int maxSizeKB, final OnImageCompressedListener listener) {
backgroundHandler.post(new Runnable() {
@Override
public void run() {
byte[] imageData = getBytesFromUri(context, uri);
if (imageData != null) {
final byte[] compressedData = compressImageToMaxSize(imageData, maxSizeKB);
mainHandler.post(() -> listener.onImageCompressed(compressedData));
} else {
mainHandler.post(new Runnable() {
@Override
public void run() {
listener.onImageCompressed(null);
}
});
}
}
});
}
private byte[] getBytesFromUri(Context context, Uri uri) {
if (uri != null) {
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
if (inputStream != null) {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
inputStream.close();
return byteBuffer.toByteArray();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private byte[] compressImageToMaxSize(byte[] imageData, int maxSizeKB) {
int quality = 100; // Start with the highest quality
byte[] compressedBytes = compressImage(imageData, quality);
// Loop to reduce quality until the image is within the max size
while (compressedBytes.length > maxSizeKB * 1024 && quality > 0) {
quality -= 5;
compressedBytes = compressImage(imageData, quality);
}
return compressedBytes;
}
private byte[] compressImage(byte[] imageData, int quality) {
if (imageData != null && imageData.length > 0) {
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
return outputStream.toByteArray();
}
return null;
}
public void shutdown() {
executorService.shutdown();
}
public interface OnImageCompressedListener {
void onImageCompressed(byte[] compressedData);
}
}

View File

@ -0,0 +1,37 @@
package com.utopiaindustries.qualitychecker.notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import androidx.core.app.NotificationCompat;
import com.utopiaindustries.qualitychecker.R;
public class NotificationHelper {
private static final String CHANNEL_ID = "001122";
private static final String CHANNEL_NAME = "QA_App_Channel";
private static final String CHANNEL_DESCRIPTION = "Channel_for_qa_app";
public static void showNotification(Context context, String title, String message) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Create a notification channel for devices running Android Oreo (API 26) and higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(CHANNEL_DESCRIPTION);
notificationManager.createNotificationChannel(channel);
}
// Build the notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.utopia_svg_logo) // Set your notification icon here
.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
// Show the notification
notificationManager.notify(0, builder.build());
}
}

View File

@ -16,6 +16,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Handler;
import retrofit2.Call;
import retrofit2.Callback;
@ -85,41 +86,85 @@ public class InspectionReportService {
this.reportResult = reportResult;
}
private void populateDefectsInBackground(InspectionReport inspectionReport) {
for (InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints()) {
List<InspectionItemDefect> defectList = getInspectionItemDefects(itemCp);
itemCp.setDefects(defectList);
}
}
private void saveReportInBackground(final InspectionReport inspectionReport, final SaveReportCallback callback) {
// Post object
apiService.saveInspectionReport(inspectionReport).enqueue(
new Callback<Map<String, String>>() {
@Override
public void onResponse(Call<Map<String, String>> call,
Response<Map<String, String>> response) {
if (response.isSuccessful()) {
System.out.println(response.body());
if (response.body().get("result").equalsIgnoreCase("success")) {
callback.onSuccess();
} else {
callback.onFailure(new Exception("Error on submitting report"));
}
} else {
callback.onFailure(new Exception("API call failed with status code: " + response.code()));
}
}
@Override
public void onFailure(Call<Map<String, String>> call, Throwable t) {
System.out.println(t);
callback.onFailure(t);
}
}
);
}
public void saveReport(InspectionReport inspectionReport , SaveReportCallback callback){
if( Objects.nonNull( inspectionReport ) && inspectionReport.getItems().get(0).getSku() != null && inspectionReport.getItems() != null &&
! inspectionReport.getItems().isEmpty() &&
! inspectionReport.getItems().get(0).getCheckPoints().isEmpty() ){
new Thread(() -> {
populateDefectsInBackground( inspectionReport );
//post report
saveReportInBackground( inspectionReport , callback );
}).start();
// populate defects in cp
for( InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints() ){
List<InspectionItemDefect> defectList = getInspectionItemDefects(itemCp);
itemCp.setDefects( defectList );
}
// for( InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints() ){
// List<InspectionItemDefect> defectList = getInspectionItemDefects(itemCp);
// itemCp.setDefects( defectList );
// }
// post object
apiService.saveInspectionReport( inspectionReport ).enqueue(
new Callback<Map<String,String>>() {
@Override
public void onResponse(Call<Map<String,String>> call,
Response<Map<String,String>> response) {
if ( response.isSuccessful() ) {
System.out.println( response.body() );
if( response.body().get("result").equalsIgnoreCase("success")){
callback.onSuccess();
}
else {
callback.onFailure(new Exception( "Error on submitting report" ));
}
} else {
callback.onFailure(new Exception("API call failed with status code: " + response.code()));
}
}
@Override
public void onFailure(Call<Map<String,String>> call, Throwable t) {
System.out.println( t );
callback.onFailure( t );
}
}
);
// apiService.saveInspectionReport( inspectionReport ).enqueue(
// new Callback<Map<String,String>>() {
// @Override
// public void onResponse(Call<Map<String,String>> call,
// Response<Map<String,String>> response) {
// if ( response.isSuccessful() ) {
// System.out.println( response.body() );
// if( response.body().get("result").equalsIgnoreCase("success")){
// callback.onSuccess();
// }
// else {
// callback.onFailure(new Exception( "Error on submitting report" ));
// }
// } else {
// callback.onFailure(new Exception("API call failed with status code: " + response.code()));
// }
// }
// @Override
// public void onFailure(Call<Map<String,String>> call, Throwable t) {
// System.out.println( t );
// callback.onFailure( t );
// }
// }
// );
} else {
callback.onFailure( new Exception("Please Fill the required Fields..") );
}

View File

@ -32,6 +32,7 @@ import com.bumptech.glide.Glide;
import com.utopiaindustries.qualitychecker.R;
import com.utopiaindustries.qualitychecker.apiservice.ApiService;
import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory;
import com.utopiaindustries.qualitychecker.async.ImageProcessor;
import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint;
import com.utopiaindustries.qualitychecker.models.InspectionDefect;
import com.utopiaindustries.qualitychecker.service.InspectionReportService;
@ -44,6 +45,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
public class SecondStepFragment extends Fragment
@ -133,63 +135,72 @@ public class SecondStepFragment extends Fragment
public void onImagePickerResult(int requestCode, int resultCode, Intent data) {
if ( resultCode == RESULT_OK && data != null ) {
try {
ImageProcessor imageProcessor = new ImageProcessor();
Uri selectedImageUri = data.getData();
assert selectedImageUri != null;
String imagePath = selectedImageUri.getPath();
store.getReport().getItems().get( 0 ).getCheckPoints().get( requestCode ).setImagePath( imagePath );
store.getReport().getItems().get( 0 ).getCheckPoints().get( requestCode ).setFile(
compressImageToMaxSize( getBytesFromUri( getContext(), selectedImageUri ), 200 )
);
adapter.notifyItemChanged( requestCode );
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
store.getReport().getItems().get(0).getCheckPoints().get(requestCode).setImagePath(imagePath);
private byte[] getBytesFromUri(Context context, Uri uri) {
if( uri != null ) {
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
if (inputStream != null) {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
imageProcessor.compressImageFromUriAsync(getContext(), selectedImageUri, 200, compressedData -> {
if (compressedData != null) {
store.getReport().getItems().get(0).getCheckPoints().get(requestCode).setFile(compressedData);
} else {
store.getReport().getItems().get(0).getCheckPoints().get(requestCode).setFile(null);
}
inputStream.close();
return byteBuffer.toByteArray();
}
} catch (IOException e) {
System.out.println(e.getMessage());
return null;
adapter.notifyItemChanged( requestCode );
});
} catch ( Exception e ){
e.printStackTrace();
}
// store.getReport().getItems().get( 0 ).getCheckPoints().get( requestCode ).setFile(
// compressImageToMaxSize( getBytesFromUri( getContext(), selectedImageUri ), 200 )
// );
}
return null;
}
public byte[] compressImageToMaxSize(byte[] imageData,
int maxSizeKB) {
int quality = 100; // Start with highest quality
byte[] compressedBytes = compressImage(imageData, quality);
// Loop to reduce quality until the image is within the max size
while (compressedBytes.length > maxSizeKB * 1024 && quality > 0) {
quality -= 5;
compressedBytes = compressImage(imageData, quality);
}
return compressedBytes;
}
private byte[] compressImage(byte[] imageData,
int quality) {
if( imageData != null && imageData.length > 0 ) {
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
return outputStream.toByteArray();
}
return null;
}
// private byte[] getBytesFromUri(Context context, Uri uri) {
// if( uri != null ) {
// try {
// InputStream inputStream = context.getContentResolver().openInputStream(uri);
// if (inputStream != null) {
// ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
// byte[] buffer = new byte[1024];
// int len;
// while ((len = inputStream.read(buffer)) != -1) {
// byteBuffer.write(buffer, 0, len);
// }
// inputStream.close();
// return byteBuffer.toByteArray();
// }
// } catch (IOException e) {
// System.out.println(e.getMessage());
// return null;
// }
// }
// return null;
// }
//
// public byte[] compressImageToMaxSize(byte[] imageData,
// int maxSizeKB) {
// int quality = 100; // Start with highest quality
// byte[] compressedBytes = compressImage(imageData, quality);
// // Loop to reduce quality until the image is within the max size
// while (compressedBytes.length > maxSizeKB * 1024 && quality > 0) {
// quality -= 5;
// compressedBytes = compressImage(imageData, quality);
// }
//
// return compressedBytes;
// }
//
// private byte[] compressImage(byte[] imageData,
// int quality) {
// if( imageData != null && imageData.length > 0 ) {
// Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
// return outputStream.toByteArray();
// }
// return null;
// }
}

View File

@ -32,11 +32,11 @@ import com.utopiaindustries.qualitychecker.R;
import com.utopiaindustries.qualitychecker.apiservice.ApiService;
import com.utopiaindustries.qualitychecker.apiservice.ApiServiceFactory;
import com.utopiaindustries.qualitychecker.models.InspectionItemCheckPoint;
import com.utopiaindustries.qualitychecker.models.InspectionItemDefect;
import com.utopiaindustries.qualitychecker.models.InspectionItemDimension;
import com.utopiaindustries.qualitychecker.models.InspectionReport;
import com.utopiaindustries.qualitychecker.models.SaveReportCallback;
import com.utopiaindustries.qualitychecker.models.VoiceOfCustomer;
import com.utopiaindustries.qualitychecker.notification.NotificationHelper;
import com.utopiaindustries.qualitychecker.service.InspectionReportService;
import com.utopiaindustries.qualitychecker.store.Store;
import com.utopiaindustries.qualitychecker.ui.adapter.DimensionAdapter;
@ -145,22 +145,33 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener
View dialogView = inflater.inflate( R.layout.save_report_dialog, null);
// progress bar
ProgressBar progressBar = dialogView.findViewById( R.id.save_report_progress );
AlertDialog.Builder builder = new AlertDialog.Builder( Objects.requireNonNull(getContext()) );
builder.setView( dialogView )
.setTitle("So you want to save report?")
.setPositiveButton( "Save",(dialog, which) -> {
progressBar.setVisibility( View.VISIBLE );
NotificationHelper.showNotification( Objects.requireNonNull(getContext()),
"Utopia QA App",
"Report is uploading keep patience...");
inspectionReportService.saveReport(store.getReport(), new SaveReportCallback() {
@Override
public void onSuccess() {
Toast.makeText( getContext(), "Report saved Successfully", Toast.LENGTH_LONG ).show();
progressBar.setVisibility( View.INVISIBLE );
Objects.requireNonNull( getActivity() ).finish();
NotificationHelper.showNotification( Objects.requireNonNull(getContext()),
"Utopia QA App",
"Report is uploaded successfully");
}
@Override
public void onFailure(Throwable throwable) {
Toast.makeText( getContext(), throwable.getMessage(), Toast.LENGTH_LONG ).show();
progressBar.setVisibility( View.INVISIBLE );
NotificationHelper.showNotification( Objects.requireNonNull(getContext()),
"Utopia QA App",
"Error in uploading report");
}
});
})
@ -170,7 +181,9 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener
});
// Show the dialog
AlertDialog dialog = builder.create();
progressBar.setVisibility( View.GONE );
dialog.show();
}
private void openDimensionDialog() {
@ -265,10 +278,18 @@ public class ThirdStepFragment extends Fragment implements View.OnClickListener
int major = 0;
int crirical = 0;
for (InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints()) {
for( String status : itemCp.getDefectSeverites() ){
if( status.equalsIgnoreCase("minor") ) minor++;
if( status.equalsIgnoreCase("major") ) major++;
if( status.equalsIgnoreCase("critical") ) crirical++;
for( int i = 0 ; i< itemCp.getDefectSeverites().size() ; i++ ){
String status = itemCp.getDefectSeverites().get( i );
float quantity = itemCp.getQuantities().get(i);
if( status.equalsIgnoreCase("minor") ){
minor += (int) quantity;
} ;
if( status.equalsIgnoreCase("major") ){
major += (int) quantity;
}
if( status.equalsIgnoreCase("critical") ) {
crirical += (int) quantity;
}
}
}

View File

@ -7,9 +7,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:id="@+id/save_report_progress"
android:visibility="invisible"
>
android:id="@+id/save_report_progress">
</ProgressBar>