From 4b58f7442170eae87908a112739fe063559b8484 Mon Sep 17 00:00:00 2001 From: JorySeverijnse Date: Mon, 11 May 2026 13:50:44 +0200 Subject: [PATCH 1/5] Add barcode widget for displaying loyalty card barcodes on home screen --- app/src/main/AndroidManifest.xml | 22 ++ .../java/protect/card_locker/BarcodeWidget.kt | 189 ++++++++++++++++++ .../BarcodeWidgetConfigureActivity.kt | 83 ++++++++ app/src/main/res/layout/barcode_widget.xml | 34 ++++ .../barcode_widget_configure_activity.xml | 35 ++++ app/src/main/res/values/strings.xml | 3 + app/src/main/res/xml/barcode_widget_info.xml | 13 ++ 7 files changed, 379 insertions(+) create mode 100644 app/src/main/java/protect/card_locker/BarcodeWidget.kt create mode 100644 app/src/main/java/protect/card_locker/BarcodeWidgetConfigureActivity.kt create mode 100644 app/src/main/res/layout/barcode_widget.xml create mode 100644 app/src/main/res/layout/barcode_widget_configure_activity.xml create mode 100644 app/src/main/res/xml/barcode_widget_info.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ed2c6f41ff..dba1631f26 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,6 +48,19 @@ android:resource="@xml/list_widget_info" /> + + + + + + + + + + + + + () + // Only pass encoding hint if not ISO-8859-1, to avoid ECI issues + if (encoding.name() != "ISO-8859-1") { + encodeHints[EncodeHintType.CHARACTER_SET] = encoding.name() + } + + val bitMatrix = try { + if (encodeHints.isNotEmpty()) { + writer.encode(cardId, format.format(), finalWidth, finalHeight, encodeHints) + } else { + writer.encode(cardId, format.format(), finalWidth, finalHeight) + } + } catch (e: WriterException) { + return null + } catch (e: Exception) { + return null + } + + bitmapFromBitMatrix(bitMatrix) + } catch (e: OutOfMemoryError) { + null + } + } + + private fun bitmapFromBitMatrix(bitMatrix: BitMatrix): Bitmap { + val width = bitMatrix.width + val height = bitMatrix.height + val pixels = IntArray(width * height) + + for (y in 0 until height) { + val offset = y * width + for (x in 0 until width) { + pixels[offset + x] = if (bitMatrix.get(x, y)) Color.BLACK else Color.WHITE + } + } + + val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + bitmap.setPixels(pixels, 0, width, 0, 0, width, height) + return bitmap + } + + companion object { + private const val PREFS_NAME = "barcode_widget_prefs" + private const val PREFS_CARD_ID_PREFIX = "card_id_" + + fun saveCardPref(context: Context, appWidgetId: Int, cardId: Int) { + context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + .edit() + .putInt(PREFS_CARD_ID_PREFIX + appWidgetId, cardId) + .apply() + } + + fun triggerUpdate(context: Context) { + val appWidgetManager = AppWidgetManager.getInstance(context) + val componentName = ComponentName(context, BarcodeWidget::class.java) + val appWidgetIds = appWidgetManager.getAppWidgetIds(componentName) + if (appWidgetIds.isNotEmpty()) { + BarcodeWidget().onUpdate(context, appWidgetManager, appWidgetIds) + } + } + } +} diff --git a/app/src/main/java/protect/card_locker/BarcodeWidgetConfigureActivity.kt b/app/src/main/java/protect/card_locker/BarcodeWidgetConfigureActivity.kt new file mode 100644 index 0000000000..a24fb41d15 --- /dev/null +++ b/app/src/main/java/protect/card_locker/BarcodeWidgetConfigureActivity.kt @@ -0,0 +1,83 @@ +package protect.card_locker + +import android.appwidget.AppWidgetManager +import android.content.Intent +import android.database.sqlite.SQLiteDatabase +import android.os.Bundle +import android.widget.Toast +import androidx.recyclerview.widget.GridLayoutManager +import protect.card_locker.databinding.BarcodeWidgetConfigureActivityBinding +import protect.card_locker.preferences.Settings + +class BarcodeWidgetConfigureActivity : CatimaAppCompatActivity(), + LoyaltyCardCursorAdapter.CardAdapterListener { + + private lateinit var binding: BarcodeWidgetConfigureActivityBinding + private lateinit var mDatabase: SQLiteDatabase + private lateinit var mAdapter: LoyaltyCardCursorAdapter + private var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = BarcodeWidgetConfigureActivityBinding.inflate(layoutInflater) + mDatabase = DBHelper(this).readableDatabase + + appWidgetId = intent?.getIntExtra( + AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID + ) ?: AppWidgetManager.INVALID_APPWIDGET_ID + + if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { + setResult(RESULT_CANCELED) + finish() + return + } + + setResult(RESULT_CANCELED) + + setContentView(binding.root) + Utils.applyWindowInsets(binding.root) + + binding.toolbar.apply { + setTitle(R.string.barcode_widget_configure_title) + setSupportActionBar(this) + } + + if (DBHelper.getLoyaltyCardCount(mDatabase) == 0) { + Toast.makeText(this, R.string.noCardsMessage, Toast.LENGTH_LONG).show() + finish() + return + } + + val cardCursor = DBHelper.getLoyaltyCardCursor(mDatabase) + mAdapter = LoyaltyCardCursorAdapter(this, cardCursor, this, null) + binding.list.adapter = mAdapter + } + + override fun onResume() { + super.onResume() + val layoutManager = binding.list.layoutManager as GridLayoutManager? + layoutManager?.spanCount = Settings(this).getPreferredColumnCount() + } + + override fun onRowClicked(position: Int) { + val cursor = DBHelper.getLoyaltyCardCursor(mDatabase) + cursor.moveToPosition(position) + val card = LoyaltyCard.fromCursor(this, cursor) + + BarcodeWidget.saveCardPref(this, appWidgetId, card.id) + + val appWidgetManager = AppWidgetManager.getInstance(this) + BarcodeWidget().onUpdate(this, appWidgetManager, intArrayOf(appWidgetId)) + + val resultValue = Intent().putExtra( + AppWidgetManager.EXTRA_APPWIDGET_ID, + appWidgetId + ) + setResult(RESULT_OK, resultValue) + finish() + } + + override fun onRowLongClicked(position: Int) { + } +} diff --git a/app/src/main/res/layout/barcode_widget.xml b/app/src/main/res/layout/barcode_widget.xml new file mode 100644 index 0000000000..efc3a16170 --- /dev/null +++ b/app/src/main/res/layout/barcode_widget.xml @@ -0,0 +1,34 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/barcode_widget_configure_activity.xml b/app/src/main/res/layout/barcode_widget_configure_activity.xml new file mode 100644 index 0000000000..07f2559b2d --- /dev/null +++ b/app/src/main/res/layout/barcode_widget_configure_activity.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6b3b8ce3b6..383d71dfc0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -335,6 +335,9 @@ Card list Set barcode width After you add some loyalty cards in Catima, they will appear here. If you have cards, make sure they are not all archived. + Barcode + Select a card for the barcode widget + Configure barcode widget Card %d Card %d (%s) Please do not rotate the device, as this will cancel the action diff --git a/app/src/main/res/xml/barcode_widget_info.xml b/app/src/main/res/xml/barcode_widget_info.xml new file mode 100644 index 0000000000..58f071c8ff --- /dev/null +++ b/app/src/main/res/xml/barcode_widget_info.xml @@ -0,0 +1,13 @@ + + From 4b836903c70b67f466ec3e9b2cad36e96b266c24 Mon Sep 17 00:00:00 2001 From: JorySeverijnse Date: Mon, 11 May 2026 14:14:29 +0200 Subject: [PATCH 2/5] Refactor barcode generation to use fixed dimensions and add optional format display setting --- .../java/protect/card_locker/BarcodeWidget.kt | 58 ++++++------------- .../card_locker/preferences/Settings.java | 4 ++ .../preferences/SettingsActivity.kt | 7 +++ app/src/main/res/layout/barcode_widget.xml | 7 ++- app/src/main/res/values/strings.xml | 3 + app/src/main/res/xml/barcode_widget_info.xml | 8 +-- app/src/main/res/xml/preferences.xml | 9 +++ 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/protect/card_locker/BarcodeWidget.kt b/app/src/main/java/protect/card_locker/BarcodeWidget.kt index 7087ec8d58..215527f3ee 100644 --- a/app/src/main/java/protect/card_locker/BarcodeWidget.kt +++ b/app/src/main/java/protect/card_locker/BarcodeWidget.kt @@ -12,6 +12,7 @@ import com.google.zxing.EncodeHintType import com.google.zxing.MultiFormatWriter import com.google.zxing.WriterException import com.google.zxing.common.BitMatrix +import protect.card_locker.preferences.Settings import java.nio.charset.Charset class BarcodeWidget : AppWidgetProvider() { @@ -52,18 +53,9 @@ class BarcodeWidget : AppWidgetProvider() { return } - val options = appWidgetManager.getAppWidgetOptions(appWidgetId) - val minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, 250) - val minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, 120) - - val barcodeBitmap = generateBarcode( - context, - cardIdStr, - barcodeType, - card.barcodeEncoding, - minWidth, - minHeight - ) + val showFormat = Settings(context).showBarcodeWidgetFormat() + + val barcodeBitmap = generateBarcode(cardIdStr, barcodeType, card.barcodeEncoding) val views = RemoteViews(context.packageName, R.layout.barcode_widget) views.setTextViewText(R.id.store_name, card.store) @@ -75,10 +67,12 @@ class BarcodeWidget : AppWidgetProvider() { views.setViewVisibility(R.id.barcode_image, View.GONE) } - views.setTextViewText( - R.id.barcode_format, - barcodeType.prettyName() - ) + if (showFormat) { + views.setTextViewText(R.id.barcode_format, barcodeType.prettyName()) + views.setViewVisibility(R.id.barcode_format, View.VISIBLE) + } else { + views.setViewVisibility(R.id.barcode_format, View.GONE) + } appWidgetManager.updateAppWidget(appWidgetId, views) } @@ -90,52 +84,34 @@ class BarcodeWidget : AppWidgetProvider() { context.getString(R.string.barcode_widget_not_configured) ) views.setViewVisibility(R.id.barcode_image, View.GONE) - views.setTextViewText(R.id.barcode_format, "") + views.setViewVisibility(R.id.barcode_format, View.GONE) return views } private fun generateBarcode( - context: Context, cardId: String, format: CatimaBarcode, - encoding: Charset, - widgetWidthDp: Int, - widgetHeightDp: Int + encoding: Charset ): Bitmap? { if (cardId.isEmpty()) return null - val metrics = context.resources.displayMetrics - val density = metrics.density - - val widthPx = (widgetWidthDp * density).toInt() - val heightPx = (widgetHeightDp * density).toInt() - - val textAreaPx = (40 * density).toInt() - val paddingPx = (16 * density).toInt() - - val barcodeWidth = widthPx - paddingPx - val barcodeHeight = heightPx - textAreaPx - - if (barcodeWidth <= 0 || barcodeHeight <= 0) return null - - val maxWidth = if (format.isSquare()) 500 else 1500 - val finalWidth = minOf(barcodeWidth, maxWidth) - val finalHeight = if (format.isSquare()) finalWidth else minOf(barcodeHeight, 500) + val isSquare = format.isSquare() + val genWidth = if (isSquare) 500 else 1000 + val genHeight = if (isSquare) 500 else 300 return try { val writer = MultiFormatWriter() val encodeHints = mutableMapOf() - // Only pass encoding hint if not ISO-8859-1, to avoid ECI issues if (encoding.name() != "ISO-8859-1") { encodeHints[EncodeHintType.CHARACTER_SET] = encoding.name() } val bitMatrix = try { if (encodeHints.isNotEmpty()) { - writer.encode(cardId, format.format(), finalWidth, finalHeight, encodeHints) + writer.encode(cardId, format.format(), genWidth, genHeight, encodeHints) } else { - writer.encode(cardId, format.format(), finalWidth, finalHeight) + writer.encode(cardId, format.format(), genWidth, genHeight) } } catch (e: WriterException) { return null diff --git a/app/src/main/java/protect/card_locker/preferences/Settings.java b/app/src/main/java/protect/card_locker/preferences/Settings.java index f77f4b359f..dc4df14eb3 100644 --- a/app/src/main/java/protect/card_locker/preferences/Settings.java +++ b/app/src/main/java/protect/card_locker/preferences/Settings.java @@ -112,4 +112,8 @@ public int getPreferredColumnCount() { public boolean useVolumeKeysForNavigation() { return getBoolean(R.string.settings_key_use_volume_keys_navigation, false); } + + public boolean showBarcodeWidgetFormat() { + return getBoolean(R.string.settings_key_barcode_widget_show_format, false); + } } diff --git a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt index 8d48320d22..4390a9d716 100644 --- a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt +++ b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt @@ -11,6 +11,7 @@ import androidx.core.os.LocaleListCompat import androidx.preference.ListPreference import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import protect.card_locker.BarcodeWidget import protect.card_locker.BuildConfig import protect.card_locker.CatimaAppCompatActivity import protect.card_locker.MainActivity @@ -160,6 +161,12 @@ class SettingsActivity : CatimaAppCompatActivity() { // Hide crash reporter settings on builds it's not enabled on val crashReporterPreference = findPreference("acra.enable") crashReporterPreference!!.isVisible = BuildConfig.useAcraCrashReporter + + val barcodeFormatPreference = findPreference(getString(R.string.settings_key_barcode_widget_show_format)) + barcodeFormatPreference?.setOnPreferenceChangeListener { _, _ -> + activity?.let { BarcodeWidget.triggerUpdate(it) } + true + } } private fun refreshActivity(reloadMain: Boolean) { diff --git a/app/src/main/res/layout/barcode_widget.xml b/app/src/main/res/layout/barcode_widget.xml index efc3a16170..6f083194ad 100644 --- a/app/src/main/res/layout/barcode_widget.xml +++ b/app/src/main/res/layout/barcode_widget.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:orientation="vertical" android:gravity="center_horizontal" - android:padding="8dp"> + android:padding="4dp"> + android:textSize="11sp" + android:gravity="center" + android:visibility="gone" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 383d71dfc0..1ec650d0b5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -112,6 +112,7 @@ Switch cards using volume buttons Use the volume buttons to change which card is displayed pref_use_volume_keys_navigation + pref_barcode_widget_show_format sharedpreference_active_tab sharedpreference_sort sharedpreference_sort_order @@ -350,6 +351,8 @@ Copied to clipboard No value found Barcode encoding + Show barcode type on widget + Display the barcode format name below the barcode on the home screen widget Back NFC is paused Change settings diff --git a/app/src/main/res/xml/barcode_widget_info.xml b/app/src/main/res/xml/barcode_widget_info.xml index 58f071c8ff..f54bbeef1e 100644 --- a/app/src/main/res/xml/barcode_widget_info.xml +++ b/app/src/main/res/xml/barcode_widget_info.xml @@ -3,11 +3,11 @@ android:configure="protect.card_locker.BarcodeWidgetConfigureActivity" android:initialKeyguardLayout="@layout/barcode_widget" android:initialLayout="@layout/barcode_widget" - android:minWidth="250dp" - android:minHeight="120dp" + android:minWidth="80dp" + android:minHeight="80dp" android:previewImage="@drawable/widget_preview" android:resizeMode="horizontal|vertical" - android:targetCellWidth="4" - android:targetCellHeight="2" + android:targetCellWidth="1" + android:targetCellHeight="1" android:updatePeriodMillis="86400000" android:widgetCategory="home_screen" /> diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index fec2bce50f..2fc2cc517a 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -118,6 +118,15 @@ android:title="@string/settings_disable_nfc_while_viewing_card" app:iconSpaceReserved="false" app:singleLineTitle="false" /> + + Date: Mon, 11 May 2026 14:35:10 +0200 Subject: [PATCH 3/5] Fix widget resize handling and correct inverted format toggle behavior --- .../java/protect/card_locker/BarcodeWidget.kt | 87 +++++++++++++++---- .../preferences/SettingsActivity.kt | 11 ++- 2 files changed, 78 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/protect/card_locker/BarcodeWidget.kt b/app/src/main/java/protect/card_locker/BarcodeWidget.kt index 215527f3ee..3a794950a9 100644 --- a/app/src/main/java/protect/card_locker/BarcodeWidget.kt +++ b/app/src/main/java/protect/card_locker/BarcodeWidget.kt @@ -1,36 +1,49 @@ package protect.card_locker +import android.app.PendingIntent import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetProvider import android.content.ComponentName import android.content.Context +import android.content.Intent import android.graphics.Bitmap import android.graphics.Color +import android.graphics.Matrix +import android.os.Bundle import android.view.View import android.widget.RemoteViews import com.google.zxing.EncodeHintType import com.google.zxing.MultiFormatWriter import com.google.zxing.WriterException import com.google.zxing.common.BitMatrix +import protect.card_locker.cardview.LoyaltyCardViewActivity import protect.card_locker.preferences.Settings import java.nio.charset.Charset class BarcodeWidget : AppWidgetProvider() { - override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, - appWidgetIds: IntArray + appWidgetIds: IntArray, ) { for (appWidgetId in appWidgetIds) { updateWidget(context, appWidgetManager, appWidgetId) } } + override fun onAppWidgetOptionsChanged( + context: Context, + appWidgetManager: AppWidgetManager, + appWidgetId: Int, + newOptions: Bundle?, + ) { + updateWidget(context, appWidgetManager, appWidgetId) + } + private fun updateWidget( context: Context, appWidgetManager: AppWidgetManager, - appWidgetId: Int + appWidgetId: Int, ) { val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) val cardId = prefs.getInt(PREFS_CARD_ID_PREFIX + appWidgetId, -1) @@ -55,7 +68,16 @@ class BarcodeWidget : AppWidgetProvider() { val showFormat = Settings(context).showBarcodeWidgetFormat() - val barcodeBitmap = generateBarcode(cardIdStr, barcodeType, card.barcodeEncoding) + val options = appWidgetManager.getAppWidgetOptions(appWidgetId) + val isVertical = + options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, 0) > + options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, 0) + + var barcodeBitmap = generateBarcode(cardIdStr, barcodeType, card.barcodeEncoding) + + if (barcodeBitmap != null && isVertical && !barcodeType.isSquare()) { + barcodeBitmap = rotateBitmap(barcodeBitmap, 90f) + } val views = RemoteViews(context.packageName, R.layout.barcode_widget) views.setTextViewText(R.id.store_name, card.store) @@ -74,6 +96,20 @@ class BarcodeWidget : AppWidgetProvider() { views.setViewVisibility(R.id.barcode_format, View.GONE) } + val cardIntent = + Intent(context, LoyaltyCardViewActivity::class.java).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + putExtra(LoyaltyCardViewActivity.BUNDLE_ID, card.id) + } + val pendingIntent = + PendingIntent.getActivity( + context, + 0, + cardIntent, + PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT, + ) + views.setOnClickPendingIntent(R.id.widget_layout, pendingIntent) + appWidgetManager.updateAppWidget(appWidgetId, views) } @@ -81,7 +117,7 @@ class BarcodeWidget : AppWidgetProvider() { val views = RemoteViews(context.packageName, R.layout.barcode_widget) views.setTextViewText( R.id.store_name, - context.getString(R.string.barcode_widget_not_configured) + context.getString(R.string.barcode_widget_not_configured), ) views.setViewVisibility(R.id.barcode_image, View.GONE) views.setViewVisibility(R.id.barcode_format, View.GONE) @@ -91,7 +127,7 @@ class BarcodeWidget : AppWidgetProvider() { private fun generateBarcode( cardId: String, format: CatimaBarcode, - encoding: Charset + encoding: Charset, ): Bitmap? { if (cardId.isEmpty()) return null @@ -107,17 +143,18 @@ class BarcodeWidget : AppWidgetProvider() { encodeHints[EncodeHintType.CHARACTER_SET] = encoding.name() } - val bitMatrix = try { - if (encodeHints.isNotEmpty()) { - writer.encode(cardId, format.format(), genWidth, genHeight, encodeHints) - } else { - writer.encode(cardId, format.format(), genWidth, genHeight) + val bitMatrix = + try { + if (encodeHints.isNotEmpty()) { + writer.encode(cardId, format.format(), genWidth, genHeight, encodeHints) + } else { + writer.encode(cardId, format.format(), genWidth, genHeight) + } + } catch (e: WriterException) { + return null + } catch (e: Exception) { + return null } - } catch (e: WriterException) { - return null - } catch (e: Exception) { - return null - } bitmapFromBitMatrix(bitMatrix) } catch (e: OutOfMemoryError) { @@ -125,6 +162,15 @@ class BarcodeWidget : AppWidgetProvider() { } } + private fun rotateBitmap( + bitmap: Bitmap, + degrees: Float, + ): Bitmap { + val matrix = Matrix() + matrix.postRotate(degrees) + return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) + } + private fun bitmapFromBitMatrix(bitMatrix: BitMatrix): Bitmap { val width = bitMatrix.width val height = bitMatrix.height @@ -146,8 +192,13 @@ class BarcodeWidget : AppWidgetProvider() { private const val PREFS_NAME = "barcode_widget_prefs" private const val PREFS_CARD_ID_PREFIX = "card_id_" - fun saveCardPref(context: Context, appWidgetId: Int, cardId: Int) { - context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + fun saveCardPref( + context: Context, + appWidgetId: Int, + cardId: Int, + ) { + context + .getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) .edit() .putInt(PREFS_CARD_ID_PREFIX + appWidgetId, cardId) .apply() diff --git a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt index 4390a9d716..9049335f3c 100644 --- a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt +++ b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt @@ -11,6 +11,7 @@ import androidx.core.os.LocaleListCompat import androidx.preference.ListPreference import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import androidx.preference.PreferenceManager import protect.card_locker.BarcodeWidget import protect.card_locker.BuildConfig import protect.card_locker.CatimaAppCompatActivity @@ -163,8 +164,14 @@ class SettingsActivity : CatimaAppCompatActivity() { crashReporterPreference!!.isVisible = BuildConfig.useAcraCrashReporter val barcodeFormatPreference = findPreference(getString(R.string.settings_key_barcode_widget_show_format)) - barcodeFormatPreference?.setOnPreferenceChangeListener { _, _ -> - activity?.let { BarcodeWidget.triggerUpdate(it) } + barcodeFormatPreference?.setOnPreferenceChangeListener { _, newValue -> + activity?.let { activity -> + PreferenceManager.getDefaultSharedPreferences(activity) + .edit() + .putBoolean(activity.getString(R.string.settings_key_barcode_widget_show_format), newValue as Boolean) + .apply() + BarcodeWidget.triggerUpdate(activity) + } true } } From 37e067ce71e225ebc0b0a28cca0be0c8e6e0d934 Mon Sep 17 00:00:00 2001 From: Jory Severijnse Date: Mon, 29 Jun 2026 01:07:07 +0200 Subject: [PATCH 4/5] refactor: Show format toggle on barcode widget removed --- .../java/protect/card_locker/BarcodeWidget.kt | 11 ---- .../card_locker/preferences/Settings.java | 4 -- .../preferences/SettingsActivity.kt | 63 ++++++++++--------- app/src/main/res/layout/barcode_widget.xml | 8 --- app/src/main/res/values/strings.xml | 3 - app/src/main/res/xml/preferences.xml | 9 --- 6 files changed, 33 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/protect/card_locker/BarcodeWidget.kt b/app/src/main/java/protect/card_locker/BarcodeWidget.kt index 3a794950a9..94bb1ef216 100644 --- a/app/src/main/java/protect/card_locker/BarcodeWidget.kt +++ b/app/src/main/java/protect/card_locker/BarcodeWidget.kt @@ -17,7 +17,6 @@ import com.google.zxing.MultiFormatWriter import com.google.zxing.WriterException import com.google.zxing.common.BitMatrix import protect.card_locker.cardview.LoyaltyCardViewActivity -import protect.card_locker.preferences.Settings import java.nio.charset.Charset class BarcodeWidget : AppWidgetProvider() { @@ -66,8 +65,6 @@ class BarcodeWidget : AppWidgetProvider() { return } - val showFormat = Settings(context).showBarcodeWidgetFormat() - val options = appWidgetManager.getAppWidgetOptions(appWidgetId) val isVertical = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, 0) > @@ -89,13 +86,6 @@ class BarcodeWidget : AppWidgetProvider() { views.setViewVisibility(R.id.barcode_image, View.GONE) } - if (showFormat) { - views.setTextViewText(R.id.barcode_format, barcodeType.prettyName()) - views.setViewVisibility(R.id.barcode_format, View.VISIBLE) - } else { - views.setViewVisibility(R.id.barcode_format, View.GONE) - } - val cardIntent = Intent(context, LoyaltyCardViewActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK @@ -120,7 +110,6 @@ class BarcodeWidget : AppWidgetProvider() { context.getString(R.string.barcode_widget_not_configured), ) views.setViewVisibility(R.id.barcode_image, View.GONE) - views.setViewVisibility(R.id.barcode_format, View.GONE) return views } diff --git a/app/src/main/java/protect/card_locker/preferences/Settings.java b/app/src/main/java/protect/card_locker/preferences/Settings.java index dc4df14eb3..f77f4b359f 100644 --- a/app/src/main/java/protect/card_locker/preferences/Settings.java +++ b/app/src/main/java/protect/card_locker/preferences/Settings.java @@ -112,8 +112,4 @@ public int getPreferredColumnCount() { public boolean useVolumeKeysForNavigation() { return getBoolean(R.string.settings_key_use_volume_keys_navigation, false); } - - public boolean showBarcodeWidgetFormat() { - return getBoolean(R.string.settings_key_barcode_widget_show_format, false); - } } diff --git a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt index 9049335f3c..23804de358 100644 --- a/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt +++ b/app/src/main/java/protect/card_locker/preferences/SettingsActivity.kt @@ -11,8 +11,6 @@ import androidx.core.os.LocaleListCompat import androidx.preference.ListPreference import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat -import androidx.preference.PreferenceManager -import protect.card_locker.BarcodeWidget import protect.card_locker.BuildConfig import protect.card_locker.CatimaAppCompatActivity import protect.card_locker.MainActivity @@ -21,7 +19,6 @@ import protect.card_locker.Utils import protect.card_locker.databinding.SettingsActivityBinding class SettingsActivity : CatimaAppCompatActivity() { - private lateinit var binding: SettingsActivityBinding private lateinit var fragment: SettingsFragment @@ -37,7 +34,8 @@ class SettingsActivity : CatimaAppCompatActivity() { // Display the fragment as the main content. fragment = SettingsFragment() - supportFragmentManager.beginTransaction() + supportFragmentManager + .beginTransaction() .replace(R.id.settings_container, fragment) .commit() @@ -46,11 +44,14 @@ class SettingsActivity : CatimaAppCompatActivity() { fragment.mReloadMain = savedInstanceState.getBoolean(RELOAD_MAIN_STATE) } - onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { - override fun handleOnBackPressed() { - finishSettingsActivity() - } - }) + onBackPressedDispatcher.addCallback( + this, + object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + finishSettingsActivity() + } + }, + ) } override fun onSaveInstanceState(outState: Bundle) { @@ -83,7 +84,10 @@ class SettingsActivity : CatimaAppCompatActivity() { class SettingsFragment : PreferenceFragmentCompat() { var mReloadMain: Boolean = false - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + override fun onCreatePreferences( + savedInstanceState: Bundle?, + rootKey: String?, + ) { // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences) @@ -94,9 +98,11 @@ class SettingsActivity : CatimaAppCompatActivity() { getString(R.string.settings_key_light_theme) -> { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) } + getString(R.string.settings_key_dark_theme) -> { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) } + else -> { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) } @@ -114,14 +120,15 @@ class SettingsActivity : CatimaAppCompatActivity() { findPreference(getString(R.string.settings_key_locale))!! localePreference.let { val entryValues = it.entryValues - val entries = entryValues.map { entry -> - if (entry.isEmpty()) { - getString(R.string.settings_system_locale) - } else { - val entryLocale = Utils.stringToLocale(entry.toString()) - entryLocale.getDisplayName(entryLocale) + val entries = + entryValues.map { entry -> + if (entry.isEmpty()) { + getString(R.string.settings_system_locale) + } else { + val entryLocale = Utils.stringToLocale(entry.toString()) + entryLocale.getDisplayName(entryLocale) + } } - } it.entries = entries.toTypedArray() // Make locale picker preference in sync with system settings @@ -155,25 +162,21 @@ class SettingsActivity : CatimaAppCompatActivity() { } val newLocale = newValue as String // If newLocale is empty, that means "System" was selected - AppCompatDelegate.setApplicationLocales(if (newLocale.isEmpty()) LocaleListCompat.getEmptyLocaleList() else LocaleListCompat.create(Utils.stringToLocale(newLocale))) + AppCompatDelegate.setApplicationLocales( + if (newLocale.isEmpty()) { + LocaleListCompat.getEmptyLocaleList() + } else { + LocaleListCompat.create( + Utils.stringToLocale(newLocale), + ) + }, + ) true } // Hide crash reporter settings on builds it's not enabled on val crashReporterPreference = findPreference("acra.enable") crashReporterPreference!!.isVisible = BuildConfig.useAcraCrashReporter - - val barcodeFormatPreference = findPreference(getString(R.string.settings_key_barcode_widget_show_format)) - barcodeFormatPreference?.setOnPreferenceChangeListener { _, newValue -> - activity?.let { activity -> - PreferenceManager.getDefaultSharedPreferences(activity) - .edit() - .putBoolean(activity.getString(R.string.settings_key_barcode_widget_show_format), newValue as Boolean) - .apply() - BarcodeWidget.triggerUpdate(activity) - } - true - } } private fun refreshActivity(reloadMain: Boolean) { diff --git a/app/src/main/res/layout/barcode_widget.xml b/app/src/main/res/layout/barcode_widget.xml index 6f083194ad..b8f14e0742 100644 --- a/app/src/main/res/layout/barcode_widget.xml +++ b/app/src/main/res/layout/barcode_widget.xml @@ -24,12 +24,4 @@ android:layout_weight="1" android:scaleType="fitCenter" android:importantForAccessibility="no" /> - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ec650d0b5..383d71dfc0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -112,7 +112,6 @@ Switch cards using volume buttons Use the volume buttons to change which card is displayed pref_use_volume_keys_navigation - pref_barcode_widget_show_format sharedpreference_active_tab sharedpreference_sort sharedpreference_sort_order @@ -351,8 +350,6 @@ Copied to clipboard No value found Barcode encoding - Show barcode type on widget - Display the barcode format name below the barcode on the home screen widget Back NFC is paused Change settings diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 2fc2cc517a..fec2bce50f 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -118,15 +118,6 @@ android:title="@string/settings_disable_nfc_while_viewing_card" app:iconSpaceReserved="false" app:singleLineTitle="false" /> - - Date: Mon, 29 Jun 2026 01:20:52 +0200 Subject: [PATCH 5/5] Update minWidth and minHeight in barcode widget Reduced the minimum width and height for the barcode widget. 80dp seemed fine on my pixel 9a but doesn't seem the case on all phones --- app/src/main/res/xml/barcode_widget_info.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/xml/barcode_widget_info.xml b/app/src/main/res/xml/barcode_widget_info.xml index f54bbeef1e..6c29deae68 100644 --- a/app/src/main/res/xml/barcode_widget_info.xml +++ b/app/src/main/res/xml/barcode_widget_info.xml @@ -3,8 +3,8 @@ android:configure="protect.card_locker.BarcodeWidgetConfigureActivity" android:initialKeyguardLayout="@layout/barcode_widget" android:initialLayout="@layout/barcode_widget" - android:minWidth="80dp" - android:minHeight="80dp" + android:minWidth="40dp" + android:minHeight="40dp" android:previewImage="@drawable/widget_preview" android:resizeMode="horizontal|vertical" android:targetCellWidth="1"