From 422caaf41d8cc8cfc3c0c1758f60dcbd1f993d1c Mon Sep 17 00:00:00 2001 From: Lucas Vermersch Date: Tue, 15 Apr 2025 21:37:34 +0200 Subject: [PATCH 1/2] Add copy barcode on long press barcode & description --- .../card_locker/LoyaltyCardViewActivity.java | 26 +++++++++--- app/src/main/res/values/strings.xml | 2 + .../LoyaltyCardViewActivityTest.java | 40 +++++++++++++++++++ 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index 47c9779251..81619adc96 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -1,6 +1,7 @@ package protect.card_locker; import android.content.ActivityNotFoundException; +import android.content.ClipboardManager; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.ColorStateList; @@ -146,6 +147,21 @@ public void onMainImageTap() { openImageInGallery(imageType); } + private boolean onMainImageLongClick(){ + if (imageTypes.get(mainImageIndex) == ImageType.BARCODE) { + String barcodeString = barcodeIdString != null ? barcodeIdString : cardIdString; + ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + if (clipboard != null) { + android.content.ClipData clip = android.content.ClipData.newPlainText("Barcode", barcodeString); + clipboard.setPrimaryClip(clip); + Toast.makeText(this, R.string.copy_success, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(this, R.string.copy_failed, Toast.LENGTH_SHORT).show(); + } + } + return true; + } + private void openImageInGallery(ImageType imageType) { File file = null; @@ -350,12 +366,10 @@ public void onStopTrackingTouch(SeekBar seekBar) { }); binding.mainImage.setOnClickListener(view -> onMainImageTap()); - // This long-press was originally only intended for when Talkback was used but sadly limiting - // this doesn't seem to work well - binding.mainImage.setOnLongClickListener(view -> { - setMainImage(true, true); - return true; - }); + + + binding.mainImage.setOnLongClickListener(view -> onMainImageLongClick()); + binding.mainImageDescription.setOnLongClickListener(view -> onMainImageLongClick()); binding.fullscreenImage.setOnClickListener(view -> onMainImageTap()); getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e782652fd1..3a1ea1b7d4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -361,4 +361,6 @@ Select a Passbook file (.pkpass) This file is not supported Sorry, something went wrong, please try again... + Copied to clipboard + Failed to copy to clipboard diff --git a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java index 2fc8d6121f..c6608e97c3 100644 --- a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java +++ b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java @@ -12,6 +12,8 @@ import android.app.Activity; import android.app.DatePickerDialog; import android.app.Dialog; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -1389,4 +1391,42 @@ public void importCardOldFormat() { checkAllFields(activity, ViewMode.ADD_CARD, "Example Store", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "123456", context.getString(R.string.sameAsCardId), "Aztec", null, null); assertEquals(-416706, ((ColorDrawable) activity.findViewById(R.id.thumbnail).getBackground()).getColor()); } + + + @Test + public void longPressOnBarcodeShouldCopyTheBarcodeValue() { + final Context context = ApplicationProvider.getApplicationContext(); + SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase(); + + long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0, null, 0); + + ActivityController activityController = createActivityWithLoyaltyCard(false, (int) cardId); + Activity activity = (Activity) activityController.get(); + + activityController.start(); + activityController.visible(); + activityController.resume(); + + // Long press on the barcode image should copy the barcode value + ImageView barcodeMainImage = activity.findViewById(R.id.main_image); + barcodeMainImage.performLongClick(); + shadowOf(getMainLooper()).idle(); + // Check if the barcode value is copied to the clipboard + ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clipData = clipboard.getPrimaryClip(); + assertNotNull(clipData); + assertEquals(BARCODE_DATA, clipData.getItemAt(0).getText().toString()); + + //clear the clipboard + clipboard.setPrimaryClip(ClipData.newPlainText("", "")); + + // Long press on the barcode description should copy the barcode value + TextView barcodeTextView = activity.findViewById(R.id.main_image_description); + barcodeTextView.performLongClick(); + shadowOf(getMainLooper()).idle(); + // Check if the barcode value is copied to the clipboard + clipData = clipboard.getPrimaryClip(); + assertNotNull(clipData); + assertEquals(BARCODE_DATA, clipData.getItemAt(0).getText().toString()); + } } From 55ef69e3f876d4a58f8f2c0314b7a3999ca8be53 Mon Sep 17 00:00:00 2001 From: Lucas Vermersch Date: Wed, 16 Apr 2025 07:38:50 +0200 Subject: [PATCH 2/2] Fix --- .../card_locker/LoyaltyCardViewActivity.java | 13 ++++++++++--- app/src/main/res/values/strings.xml | 1 + .../LoyaltyCardViewActivityTest.java | 17 +++++++++++++---- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index 81619adc96..965000277a 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -147,7 +147,7 @@ public void onMainImageTap() { openImageInGallery(imageType); } - private boolean onMainImageLongClick(){ + private boolean copyBarcodeToClipBoard(){ if (imageTypes.get(mainImageIndex) == ImageType.BARCODE) { String barcodeString = barcodeIdString != null ? barcodeIdString : cardIdString; ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); @@ -367,9 +367,15 @@ public void onStopTrackingTouch(SeekBar seekBar) { binding.mainImage.setOnClickListener(view -> onMainImageTap()); + // This long-press was originally only intended for when Talkback was used but sadly limiting + // this doesn't seem to work well + binding.mainImage.setOnLongClickListener(view -> { + setMainImage(true, true); + return true; + }); + + binding.mainImageDescription.setOnLongClickListener(view -> copyBarcodeToClipBoard()); - binding.mainImage.setOnLongClickListener(view -> onMainImageLongClick()); - binding.mainImageDescription.setOnLongClickListener(view -> onMainImageLongClick()); binding.fullscreenImage.setOnClickListener(view -> onMainImageTap()); getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { @@ -712,6 +718,7 @@ protected void onResume() { builder.setTitle(R.string.cardId); builder.setView(cardIdView); builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> dialogInterface.dismiss()); + builder.setNeutralButton(R.string.copy, (dialogInterface, i) -> copyBarcodeToClipBoard()); AlertDialog dialog = builder.create(); dialog.show(); }); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3a1ea1b7d4..bf5bec02f7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -361,6 +361,7 @@ Select a Passbook file (.pkpass) This file is not supported Sorry, something went wrong, please try again... + Copy Copied to clipboard Failed to copy to clipboard diff --git a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java index c6608e97c3..831a822b4d 100644 --- a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java +++ b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java @@ -1407,10 +1407,17 @@ public void longPressOnBarcodeShouldCopyTheBarcodeValue() { activityController.visible(); activityController.resume(); - // Long press on the barcode image should copy the barcode value - ImageView barcodeMainImage = activity.findViewById(R.id.main_image); - barcodeMainImage.performLongClick(); + // Short press on description to open the modal + TextView barcodeTextView = activity.findViewById(R.id.main_image_description); + barcodeTextView.performClick(); + shadowOf(getMainLooper()).idle(); + + // click on the copy neutral button + AlertDialog barcodeDialog = (AlertDialog) (ShadowDialog.getLatestDialog()); + assertNotNull(barcodeDialog); + barcodeDialog.getButton(AlertDialog.BUTTON_NEUTRAL).performClick(); shadowOf(getMainLooper()).idle(); + // Check if the barcode value is copied to the clipboard ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); ClipData clipData = clipboard.getPrimaryClip(); @@ -1420,8 +1427,10 @@ public void longPressOnBarcodeShouldCopyTheBarcodeValue() { //clear the clipboard clipboard.setPrimaryClip(ClipData.newPlainText("", "")); + //quit the dialog + barcodeDialog.dismiss(); + // Long press on the barcode description should copy the barcode value - TextView barcodeTextView = activity.findViewById(R.id.main_image_description); barcodeTextView.performLongClick(); shadowOf(getMainLooper()).idle(); // Check if the barcode value is copied to the clipboard