Android icon indicating copy to clipboard operation
Android copied to clipboard

Catima can't read file opened from Nextcloud in file manager (NetworkOnMainThreadException)

Open BaumiCoder opened this issue 7 months ago • 8 comments

  • Catima version: 2.34.5
  • OS: /e/OS 2.9 (Android 14)

I have a pkpasses file from Reservix (a german ticket portal) and want to open it in Catima. Due to the leck of pkpasses support (see #2287) I unzip the pkpasses file to get the three contained pkpass files. If I open one of this pkpass files, I get only the error message "Could not read the file".

The pkpass files themself seems to be valid as PassAndroid can open them. If necessary, I can provide the files for reproduction, but not in publicly.

BaumiCoder avatar Apr 23 '25 06:04 BaumiCoder

Was going to post this but beat me to it.

Tested a demo PKPASS that worked fine, but PKPASS I received for some travel insurance does not open. After comparing the two and testing them in another app (PassAndroid and another), it seems the one that didn't work does not contain a QR code whereas the working one does. So maybe it's because the PKPASS has no QR code that it doesn't upload?

It just crashes if I attempt to upload the non QR one.

Kobaratz avatar Apr 23 '25 09:04 Kobaratz

If you can send me the affected pkpass I'll happily take a look, see why it fails and if it can be fixed :) My email and website are on my GitHub profile, use whatever method you prefer.

TheLastProject avatar Apr 23 '25 10:04 TheLastProject

... So maybe it's because the PKPASS has no QR code that it doesn't upload?

It just crashes if I attempt to upload the non QR one.

@Kobaratz My problematic pkpass files do contain a QR code.

If you can send me the affected pkpass I'll happily take a look, see why it fails and if it can be fixed :) My email and website are on my GitHub profile, use whatever method you prefer.

@TheLastProject I sent you one of the pkpass files via email.

BaumiCoder avatar Apr 23 '25 14:04 BaumiCoder

I definitely cannot reproduce the issue with the files frim @BaumiCoder. The pkpass files are fine and open fine for me.

The error "Could not read the file" could also show if the file can't be opened for another reason, like Android saying "File not found", or a broken File Manager app not giving Catima permission to read the file selected through it. I'm starting to wonder if something like that might be the issue? Sadly, checking that will require setting up access to logcat: https://developer.android.com/studio/debug/logcat. Alternatively, I could build a debug APK that shows the exception in more details.

@Kobaratz You might have another issue, so your files would still be helpful.

TheLastProject avatar Apr 23 '25 16:04 TheLastProject

It seems that the location of the files is the problem. The files are stored in my Nextcloud, which is available as Nextcloud section in the file manager provided by the Nextcloud Android app. Now, I copied it to the downloads directory on my device and from there it works just fine. Therefore, Catima struggles with the file location.

I extracted a logcat with SysLog: logcat.log

BaumiCoder avatar Apr 24 '25 08:04 BaumiCoder

That's a long logcat, seems to be a lot of non-Catima data in there too.

The important part seems to be the following, a NetworkOnMainThreadException:

04-24 10:17:33.797 D/OwnCloudClient #0( 8556): REQUEST PROPFIND <Nextcloud file name>
04-24 10:17:33.810 E/DatabaseUtils( 8556): Writing exception to parcel
04-24 10:17:33.810 E/DatabaseUtils( 8556): android.os.NetworkOnMainThreadException
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1688)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.conscrypt.Platform.blockGuardOnNetwork(Platform.java:804)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:811)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:799)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:772)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at java.io.BufferedInputStream.fill(BufferedInputStream.java:239)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at java.io.BufferedInputStream.read(BufferedInputStream.java:258)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.apache.commons.httpclient.HttpConnection.isStale(HttpConnection.java:506)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.apache.commons.httpclient.HttpConnection.closeIfStale(HttpConnection.java:431)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.closeIfStale(MultiThreadedHttpConnectionManager.java:1313)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:382)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at com.owncloud.android.lib.common.OwnCloudClient.executeMethod(OwnCloudClient.java:192)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at com.owncloud.android.lib.common.OwnCloudClient.executeMethod(OwnCloudClient.java:155)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at com.owncloud.android.lib.resources.files.CheckEtagRemoteOperation.run(CheckEtagRemoteOperation.java:62)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at com.owncloud.android.lib.common.operations.RemoteOperation.execute(RemoteOperation.java:132)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at com.owncloud.android.lib.common.operations.RemoteOperation.execute(RemoteOperation.java:141)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at com.owncloud.android.providers.DocumentsStorageProvider.hasServerChange(DocumentsStorageProvider.java:288)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at com.owncloud.android.providers.DocumentsStorageProvider.openDocument(DocumentsStorageProvider.java:209)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at android.provider.DocumentsProvider.openAssetFile(DocumentsProvider.java:1347)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at android.provider.DocumentsProvider.openTypedAssetFileImpl(DocumentsProvider.java:1457)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at android.provider.DocumentsProvider.openTypedAssetFile(DocumentsProvider.java:1389)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:672)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:341)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at android.os.Binder.execTransactInternal(Binder.java:1500)
04-24 10:17:33.810 E/DatabaseUtils( 8556): 	at android.os.Binder.execTransact(Binder.java:1444)
04-24 10:17:33.814 E/Catima  (18052): Error reading pkpass file
04-24 10:17:33.814 E/Catima  (18052): android.os.NetworkOnMainThreadException
04-24 10:17:33.814 E/Catima  (18052): 	at android.os.Parcel.createExceptionOrNull(Parcel.java:3215)
04-24 10:17:33.814 E/Catima  (18052): 	at android.os.Parcel.createException(Parcel.java:3189)
04-24 10:17:33.814 E/Catima  (18052): 	at android.os.Parcel.readException(Parcel.java:3172)
04-24 10:17:33.814 E/Catima  (18052): 	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:202)
04-24 10:17:33.814 E/Catima  (18052): 	at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:165)
04-24 10:17:33.814 E/Catima  (18052): 	at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:814)
04-24 10:17:33.814 E/Catima  (18052): 	at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:2043)
04-24 10:17:33.814 E/Catima  (18052): 	at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1858)
04-24 10:17:33.814 E/Catima  (18052): 	at android.content.ContentResolver.openInputStream(ContentResolver.java:1528)
04-24 10:17:33.814 E/Catima  (18052): 	at protect.card_locker.PkpassParser.<init>(PkpassParser.kt:64)
04-24 10:17:33.814 E/Catima  (18052): 	at protect.card_locker.Utils.retrieveBarcodesFromPkPass(Utils.java:192)
04-24 10:17:33.814 E/Catima  (18052): 	at protect.card_locker.Utils.parseSetBarcodeActivityResult(Utils.java:318)
04-24 10:17:33.814 E/Catima  (18052): 	at protect.card_locker.ScanActivity.handleActivityResult(ScanActivity.java:315)
04-24 10:17:33.814 E/Catima  (18052): 	at protect.card_locker.ScanActivity.lambda$onCreate$3(ScanActivity.java:113)
04-24 10:17:33.814 E/Catima  (18052): 	at protect.card_locker.ScanActivity.$r8$lambda$1UXWETCalRMm3lpLgyiYV6_9zwM(ScanActivity.java:0)
04-24 10:17:33.814 E/Catima  (18052): 	at protect.card_locker.ScanActivity$$ExternalSyntheticLambda4.onActivityResult(R8$$SyntheticClass:0)
04-24 10:17:33.814 E/Catima  (18052): 	at androidx.activity.result.ActivityResultRegistry.doDispatch(ActivityResultRegistry.java:414)
04-24 10:17:33.814 E/Catima  (18052): 	at androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.java:371)
04-24 10:17:33.814 E/Catima  (18052): 	at androidx.activity.ComponentActivity.onActivityResult(ComponentActivity.java:845)
04-24 10:17:33.814 E/Catima  (18052): 	at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:152)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.Activity.internalDispatchActivityResult(Activity.java:9340)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.Activity.dispatchActivityResult(Activity.java:9324)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.ActivityThread.deliverResults(ActivityThread.java:5807)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.ActivityThread.handleSendResult(ActivityThread.java:5854)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:69)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:60)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:231)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:152)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:93)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2595)
04-24 10:17:33.814 E/Catima  (18052): 	at android.os.Handler.dispatchMessage(Handler.java:107)
04-24 10:17:33.814 E/Catima  (18052): 	at android.os.Looper.loopOnce(Looper.java:232)
04-24 10:17:33.814 E/Catima  (18052): 	at android.os.Looper.loop(Looper.java:317)
04-24 10:17:33.814 E/Catima  (18052): 	at android.app.ActivityThread.main(ActivityThread.java:8592)
04-24 10:17:33.814 E/Catima  (18052): 	at java.lang.reflect.Method.invoke(Native Method)
04-24 10:17:33.814 E/Catima  (18052): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
04-24 10:17:33.814 E/Catima  (18052): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:878)

TheLastProject avatar Apr 24 '25 14:04 TheLastProject

Now that Catima is using Kotlin, it should be easily fixable by using coroutines. To observe the result, I suggest using flows. There are quite a few different types of flows, but the most used ones are StateFlow and SharedFlow. StateFlow should be good enough for this use case.

theimpulson avatar Apr 30 '25 16:04 theimpulson

Most likely this is also the cause of Google Drive crashing in #2501.

TheLastProject avatar May 10 '25 20:05 TheLastProject