Android App select file with Nextcloud App - File can't be read

Hi,
I’m developing an Android App and want to support saving and restoring my backups using the nextcloud App.

  1. Backup is working (My own app is saving a zip file. The file can be shared with the nextcloud app and is then uploaded)

  2. Restore is not working yet. I’m sending an ACTION_GET_CONTENT intent and select the file from Nextcloud. The problem is that I can’t find a way to read the selected file. I tried different ways and even the one that worked from many different locations and apps is crashing. At least I can differentiate when the file was selected using nextcloud (uri authoritity org.nextcloud.documents)

val inputStream = context.contentResolver.openInputStream(uri) //uri returned from ACTION_GET_CONTENT by Nextcloud app

It always fails with FileNotFoundException:
Caused by: java.io.FileNotFoundException: Error downloading file: batteryManager2017_12_24_15_33_25.zip
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:149)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:705)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1687)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1503)
at android.content.ContentResolver.openInputStream(ContentResolver.java:1187)

Hope someone has an idea. Thanks

Hi,
I’ve run into the same issue right now. Have you found a solution?

Hi,
unfortunately no. I suppose there is a bug at the nextcloud’s content provider. But I’m quite lost with that issue.

Hi,
I currently believe it depends on the thread where the content reading access happens. I’ve two types of implementation now one is broken (UIThread) and one is working without this issue.

Oh crazy…thanks for the threading hint!
For me it is exactly the other way round. Up to now I’ve tried to restore in UiThread.
When I wrap the code in a doAsync (Anko method) block it is actually working. The data was set to the object returned by getImport() before and is used when calling exec.

    context?.let {
        doAsync {
            val daoList = getBackupConfig().createDaos( it )
            getImport().exec( it, daoList )
            daoList.forEach { dao -> dao.close() }
            it.runOnUiThread {
                binding.txtImportLog.text = getImport().getImportLog()
                setButtonEnabledState( binding.btnImport, true )
            } }
        }
    }
1 Like

I also have this problem. I also get a longer content URL on my device, not just the device Id. Has this been reported on GitHub yet?