Compare commits

..

26 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
14 changed files with 103 additions and 48 deletions

View File

@@ -1,5 +1,14 @@
# Changelog
## v2.41.4 - 161 (2026-01-04)
- 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

@@ -19,8 +19,8 @@ android {
applicationId = "me.hackerchick.catima"
minSdk = 21
targetSdk = 36
versionCode = 159
versionName = "2.41.2"
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

@@ -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

@@ -459,8 +459,11 @@ public class CatimaImporter implements Importer {
barcodeType = CatimaBarcode.fromName(unparsedBarcodeType);
}
// 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

@@ -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)