- bug fixed after testing
parent
360ce2dd24
commit
30526b3dab
|
@ -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"/>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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,17 +86,16 @@ public class InspectionReportService {
|
|||
this.reportResult = reportResult;
|
||||
}
|
||||
|
||||
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() ){
|
||||
// populate defects in cp
|
||||
private void populateDefectsInBackground(InspectionReport inspectionReport) {
|
||||
for (InspectionItemCheckPoint itemCp : inspectionReport.getItems().get(0).getCheckPoints()) {
|
||||
List<InspectionItemDefect> defectList = getInspectionItemDefects(itemCp);
|
||||
itemCp.setDefects(defectList);
|
||||
}
|
||||
// post object
|
||||
}
|
||||
|
||||
|
||||
private void saveReportInBackground(final InspectionReport inspectionReport, final SaveReportCallback callback) {
|
||||
// Post object
|
||||
apiService.saveInspectionReport(inspectionReport).enqueue(
|
||||
new Callback<Map<String, String>>() {
|
||||
@Override
|
||||
|
@ -105,14 +105,14 @@ public class InspectionReportService {
|
|||
System.out.println(response.body());
|
||||
if (response.body().get("result").equalsIgnoreCase("success")) {
|
||||
callback.onSuccess();
|
||||
}
|
||||
else {
|
||||
} 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);
|
||||
|
@ -120,6 +120,51 @@ public class InspectionReportService {
|
|||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
// }
|
||||
// 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 );
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
} else {
|
||||
callback.onFailure( new Exception("Please Fill the required Fields..") );
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
adapter.notifyItemChanged( requestCode );
|
||||
});
|
||||
} catch ( Exception e ){
|
||||
throw new RuntimeException(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
// store.getReport().getItems().get( 0 ).getCheckPoints().get( requestCode ).setFile(
|
||||
// compressImageToMaxSize( getBytesFromUri( getContext(), selectedImageUri ), 200 )
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// 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;
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue