Fetch
Fetch copied to clipboard
EnqueueAction.REPLACE_EXISTING does not work when SAF is used
Sample: https://github.com/aartikov/Fetch-Bug
Steps to reproduce:
- Replace
request.enqueueAction = EnqueueAction.UPDATE_ACCORDINGLYtorequest.enqueueAction = EnqueueAction.REPLACE_EXISTING. - Run sample on any device or emulator.
- Select a directory and press "Download". Downloading is failed.
Stacktrace:
java.lang.IllegalArgumentException: Failed to determine if primary:Music/Test/818.mp3 is child of primary:Music/Test: java.io.FileNotFoundException: Missing file for primary:Music/Test/818.mp3 at /storage/emulated/0/Music/Test/818.mp3
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:165)
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146)
at android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:639)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1358)
at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1193)
at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1147)
at com.tonyodev.fetch2core.StorageResolverHelper.createFileAtPath(StorageResolverHelper.kt:191)
at com.tonyodev.fetch2core.DefaultStorageResolver.createFile(DefaultStorageResolver.kt:15)
at com.tonyodev.fetch2.downloader.ParallelFileDownloaderImpl.downloadSliceFiles(ParallelFileDownloaderImpl.kt:410)
at com.tonyodev.fetch2.downloader.ParallelFileDownloaderImpl.run(ParallelFileDownloaderImpl.kt:149)
at com.tonyodev.fetch2.downloader.DownloadManagerImpl$start$$inlined$synchronized$lambda$1.run(DownloadManagerImpl.kt:103)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
@aartikov From the look of the stack trace. The DefaultStorageResolver attempted to create the file at the location but was not able to. Incorrect file path or write permission issue.
The DefaultStorageResolver does not cover ever edge case. It would be best to create your own StorageResolver that Fetch can use. Eg:
final FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
.enableRetryOnNetworkGain(true)
.setDownloadConcurrentLimit(3)
.setStorageResolver(new MyStorageResolver(context))
.build()
Fetch.Impl.setDefaultInstanceConfiguration(fetchConfiguration);