Compare commits

..

27 Commits

Author SHA1 Message Date
Sylvia van Os
008b5254c6 Release Catima 2.41.4 2026-01-04 23:17:37 +01:00
Sylvia van Os
1b1163a100 Merge pull request #2941 from CatimaLoyalty/create-pull-request/patch-1767564871
Update Fastlane changelogs
2026-01-04 23:14:46 +01:00
TheLastProject
70c14514e6 Update Fastlane changelogs 2026-01-04 22:14:31 +00:00
Sylvia van Os
5830813170 Update CHANGELOG 2026-01-04 23:14:14 +01:00
Sylvia van Os
a07d4d1b8a Merge pull request #2940 from CatimaLoyalty/fix/disable_automatic_encoding
Disable automatic barcode encoding guessing for now
2026-01-04 23:12:57 +01:00
Sylvia van Os
29c4ccf4d9 Disable automatic barcode encoding guessing for now 2026-01-04 22:57:50 +01:00
Sylvia van Os
417006cfa3 Release Catima 2.41.3 2026-01-04 21:45:51 +01:00
Sylvia van Os
907a8578ca Merge pull request #2938 from CatimaLoyalty/create-pull-request/patch-1767559150
Update Fastlane changelogs
2026-01-04 21:39:39 +01:00
TheLastProject
7e63babd47 Update Fastlane changelogs 2026-01-04 20:39:10 +00:00
Sylvia van Os
c289bb0af3 Update CHANGELOG 2026-01-04 21:39:00 +01:00
Sylvia van Os
80767e7cd6 Merge pull request #2937 from CatimaLoyalty/fix/enforce_iso_on_2.41.3_upgrade
On initial upgrade to 2.41.3, force all cards to ISO-8859-1
2026-01-04 21:38:11 +01:00
Sylvia van Os
90e6dd8738 Fix tests 2026-01-04 21:20:49 +01:00
Sylvia van Os
d3de9c65e6 Force ISO-8859-1 when importing old backups
This will not catch one edge case: use exporting a backup in Catima
2.41.0 - 2.41.2, then uninstall Catima, then installing Catima 2.41.3
and then importing the database. But this seems rare enough to be
acceptable.
2026-01-04 21:20:49 +01:00
Sylvia van Os
48993f0486 On initial upgrade, force all automatic cards to ISO-8859-1
This fixes old pkpass files imported before Catima 2.41.0 to be forced
to "Automatic", which may guess UTF-8. New pkpass files will have the
encoding read from the file and newly scanned barcodes will use
Automatic.

This does have the unfortunate side effect of everyone who already
scanned a QR code with UTF-8 data since Catima 2.41.0 to have it forced
to ISO-8859-1, but it will fix Deutschlandtickets imported before 2.41.0
which is a rather large amount of the Catima userbase.
2026-01-04 21:20:44 +01:00
Sylvia van Os
918c6fb41b Merge pull request #2936 from CatimaLoyalty/create-pull-request/patch-1767555122
Update Fastlane changelogs
2026-01-04 20:32:26 +01:00
TheLastProject
d121841fdf Update Fastlane changelogs 2026-01-04 19:32:02 +00:00
Sylvia van Os
95ace2aa39 Update CHANGELOG 2026-01-04 20:31:51 +01:00
Sylvia van Os
b8cd52563d Merge pull request #2935 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2026-01-04 20:29:37 +01:00
Sylvia van Os
70754af167 Merge pull request #2934 from CatimaLoyalty/fix/2932
Never pass ISO-8859-1 as encode hint
2026-01-04 20:29:24 +01:00
Sylvia van Os
80bad7ad56 Never pass ISO-8859-1 as encode hint
This fully restores the old behaviour for pkpass files with ISO-8859-1 as messageEncoding
2026-01-04 20:13:43 +01:00
Edgars Andersons
e214d6d69e Translated using Weblate (Latvian)
Currently translated at 100.0% (313 of 313 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/lv/
2026-01-04 20:02:09 +01:00
109247019824
0e7509d966 Translated using Weblate (Bulgarian)
Currently translated at 100.0% (316 of 316 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/bg/
2026-01-04 20:02:08 +01:00
Fjuro
58a5b16484 Translated using Weblate (Czech)
Currently translated at 100.0% (316 of 316 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/cs/
2026-01-04 20:02:07 +01:00
B o d o
a8df588b33 Translated using Weblate (German)
Currently translated at 100.0% (316 of 316 strings)

Translation: Catima/Android
Translate-URL: https://hosted.weblate.org/projects/catima/catima/de/
2026-01-04 20:02:05 +01:00
Sylvia van Os
ef948f16f1 Merge pull request #2933 from CatimaLoyalty/create-pull-request/patch-1767502013
Update contributors
2026-01-04 09:50:08 +01:00
TheLastProject
11f942771f Update contributors 2026-01-04 04:46:53 +00:00
Sylvia van Os
f507e15bfc Release Catima 2.41.2 2026-01-03 21:06:53 +01:00
23 changed files with 176 additions and 68 deletions

View File

@@ -50,10 +50,10 @@ jobs:
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run instrumented tests (API 23)
- name: Run instrumented tests (API 21)
uses: ReactiveCircus/android-emulator-runner@v2
with:
api-level: 23
api-level: 21
arch: x86_64
script: ./gradlew connected${{ matrix.flavor }}DebugAndroidTest
- name: Run instrumented tests (API 35)

View File

@@ -1,8 +1,15 @@
# Changelog
## Unreleased - 159
## v2.41.4 - 161 (2026-01-04)
Android 5.0 and 5.1 are no longer supported starting with this release. If you want to use Catima on these versions, please use version 2.41.1.
- Disable automatic barcode encoding detection for now (breaks too many cards)
## v2.41.3 - 160 (2026-01-04)
- Follow-up for fix in 2.41.2 for cards explicitly set to ISO-8859-1
- Migrate old cards to ISO-8859-1 to fix sudden behaviour differences for existing cards
## v2.41.2 - 159 (2026-01-03)
- Fix change introduced in 2.41.0 that broke support for some scanners for non-UTF-8 barcodes

View File

@@ -17,10 +17,10 @@ android {
defaultConfig {
applicationId = "me.hackerchick.catima"
minSdk = 23
minSdk = 21
targetSdk = 36
versionCode = 158
versionName = "2.41.1"
versionCode = 161
versionName = "2.41.4"
vectorDrawables.useSupportLibrary = true
multiDexEnabled = true

View File

@@ -21,6 +21,7 @@ import com.google.zxing.common.StringUtils;
import java.lang.ref.WeakReference;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
@@ -184,23 +185,44 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
MultiFormatWriter writer = new MultiFormatWriter();
Map<EncodeHintType, Object> encodeHints = new ArrayMap<>();
Charset chosenEncoding = encoding;
// Use charset if defined or guess otherwise
if (encoding != null) {
Log.d(TAG, "Encoding explicitly set, " + encoding.name());
encodeHints.put(EncodeHintType.CHARACTER_SET, encoding);
if (chosenEncoding != null) {
Log.d(TAG, "Encoding explicitly set, " + chosenEncoding.name());
} else {
String guessedEncoding = StringUtils.guessEncoding(cardId.getBytes(), new ArrayMap<>());
Log.d(TAG, "Guessed encoding: " + guessedEncoding);
// We don't want to pass the guessed encoding as an encoding hint unless it is UTF-8 as
// zxing is likely to add the mentioned encoding hint as ECI inside the barcode.
// FIXME: Guessing encoding using zxing causes too many false positives and breaks the Deutschlandticket, a common public transport ticket in Germany
// See https://github.com/CatimaLoyalty/Android/issues/2932
//
// Due to many barcode scanners in the wild being badly coded they may trip over ECI
// info existing and fail to scan, such as in https://github.com/CatimaLoyalty/Android/issues/2921
if (Objects.equals(guessedEncoding, "UTF8")) {
Log.d(TAG, "Guessed encoding is UTF8, so passing as encoding hint");
encodeHints.put(EncodeHintType.CHARACTER_SET, Charset.forName(guessedEncoding));
}
// So, for now, we just force ISO in the "guessing" path until we figure out a better way to guess
// The previous code is commented before, DO NOT UNCOMMENT, IT IS BROKEN
//
// chosenEncoding = Charset.forName(StringUtils.guessEncoding(cardId.getBytes(), new ArrayMap<>()));
// Log.d(TAG, "Guessed encoding: " + chosenEncoding.name());
// FIXME: Figure out a good way to automatically determine the best format to use, to not break UTF-8 barcodes
// However, make sure to NOT break the Deutschlandticket!
chosenEncoding = StandardCharsets.ISO_8859_1;
Log.w(TAG, "The encoding guessing code path is temporarily disabled due to it breaking Deutschlandticket. Forcing ISO-8859-1...");
}
// We don't want to pass the ISO-8859-1 as an encoding hint as zxing may add this as ECI
// inside the barcode.
//
// Due to many barcode scanners in the wild being badly coded they may trip over ECI
// info existing and fail to scan.
// See:
// - https://github.com/CatimaLoyalty/Android/issues/2921
// - https://github.com/CatimaLoyalty/Android/issues/2932
//
// Just not always passing the encoding hint is slightly hacky, but in 5+ years of Catima
// cards without encode hints have never caused any issues (unless they were UTF-8), yet
// just days after passing ISO-8859-1 as CHARACTER_SET in the encode hints already 2
// scan failures were reported (one for QR, one for Aztec).
if (!Objects.equals(chosenEncoding.name(), StandardCharsets.ISO_8859_1.name())) {
Log.d(TAG, "Chosen encoding is not ISO_8859_1, so passing as encoding hint");
encodeHints.put(EncodeHintType.CHARACTER_SET, chosenEncoding);
} else {
Log.d(TAG, "Not passing encoding as encoding hint");
}
BitMatrix bitMatrix;

View File

@@ -38,10 +38,15 @@ public class CatimaAppCompatActivity extends AppCompatActivity {
Window window = getWindow();
if (window != null) {
boolean darkMode = Utils.isDarkModeEnabled(this);
View decorView = window.getDecorView();
WindowInsetsControllerCompat wic = new WindowInsetsControllerCompat(window, decorView);
wic.setAppearanceLightStatusBars(!darkMode);
window.setStatusBarColor(Color.TRANSPARENT);
if (Build.VERSION.SDK_INT >= 23) {
View decorView = window.getDecorView();
WindowInsetsControllerCompat wic = new WindowInsetsControllerCompat(window, decorView);
wic.setAppearanceLightStatusBars(!darkMode);
window.setStatusBarColor(Color.TRANSPARENT);
} else {
// icons are always white back then
window.setStatusBarColor(darkMode ? Color.TRANSPARENT : Color.argb(127, 0, 0, 0));
}
}
// XXX android 9 and below has a nasty rendering bug if the theme was patched earlier
Utils.postPatchColors(this);
@@ -61,4 +66,7 @@ public class CatimaAppCompatActivity extends AppCompatActivity {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
public void onMockedRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
}
}

View File

@@ -26,7 +26,7 @@ import java.util.Set;
public class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Catima.db";
public static final int ORIGINAL_DATABASE_VERSION = 1;
public static final int DATABASE_VERSION = 18;
public static final int DATABASE_VERSION = 19;
// NB: changing these values requires a migration
public static final int DEFAULT_ZOOM_LEVEL = 100;
@@ -345,6 +345,17 @@ public class DBHelper extends SQLiteOpenHelper {
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
+ " ADD COLUMN " + LoyaltyCardDbIds.BARCODE_ENCODING + " TEXT");
}
// On upgrade to 2.41.3, force all existing "Automatic" cards to ISO-8859-1.
// UTF-8 support was only added in 2.42.0, before that, all barcodes were saved without
// any encoding info. As many scanners deal badly with ECI info, automatically guessing
// UTF-8 for old barcodes may break them.
//
// New cards will be saved using either "Automatic" encoding to guess or, for pkpass files,
// whatever encoding is specified.
if (oldVersion < 19 && newVersion >= 19) {
db.execSQL("UPDATE " + LoyaltyCardDbIds.TABLE + " SET " + LoyaltyCardDbIds.BARCODE_ENCODING + " = 'ISO-8859-1' WHERE " + LoyaltyCardDbIds.BARCODE_ENCODING + " IS NULL");
}
}
public static Set<String> imageFiles(Context context, final SQLiteDatabase database) {

View File

@@ -100,7 +100,8 @@ class ListWidget : AppWidgetProvider() {
val foreground = if (Utils.needsDarkForeground(headerColor)) Color.BLACK else Color.WHITE
setInt(R.id.item_container_foreground, "setBackgroundColor", headerColor)
val icon = loyaltyCard.getImageThumbnail(context)
// FIXME: The icon flow causes a crash up to Android 12L, so force anything below 33 down this path
// setImageViewIcon is not supported on Android 5, so force Android 5 down the text path
// FIXME: The icon flow causes a crash up to Android 12L, so SDK_INT is forced up from 23 to 33
if (icon != null && Build.VERSION.SDK_INT >= 32) {
setInt(R.id.item_container_foreground, "setBackgroundColor", foreground)
setImageViewIcon(R.id.item_image, Icon.createWithBitmap(icon))

View File

@@ -34,6 +34,11 @@ public class PermissionUtils {
* @return
*/
public static boolean needsCameraPermission(Activity activity) {
// Android only introduced the runtime permission system in Marshmallow (Android 6.0)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return false;
}
return ContextCompat.checkSelfPermission(activity, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED;
}
@@ -44,14 +49,21 @@ public class PermissionUtils {
* @param activity
* @param requestCode
*/
public static void requestStorageReadPermission(Activity activity, int requestCode) {
public static void requestStorageReadPermission(CatimaAppCompatActivity activity, int requestCode) {
String[] permissions = new String[]{ android.Manifest.permission.READ_EXTERNAL_STORAGE };
int[] mockedResults = new int[]{ PackageManager.PERMISSION_GRANTED };
if (needsStorageReadPermission(activity)) {
ActivityCompat.requestPermissions(activity, permissions, requestCode);
} else {
activity.onRequestPermissionsResult(requestCode, permissions, mockedResults);
// FIXME: This points to onMockedRequestPermissionResult instead of to
// onRequestPermissionResult because onRequestPermissionResult was only introduced in
// Android 6.0 (SDK 23) and we and to support Android 5.0 (SDK 21) too.
//
// When minSdk becomes 23, this should point to onRequestPermissionResult directly and
// the activity input variable should be changed from CatimaAppCompatActivity to
// Activity.
activity.onMockedRequestPermissionsResult(requestCode, permissions, mockedResults);
}
}
@@ -62,14 +74,21 @@ public class PermissionUtils {
* @param activity
* @param requestCode
*/
public static void requestCameraPermission(Activity activity, int requestCode) {
public static void requestCameraPermission(CatimaAppCompatActivity activity, int requestCode) {
String[] permissions = new String[]{ Manifest.permission.CAMERA };
int[] mockedResults = new int[]{ PackageManager.PERMISSION_GRANTED };
if (needsCameraPermission(activity)) {
ActivityCompat.requestPermissions(activity, permissions, requestCode);
} else {
activity.onRequestPermissionsResult(requestCode, permissions, mockedResults);
// FIXME: This points to onMockedRequestPermissionResult instead of to
// onRequestPermissionResult because onRequestPermissionResult was only introduced in
// Android 6.0 (SDK 23) and we and to support Android 5.0 (SDK 21) too.
//
// When minSdk becomes 23, this should point to onRequestPermissionResult directly and
// the activity input variable should be changed from CatimaAppCompatActivity to
// Activity.
activity.onMockedRequestPermissionsResult(requestCode, permissions, mockedResults);
}
}
}

View File

@@ -543,6 +543,14 @@ class ScanActivity : CatimaAppCompatActivity() {
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
onMockedRequestPermissionsResult(requestCode, permissions, grantResults)
}
override fun onMockedRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
val granted =
grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED

View File

@@ -40,9 +40,16 @@ class UCropWrapper : UCropActivity() {
return
}
val decorView = window.decorView
val wic = WindowInsetsControllerCompat(window, decorView)
wic.isAppearanceLightStatusBars = !darkMode
if (Build.VERSION.SDK_INT >= 23) {
val decorView = window.decorView
val wic = WindowInsetsControllerCompat(window, decorView)
wic.isAppearanceLightStatusBars = !darkMode
} else if (!darkMode) {
window.statusBarColor = ColorUtils.compositeColors(
Color.argb(127, 0, 0, 0),
window.statusBarColor
)
}
}
private fun checkViews(darkMode: Boolean) {

View File

@@ -77,6 +77,13 @@ public class CardsContentProvider extends ContentProvider {
@Nullable final String selection,
@Nullable final String[] selectionArgs,
@Nullable final String sortOrder) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Disable the content provider on SDK < 23 since it grants dangerous
// permissions at install-time
Log.w(TAG, "Content provider read is only available for SDK >= 23");
return null;
}
final Settings settings = new Settings(getContext());
if (!settings.getAllowContentProviderRead()) {
Log.w(TAG, "Content provider read is disabled");

View File

@@ -459,9 +459,11 @@ public class CatimaImporter implements Importer {
barcodeType = CatimaBarcode.fromName(unparsedBarcodeType);
}
// This field did not exist in version 2.40.0 and before
// Barcode encoding information is only supported since Catima 2.41.0, so old exports will lack this field
// Database migration 19 forcing ISO-8859-1 on all cards, so we should treat imports from old Catima versions the same and force ISO-8859-1 there too
// This limits the risk of breaking cards when importing an old database backup
Charset barcodeEncoding = null;
String unparsedBarcodeEncoding = CSVHelpers.extractString(DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING, record, "");
String unparsedBarcodeEncoding = CSVHelpers.extractString(DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING, record, "ISO-8859-1");
if (!unparsedBarcodeEncoding.isEmpty()) {
barcodeEncoding = Charset.forName(unparsedBarcodeEncoding);
}

View File

@@ -157,6 +157,12 @@ class SettingsActivity : CatimaAppCompatActivity() {
true
}
// Disable content provider on SDK < 23 since dangerous permissions
// are granted at install-time
val contentProviderReadPreference = findPreference<Preference>(getString(R.string.settings_key_allow_content_provider_read))
contentProviderReadPreference!!.isVisible =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
// Hide crash reporter settings on builds it's not enabled on
val crashReporterPreference = findPreference<Preference>("acra.enable")
crashReporterPreference!!.isVisible = BuildConfig.useAcraCrashReporter

View File

@@ -7,8 +7,8 @@ Heimen Stoffels
Oğuz Ersen
FC (Fay) Stegerman
StoyanDimitrov
大王叫我来巡山
B o d o
大王叫我来巡山
SlavekB
Katharine Chui
mondstern
@@ -18,12 +18,12 @@ Altonss
Edgars Andersons
Joel A
Michael Moroni
Liner Seven
Priit Jõerüüt
Liner Seven
Eric
Fjuro
Максим Горпиніч
GitSpoon
Fjuro
GM
Petr Novák
laralem
@@ -33,14 +33,14 @@ pfaffenrodt
Aayush Gupta
Scrambled777
josé m
Nyatsuki
ikanakova
Vasilis
ikanakova
Nyatsuki
Kachelkaiser
Giovanni Donisi
Milo Ivir
Горпиніч Максим Олександрович
HudobniVolk
Горпиніч Максим Олександрович
Jiri Grönroos
Warder
Samantaz Fox
@@ -48,18 +48,19 @@ Balázs Meskó
109247019824
Feike Donia
Arno-github
Ankit Tiwari
Cliff Heraldo
Sergio Paredes
Ankit Tiwari
Jose Delvani
Robin
Milan Šalka
mdvhimself
Milan Šalka
AMIR-G98
Robin
தமிழ்நேரம்
huuhaa
Skrripy
Govindgopalyadav
damjang
Skrripy
huuhaa
waffshappen
Marnick L'Eau
ngocanhtve
@@ -67,19 +68,18 @@ aradxxx
StellarSand
Quentin PAGÈS
Projjal Moitra
Aliaksandr Trush
e-michalak
JungHee Lee
AMIR-G98
hajertabbane
inavleb
Ziad OUALHADJ
Aliaksandr Trush
Denis Shilin
Traductor
Gideon
Renko
Ricky Tigg
Robin Liu
Ricky Tigg
Renko
Gideon
Traductor
Denis Shilin
しいたけ
Alexander Ivanov
Miha Frangež
@@ -88,13 +88,14 @@ mrestivill
ehrt74
Virginie
Tim Trek
Peter Dave Hello
Alì Mortacci
MisterCosta96
arshbeerSingh
Augustin LAVILLE
Freddo espresso
vasudev-cell
Vasudev R.
Kim Seohyun
rudy3
Michael Gangolf
PRATHAMESH BHAGAT
Peter Dave Hello

View File

@@ -299,4 +299,7 @@
<string name="copy_value">Копиране на стойността</string>
<string name="copied_to_clipboard">Копирано</string>
<string name="nothing_to_copy">Няма стойност</string>
<string name="back">Назад</string>
<string name="automatic">Автоматично</string>
<string name="barcodeEncoding">Кодиране на щрихкода</string>
</resources>

View File

@@ -305,4 +305,7 @@
<string name="copy_value">Kopírovat hodnotu</string>
<string name="copied_to_clipboard">Zkopírováno do schránky</string>
<string name="nothing_to_copy">Nenalezena žádná hodnota</string>
<string name="barcodeEncoding">Kódování čárového kódu</string>
<string name="automatic">Automatické</string>
<string name="back">Zpět</string>
</resources>

View File

@@ -100,7 +100,7 @@
<string name="importLoyaltyCardKeychain">Aus Loyalty Card Keychain importieren</string>
<string name="importFidmeMessage">Wähle deinen „FidMe-Export“ zum Importieren und anschließend manuell die Barcodetypen aus.\nErstelle ihn aus deinem FidMe-Profil, indem du Datenschutz wählst und dann auf Meine Daten extrahieren drückst.</string>
<string name="importFidme">Aus FidMe importieren</string>
<string name="importCatimaMessage">Wähle deinen „Catima-Export“ zum Importieren aus.\nErstelle diesen durch das Drücken auf Export im Import/Export-Menü in einer anderen Catima-Anwendung.</string>
<string name="importCatimaMessage">Wähle deinen „Catima-Export“ zum Importieren aus.\nExportiere diesen zuvor im Import/Export-Menü einer anderen Catima-Anwendung.</string>
<string name="importCatima">Aus Catima importieren</string>
<string name="setBarcodeId">Barcodewert festlegen</string>
<string name="sameAsCardId">Entspricht Kartennummer</string>

View File

@@ -145,7 +145,7 @@
<string name="privacy_policy">Privātuma politika</string>
<string name="accept">Pieņemt</string>
<string name="editGroup">Kopas labošana: <xliff:g>%s</xliff:g></string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Autortiesības © 2019<xliff:g>%d</xliff:g> Sylvia van Os</string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Autortiesības © 2019<xliff:g>%d</xliff:g> Sylvia van Os un līdzdalībnieki</string>
<string name="app_copyright_old">Balstīta uz Loyalty Card Keychain
\nautortiesības © 20162020 Branden Archer</string>
<string name="debug_version_fmt">Versija: <xliff:g id="version">%s</xliff:g></string>

View File

@@ -497,7 +497,7 @@ public class DatabaseTest {
assertEquals("cardId", card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BarcodeFormat.UPC_A, card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(StandardCharsets.ISO_8859_1, card.barcodeEncoding); // Old cards are assumed to be ISO-8859-1
assertEquals(null, card.headerColor);
assertEquals(0, card.starStatus);
assertEquals(0, card.lastUsed);
@@ -515,7 +515,7 @@ public class DatabaseTest {
assertEquals("cardId", card2.cardId);
assertEquals(null, card2.barcodeId);
assertEquals(null, card2.barcodeType); // Empty string should've become null
assertEquals(null, card.barcodeEncoding);
assertEquals(StandardCharsets.ISO_8859_1, card.barcodeEncoding); // Old cards are assumed to be ISO-8859-1
assertEquals(null, card2.headerColor);
assertEquals(0, card2.starStatus);
assertEquals(0, card2.lastUsed);

View File

@@ -669,7 +669,7 @@ public class ImportExportTest {
assertEquals("12345", card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BarcodeFormat.AZTEC, card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(StandardCharsets.ISO_8859_1, card.barcodeEncoding); // Old cards are assumed to be ISO-8859-1
assertNull(card.headerColor);
assertEquals(0, card.starStatus);
@@ -696,7 +696,7 @@ public class ImportExportTest {
assertEquals("12345", card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BarcodeFormat.AZTEC, card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(StandardCharsets.ISO_8859_1, card.barcodeEncoding); // Old cards are assumed to be ISO-8859-1
assertNull(card.headerColor);
assertEquals(0, card.starStatus);
@@ -735,7 +735,7 @@ public class ImportExportTest {
assertEquals("12345", card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(null, card.barcodeType);
assertEquals(null, card.barcodeEncoding);
assertEquals(StandardCharsets.ISO_8859_1, card.barcodeEncoding); // Old cards are assumed to be ISO-8859-1
assertEquals(1, (long) card.headerColor);
assertEquals(0, card.starStatus);
@@ -762,7 +762,7 @@ public class ImportExportTest {
assertEquals("12345", card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BarcodeFormat.AZTEC, card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(StandardCharsets.ISO_8859_1, card.barcodeEncoding); // Old cards are assumed to be ISO-8859-1
assertEquals(1, (long) card.headerColor);
assertEquals(1, card.starStatus);
@@ -789,7 +789,7 @@ public class ImportExportTest {
assertEquals("12345", card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BarcodeFormat.AZTEC, card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(StandardCharsets.ISO_8859_1, card.barcodeEncoding); // Old cards are assumed to be ISO-8859-1
assertEquals(1, (long) card.headerColor);
assertEquals(0, card.starStatus);
@@ -823,7 +823,7 @@ public class ImportExportTest {
assertEquals("12345", card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BarcodeFormat.AZTEC, card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(StandardCharsets.ISO_8859_1, card.barcodeEncoding); // Old cards are assumed to be ISO-8859-1
assertEquals(1, (long) card.headerColor);
assertEquals(0, card.starStatus);

View File

@@ -0,0 +1,2 @@
- Follow-up for fix in 2.41.2 for cards explicitly set to ISO-8859-1
- Migrate old cards to ISO-8859-1 to fix sudden behaviour differences for existing cards

View File

@@ -0,0 +1 @@
- Disable automatic barcode encoding detection for now (breaks too many cards)

View File

@@ -1,6 +1,6 @@
[versions]
# AndroidX
compose = "2025.12.01"
compose = "2025.11.01"
# Third-party
acra = "5.13.1"
@@ -22,7 +22,7 @@ com-google-android-material-material = { group = "com.google.android.material",
com-android-tools-desugar_jdk_libs = { group = "com.android.tools", name = "desugar_jdk_libs", version = "2.1.5" }
# Compose
androidx-activity-activity-compose = { group = "androidx.activity", name = "activity-compose", version = "1.12.2" }
androidx-activity-activity-compose = { group = "androidx.activity", name = "activity-compose", version = "1.10.1" }
androidx-compose-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose" }
androidx-compose-foundation-foundation = { group = "androidx.compose.foundation", name = "foundation" }
androidx-compose-material3-material3 = { group = "androidx.compose.material3", name = "material3"}