diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5a5217267..ed11d0e1b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -117,7 +117,6 @@
currencies = new HashMap<>();
- String tempCameraPicturePath;
-
LoyaltyCard tempLoyaltyCard;
- ActivityResultLauncher mPhotoTakerLauncher;
+ ActivityResultLauncher mPhotoTakerLauncher;
ActivityResultLauncher mPhotoPickerLauncher;
ActivityResultLauncher mCardIdAndBarCodeEditorLauncher;
ActivityResultLauncher mCropperLauncher;
- int mRequestedImage;
+ int mRequestedImage = 0;
+ int mCropperFinishedType = 0;
UCrop.Options mCropperOptions;
-
+ boolean mFrontImageUnsaved = false;
+ boolean mBackImageUnsaved = false;
final private TaskHandler mTasks = new TaskHandler();
@@ -199,6 +206,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
+ ", updateLoyaltyCard=" + updateLoyaltyCard);
}
+
+
@Override
public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
@@ -206,7 +215,20 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
savedInstanceState.putInt(STATE_TAB_INDEX, tabs.getSelectedTabPosition());
savedInstanceState.putParcelable(STATE_TEMP_CARD, tempLoyaltyCard);
savedInstanceState.putInt(STATE_REQUESTED_IMAGE, mRequestedImage);
- savedInstanceState.putString(STATE_TEMP_CAMERA_PICTURE_PATH, tempCameraPicturePath);
+ Object cardImageFrontObj = cardImageFront.getTag();
+ if (mFrontImageUnsaved && (cardImageFrontObj instanceof Bitmap) && Utils.saveTempImage(this, (Bitmap)cardImageFrontObj, TEMP_UNSAVED_FRONT_IMAGE_NAME, TEMP_UNSAVED_IMAGE_FORMAT) != null){
+ savedInstanceState.putInt(STATE_FRONT_IMAGE_UNSAVED, 1);
+ }else{
+ savedInstanceState.putInt(STATE_FRONT_IMAGE_UNSAVED, 0);
+ }
+ Object cardImageBackObj = cardImageBack.getTag();
+ if (mBackImageUnsaved && (cardImageBackObj instanceof Bitmap) && Utils.saveTempImage(this, (Bitmap)cardImageBackObj, TEMP_UNSAVED_BACK_IMAGE_NAME, TEMP_UNSAVED_IMAGE_FORMAT) != null){
+ savedInstanceState.putInt(STATE_BACK_IMAGE_UNSAVED, 1);
+ }else{
+ savedInstanceState.putInt(STATE_BACK_IMAGE_UNSAVED, 0);
+ }
+ savedInstanceState.putInt(STATE_UPDATE_LOYALTY_CARD, updateLoyaltyCard ? 1 : 0);
+ savedInstanceState.putInt(STATE_HAS_CHANGED, hasChanged? 1:0);
}
@Override
@@ -216,7 +238,10 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
tabs = findViewById(R.id.tabs);
tabs.selectTab(tabs.getTabAt(savedInstanceState.getInt(STATE_TAB_INDEX)));
mRequestedImage = savedInstanceState.getInt(STATE_REQUESTED_IMAGE);
- tempCameraPicturePath = savedInstanceState.getString(STATE_TEMP_CAMERA_PICTURE_PATH);
+ mFrontImageUnsaved = savedInstanceState.getInt(STATE_FRONT_IMAGE_UNSAVED) == 1;
+ mBackImageUnsaved = savedInstanceState.getInt(STATE_BACK_IMAGE_UNSAVED) == 1;
+ updateLoyaltyCard = savedInstanceState.getInt(STATE_UPDATE_LOYALTY_CARD) == 1;
+ hasChanged = savedInstanceState.getInt(STATE_HAS_CHANGED) == 1;
}
@Override
@@ -438,7 +463,6 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
if (!lastValue.toString().equals(getString(R.string.setBarcodeId))) {
barcodeIdField.setText(lastValue);
}
- ;
AlertDialog.Builder builder = new AlertDialog.Builder(LoyaltyCardEditActivity.this);
builder.setTitle(R.string.setBarcodeId);
@@ -531,13 +555,14 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
tabs.selectTab(tabs.getTabAt(0));
- mPhotoTakerLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
- if (result.getResultCode() == RESULT_OK) {
- startCropper(tempCameraPicturePath);
- }
+ mPhotoTakerLauncher = registerForActivityResult(new ActivityResultContracts.TakePicture(), result->{
+ if (result) {
+ startCropper(getCacheDir() + "/" + TEMP_CAMERA_IMAGE_NAME);
+ }
});
+ // android 11: wanted to swap it to ActivityResultContracts.GetContent but then it shows a file browsers that shows image mime types, offering gallery in the file browser
mPhotoPickerLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == RESULT_OK) {
Intent intent = result.getData();
@@ -548,7 +573,6 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
Uri uri = intent.getData();
startCropperUri(uri);
}
-
});
mCardIdAndBarCodeEditorLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
@@ -577,25 +601,20 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
if (debugUri == null){
throw new RuntimeException("ucrop returned success but not destination uri!");
}
- String cropOutputPath = debugUri.getPath();
- Log.d("cropper", "cropper has produced image at " + debugUri.toString());
- Bitmap bitmap = BitmapFactory.decodeFile(cropOutputPath);
-
+ Log.d("cropper", "ucrop produced image at " + debugUri);
+ Bitmap bitmap = BitmapFactory.decodeFile(getCacheDir() + "/" + TEMP_CROP_IMAGE_NAME);
if (bitmap != null) {
bitmap = Utils.resizeBitmap(bitmap);
- try {
- bitmap = Utils.rotateBitmap(bitmap, new ExifInterface(cropOutputPath));
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- if (mRequestedImage == Utils.CARD_IMAGE_FROM_CAMERA_FRONT || mRequestedImage == Utils.CARD_IMAGE_FROM_FILE_FRONT) {
+ if (requestedFrontImage()) {
+ mFrontImageUnsaved = true;
setCardImage(cardImageFront, bitmap);
} else {
+ mBackImageUnsaved = true;
setCardImage(cardImageBack, bitmap);
}
-
+ Log.d("cropper", "mRequestedImage: " + mRequestedImage);
+ mCropperFinishedType = mRequestedImage;
hasChanged = true;
} else {
Toast.makeText(LoyaltyCardEditActivity.this, R.string.errorReadingImage, Toast.LENGTH_LONG).show();
@@ -615,7 +634,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
}
private void setCropperOptions(){
- mCropperOptions.setCompressionFormat(Bitmap.CompressFormat.JPEG);
+ mCropperOptions.setCompressionFormat(TEMP_CROP_IMAGE_FORMAT);
mCropperOptions.setFreeStyleCropEnabled(true);
mCropperOptions.setHideBottomControls(false);
// needed when bottom controls are hidden
@@ -641,6 +660,18 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
extractIntentFields(intent);
}
+ private boolean requestedFrontImage(){
+ return mRequestedImage == Utils.CARD_IMAGE_FROM_CAMERA_FRONT || mRequestedImage == Utils.CARD_IMAGE_FROM_FILE_FRONT;
+ }
+
+ private boolean croppedFrontImage(){
+ return mCropperFinishedType == Utils.CARD_IMAGE_FROM_CAMERA_FRONT || mCropperFinishedType == Utils.CARD_IMAGE_FROM_FILE_FRONT;
+ }
+
+ private boolean croppedBackImage(){
+ return mCropperFinishedType == Utils.CARD_IMAGE_FROM_CAMERA_BACK || mCropperFinishedType == Utils.CARD_IMAGE_FROM_FILE_BACK;
+ }
+
@SuppressLint("DefaultLocale")
@Override
public void onResume() {
@@ -650,6 +681,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
onResuming = true;
+
if (tempLoyaltyCard == null) {
if (updateLoyaltyCard) {
tempLoyaltyCard = db.getLoyaltyCard(loyaltyCardId);
@@ -659,9 +691,6 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
finish();
return;
}
- setTitle(R.string.editCardTitle);
- setCardImage(cardImageFront, Utils.retrieveCardImage(this, tempLoyaltyCard.id, true));
- setCardImage(cardImageBack, Utils.retrieveCardImage(this, tempLoyaltyCard.id, false));
} else if (importLoyaltyCardUri != null) {
try {
tempLoyaltyCard = importUriHelper.parse(importLoyaltyCardUri);
@@ -670,14 +699,37 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
finish();
return;
}
- setTitle(R.string.addCardTitle);
} else {
// New card, use default values
tempLoyaltyCard = new LoyaltyCard(-1, "", "", null, new BigDecimal("0"), null, "", null, null, null, 0, Utils.getUnixTime(),100);
- setTitle(R.string.addCardTitle);
+
}
}
+ if(!initDone) {
+ if (updateLoyaltyCard) {
+ setTitle(R.string.editCardTitle);
+ if (!mFrontImageUnsaved && !croppedFrontImage()) {
+ setCardImage(cardImageFront, Utils.retrieveCardImage(this, tempLoyaltyCard.id, true));
+ }
+ if (!mBackImageUnsaved && !croppedBackImage()) {
+ setCardImage(cardImageBack, Utils.retrieveCardImage(this, tempLoyaltyCard.id, false));
+ }
+ }else{
+ setTitle(R.string.addCardTitle);
+ }
+ if(mFrontImageUnsaved && !croppedFrontImage()){
+ setCardImage(cardImageFront, Utils.loadTempImage(this, TEMP_UNSAVED_FRONT_IMAGE_NAME));
+ }
+ if(mBackImageUnsaved && !croppedBackImage()){
+ setCardImage(cardImageBack, Utils.loadTempImage(this, TEMP_UNSAVED_BACK_IMAGE_NAME));
+ }
+ }
+
+ mCropperFinishedType = 0;
+
+ boolean hadChanges = hasChanged;
+
storeFieldEdit.setText(tempLoyaltyCard.store);
noteFieldEdit.setText(tempLoyaltyCard.note);
formatExpiryField(this, expiryField, tempLoyaltyCard.expiry);
@@ -767,8 +819,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
// Initialization has finished
if (!initDone) {
- hasChanged = false;
initDone = true;
+ hasChanged = hadChanges;
}
generateOrHideBarcode();
@@ -908,26 +960,13 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
confirmExitDialog.show();
}
- private File createTempFile(String prefix, String suffix) throws IOException{
- String imageFileName = prefix + new Date().getTime();
- return File.createTempFile(
- imageFileName,
- suffix,
- getExternalFilesDir(Environment.DIRECTORY_PICTURES)
- );
- }
+
private void takePhotoForCard(int type) throws IOException {
- Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
-
- File image = createTempFile("CATIMA_", ".jpg");
-
- tempCameraPicturePath = image.getAbsolutePath();
-
- Uri photoURI = FileProvider.getUriForFile(LoyaltyCardEditActivity.this, BuildConfig.APPLICATION_ID, image);
- i.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
+ Uri photoURI = FileProvider.getUriForFile(LoyaltyCardEditActivity.this, BuildConfig.APPLICATION_ID, Utils.createTempFile(this, TEMP_CAMERA_IMAGE_NAME));
mRequestedImage = type;
- mPhotoTakerLauncher.launch(i);
+
+ mPhotoTakerLauncher.launch(photoURI);
}
class EditCardIdAndBarcode implements View.OnClickListener {
@@ -1168,12 +1207,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
public void startCropperUri(Uri sourceUri){
Log.d("cropper", "launching cropper with image " + sourceUri.getPath());
File cropOutput;
- try {
- cropOutput = createTempFile("UCROP_", ".jpg");
- }catch(java.io.IOException e){
- Log.e("image cropping", "failed creating temporarily file");
- return;
- }
+ cropOutput = Utils.createTempFile(this, TEMP_CROP_IMAGE_NAME);
Uri destUri = Uri.parse("file://" + cropOutput.getAbsolutePath());
Log.d("cropper", "asking cropper to output to " + destUri.toString());
diff --git a/app/src/main/java/protect/card_locker/Utils.java b/app/src/main/java/protect/card_locker/Utils.java
index 0ab199492..eb889b479 100644
--- a/app/src/main/java/protect/card_locker/Utils.java
+++ b/app/src/main/java/protect/card_locker/Utils.java
@@ -25,6 +25,7 @@ import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@@ -410,10 +411,37 @@ public class Utils {
Configuration config = inputContext.getResources().getConfiguration();
int currentNightMode = config.uiMode & Configuration.UI_MODE_NIGHT_MASK;
return (currentNightMode == Configuration.UI_MODE_NIGHT_YES);
- }else if (nightModeSetting == AppCompatDelegate.MODE_NIGHT_YES){
- return true;
- }else{
- return false;
+ }else {
+ return nightModeSetting == AppCompatDelegate.MODE_NIGHT_YES;
}
}
+
+ public static File createTempFile(Context context, String name){
+ return new File(context.getCacheDir() + "/" + name);
+ }
+
+ public static String saveTempImage(Context context, Bitmap in, String name, Bitmap.CompressFormat format){
+ File image = createTempFile(context, name);
+ try (FileOutputStream out = new FileOutputStream(image)){
+ in.compress(format, 100, out);
+ return image.getAbsolutePath();
+ }catch(IOException e){
+ Log.d("store temp image", "failed writing temp file for temporary image, name: " + name);
+ return null;
+ }
+ }
+
+ public static Bitmap loadImage(String path){
+ try{
+ return BitmapFactory.decodeStream(new FileInputStream(path));
+ }catch(IOException e){
+ Log.d("load image", "failed loading image from " + path);
+ return null;
+ }
+ }
+
+ public static Bitmap loadTempImage(Context context, String name){
+ return loadImage(context.getCacheDir() + "/" + name);
+ }
+
}
diff --git a/app/src/main/res/xml/file_provider_paths.xml b/app/src/main/res/xml/file_provider_paths.xml
index 8bacf6557..3cd946b00 100644
--- a/app/src/main/res/xml/file_provider_paths.xml
+++ b/app/src/main/res/xml/file_provider_paths.xml
@@ -1,3 +1,3 @@
-
+
\ No newline at end of file