Giter VIP home page Giter VIP logo

k1rakishou / fuck-storage-access-framework Goto Github PK

View Code? Open in Web Editor NEW
275.0 275.0 14.0 423 KB

Fuck Storage Access Framework (or just FSAF) is a handy library that hides away from you all the annoying parts of the Storage Access Framework (like DocumentTrees / DocumentIds / DocumentFiles / DocumentContracts and other bullshit) leaving only an API that is similar to good-old Java File API

License: The Unlicense

Kotlin 100.00%
android kotlin saf storage-access-framework

fuck-storage-access-framework's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

fuck-storage-access-framework's Issues

Crash "java.lang.IllegalStateException: create() root is already FileRoot, cannot append anything anymore, root = /storage/emulated/0/Android/data/com.github.adamantcheese.chan/cache/filecache/b242d2460781b1e813c50efa4e9cc1ac.cache, baseDir segments = , segments = "

java.lang.IllegalStateException: create() root is already FileRoot, cannot append anything anymore, root = /storage/emulated/0/Android/data/com.github.adamantcheese.chan/cache/filecache/b242d2460781b1e813c50efa4e9cc1ac.cache, baseDir segments = , segments = 
		at com.github.k1rakishou.fsaf.manager.RawFileManager.create(RawFileManager.kt:24)
		at com.github.k1rakishou.fsaf.manager.RawFileManager.create(RawFileManager.kt:14)
		at com.github.k1rakishou.fsaf.FileManager.create(FileManager.kt:358)
		at com.github.k1rakishou.fsaf.FileManager.create(FileManager.kt:330)
		at com.github.adamantcheese.chan.core.cache.FileCacheV2.handleFileDownload(FileCacheV2.kt:819)
		at com.github.adamantcheese.chan.core.cache.FileCacheV2.access$handleFileDownload(FileCacheV2.kt:46)
		at com.github.adamantcheese.chan.core.cache.FileCacheV2$initBatchRequestQueue$1$1.apply(FileCacheV2.kt:187)
		at com.github.adamantcheese.chan.core.cache.FileCacheV2$initBatchRequestQueue$1$1.apply(FileCacheV2.kt:46)
		at io.reactivex.internal.operators.flowable.FlowableConcatMap$ConcatMapImmediate.drain(FlowableConcatMap.java:284)
		at io.reactivex.internal.operators.flowable.FlowableConcatMap$BaseConcatMapSubscriber.onNext(FlowableConcatMap.java:159)
		at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onNext(FlowableSubscribeOn.java:97)
		at io.reactivex.internal.operators.flowable.FlowableFromIterable$IteratorSubscription.slowPath(FlowableFromIterable.java:236)
		at io.reactivex.internal.operators.flowable.FlowableFromIterable$BaseRangeSubscription.request(FlowableFromIterable.java:124)
		at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.requestUpstream(FlowableSubscribeOn.java:133)
		at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onSubscribe(FlowableSubscribeOn.java:90)
		at io.reactivex.internal.operators.flowable.FlowableFromIterable.subscribe(FlowableFromIterable.java:69)
		at io.reactivex.internal.operators.flowable.FlowableFromIterable.subscribeActual(FlowableFromIterable.java:47)
		at io.reactivex.Flowable.subscribe(Flowable.java:14935)
		at io.reactivex.Flowable.subscribe(Flowable.java:14882)
		at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
		at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:288)
		at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:253)
		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)

createSnapshot takes a lot of time

I want scan a Directory and its Childs Directory in Android 11。 and it takes a lot of time.
but my consumer do not know what happed I want add a Progress bar。
maybe not a Percentage bar, just tell consumer it scans how many files。 what should I do?
sir!
hope u will reply me.

[FEATURE] Add "areTheSame" method to fileManager

So it is easy to check if two AbstractFiles, that may be backed by different file implementations, point to the same file or directory. This is really useful, when, for example, we want to copy files from one directory to another and we want to check beforehand whether the directories are the same and do nothing if they are.

The hard part here is that one file may be a RawFile and the other an ExternalFile meaning they will have different base directories. We need to somehow remove the base directory prefixes, then split them into segments and compare segments.

And there is another hard part: SAF encodes segments (like URL does, e.g. ' ' -> %20, etc.) while Java File API does not. So we will probably need to encode them both before comparing. Or decode both.

[IMPROVEMENT/OPTIMISATION] Use FastFileSearchTree as a look-up cache when doing file searching

So basically when using listFiles() (which is being used A LOT, like for EVERY FILE OPERATION, thus the slow speed) cache the results in the FastFileSearchTree and before actually calling the listFiles() check the cache first.

  • If a file is in the cache then check if it actually exists on the disk (AbstractFile.exists()) and if it doesn't remove it from the FastFileSearchTree.
  • If a file does not exist in the cache then call listFiles() and cache the results.

Use it only with the ExternalFile since there is no point in using it with RawFile because we can just construct the file path via new File("/1/2/3/4") and then call whatever we want.

NPE in SAFHelper.listFilesFast

java.lang.NullPointerException: Attempt to get length of null array
	at android.os.Parcel.createException(Parcel.java:1956)
	at android.os.Parcel.readException(Parcel.java:1918)
	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
	at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
	at android.content.ContentResolver.query(ContentResolver.java:803)
	at android.content.ContentResolver.query(ContentResolver.java:753)
	at android.content.ContentResolver.query(ContentResolver.java:711)
	at com.github.k1rakishou.fsaf.util.SAFHelper.listFilesFast(SAFHelper.kt:273)
	at com.github.k1rakishou.fsaf.manager.ExternalFileManager.listFiles(ExternalFileManager.kt:391)
	at com.github.k1rakishou.fsaf.FileManager.listFiles(FileManager.kt:678)
	at com.github.k1rakishou.fsaf.FileManager.traverseDirectory(FileManager.kt:532)
	at com.github.adamantcheese.chan.core.presenter.MediaSettingsControllerPresenter.moveOldFilesToTheNewDirectory(MediaSettingsControllerPresenter.kt:202)
	at com.github.adamantcheese.chan.ui.controller.settings.MediaSettingsController.lambda$askUserIfTheyWantToMoveOldSavedFilesToTheNewDirectory$16$MediaSettingsController(MediaSettingsController.java:522)
	at com.github.adamantcheese.chan.ui.controller.settings.-$$Lambda$MediaSettingsController$2MMLoOIwXgP7VNEqTFosMIebQN8.onClick(Unknown Source:6)
	at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:172)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loop(Looper.java:193)
	at android.app.ActivityThread.main(ActivityThread.java:6718)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:491)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

[Question] How to get fullPath without creating the File Itself?

image

In Above Image As you can see I am creating a File with all the segments I need. I just need its FilePath as String (uri for saf / path for java.io.File) (I can get that using AbstractFile.getFilePath() )
But in order to that I need to create an empty File and delete it, Which is very inefficient!

Can you point me what I can do here? or do I need to manually handle it ?
PS: (What is clone function for?, I really didn't understand that? as literally it should mean cloning the file to new path with its data)
As far as I can see its implementation, clone is what I am looking for.... am I right?

and thanks for this lib, I don't understand why doesn't Android allow me to write to sdcard using java.io.File when I have asked the permission to whole Tree using ACTION_OPEN_DOCUMENT_TREE !!!!, Really, Fuck SAF.

Right way to share the path to DownloadManager...

Hi and thanks for this great library.
I have a question that I have not been able to answer looking at the code and README.md.
I have been able to create a file in a directory selected by the user. At the end of the file creation, I want to notify the user using DownloadManager. I am using this code:

    val downloadManager = ctx.getSystemService(DOWNLOAD_SERVICE) as DownloadManager
    downloadManager.addCompletedDownload(
        filename,
        "dummy description",
        true,
        "text/plain",
        file!!.getFullPath(),
        fileManager.getLength(file),
        true
    )

where file is the file obtained by the creation (i have used the fileManager.createFile method).
So, as you can see I am sharing the fullpath of the file.
The problem is that when I scroll down the notifications and click on the related entry, I receive an error saying that "content:" are blocked. Instead, If I open the Download app and click on the entry, I can open it.
Is there a way to obtain a real path without that content: or am I using DownloadManager in the wrong way?
Regards

[FEATURE] Ability to automatically create AbstractFile in one of the predefined directories depending of some predicate

Lets say you have an app that uses external storage but works with it via the old Java File API. But you need to implement Storage Access Framework because Android R is soon and Scoped Storage will make your app unusable.

You can't just jump into SAF because it may break something for users or you may have to copy some data from one directory to another and you don't want to do that. So instead you may implement a class, provide some function that is going to figure out where to create a file and then just call some method like fileManager.newFile() that is going to create a file in a directory depending on that predicate.

E.g. you have a setting to choose a base directory where some files will be stored that uses Java File API to get that directory. Then you implement a new entry that is going to use SAF to ask the user to select the directory for file dumping. Then you implement a function that checks if the setting contains old java directory path then whenever you call newFile() it will be created in the old directory and if the user decides to change it via SAF then from that point all of the files will be created in the new directory.

Here some code as a rough example of how it should work - https://github.com/K1rakishou/Fuck-Storage-Access-Framework/blob/master/app/src/main/java/com/github/k1rakishou/fsaf/FileManager.kt#L137

SnapshotFileManager findFile and listFiles return null

Hi!
I'm creating a snapshot of a SAF directory, but after that calling findFile() and listFiles() on the returned FileManager return null even if the file exists.
It seems SnapshotFileManager starts tracking the files only after I call create on one.
Is this how this is supposed to work?
How can I use the SnapshotFileManager to list the files that were snapshotted?

Crash "too many SQL variables"

android.database.sqlite.SQLiteException: too many SQL variables (code 1 SQLITE_ERROR): , while compiling: SELECT instance_id, duration, description, orientation, height, is_drm, bucket_display_name, owner_package_name, volume_name, date_modified, date_expires, _display_name, datetaken, mime_type, referer_uri, _id, _data, _hash, _size, title, width, is_trashed, group_id, document_id, is_pending, date_added, download_uri, primary_directory, secondary_directory, original_document_id, bucket_id, relative_path FROM downloads WHERE ((is_pending=0) AND (is_trashed=0)) AND (_data NOT IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) AND relative_path=?)
	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:184)
	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
	at android.content.ContentProviderProxy.query(ContentProviderNative.java:437)
	at android.content.ContentResolver.query(ContentResolver.java:962)
	at android.content.ContentResolver.query(ContentResolver.java:890)
	at android.content.ContentResolver.query(ContentResolver.java:846)
	at com.github.k1rakishou.fsaf.util.SAFHelper.findFile(SAFHelper.kt:151)
	at com.github.k1rakishou.fsaf.util.SAFHelper.findSnapshotFile(SAFHelper.kt:120)
	at com.github.k1rakishou.fsaf.util.SAFHelper.findDeepFile(SAFHelper.kt:80)
	at com.github.k1rakishou.fsaf.manager.ExternalFileManager.toDocumentFile(ExternalFileManager.kt:405)
	at com.github.k1rakishou.fsaf.manager.ExternalFileManager.exists(ExternalFileManager.kt:155)
	at com.github.k1rakishou.fsaf.FileManager.exists(FileManager.kt:590)
	at com.github.adamantcheese.chan.core.saver.ImageSaver.deduplicateFile(ImageSaver.java:533)
	at com.github.adamantcheese.chan.core.saver.ImageSaver.startDownloadTaskInternal(ImageSaver.java:220)
	at com.github.adamantcheese.chan.core.saver.ImageSaver.startDownloadTask(ImageSaver.java:186)
	at com.github.adamantcheese.chan.ui.controller.ImageViewerController.saveShare(ImageViewerController.java:325)
	at com.github.adamantcheese.chan.ui.controller.ImageViewerController.saveClicked(ImageViewerController.java:226)
	at com.github.adamantcheese.chan.ui.controller.ImageViewerController.lambda$YTaxqp3Z9HaAlCji6bOdoidkYgY(Unknown Source:0)
	at com.github.adamantcheese.chan.ui.controller.-$$Lambda$ImageViewerController$YTaxqp3Z9HaAlCji6bOdoidkYgY.clicked(Unknown Source:2)
	at com.github.adamantcheese.chan.ui.toolbar.ToolbarMenuItem.performClick(ToolbarMenuItem.java:200)
	at com.github.adamantcheese.chan.ui.toolbar.ToolbarMenuView.handleClick(ToolbarMenuView.java:92)
	at com.github.adamantcheese.chan.ui.toolbar.ToolbarMenuView.lambda$setupMenuViews$0$ToolbarMenuView(ToolbarMenuView.java:73)
	at com.github.adamantcheese.chan.ui.toolbar.-$$Lambda$ToolbarMenuView$XxndyQBpeckpIT0kUQ_qKt6_FVc.onClick(Unknown Source:4)
	at android.view.View.performClick(View.java:7201)
	at android.view.View.performClickInternal(View.java:7170)
	at android.view.View.access$3500(View.java:806)
	at android.view.View$PerformClick.run(View.java:27562)
	at android.os.Handler.handleCallback(Handler.java:883)
	at android.os.Handler.dispatchMessage(Handler.java:100)
	at android.os.Looper.loop(Looper.java:214)
	at android.app.ActivityThread.main(ActivityThread.java:7682)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

kotlin.NotImplementedError: Not implemented for com.github.k1rakishou.fsaf.file.ExternalFile, fileManagerId = FileManagerId(id='ExternalFile')

E/Kuroba | UNCAUGHT: kotlin.NotImplementedError: Not implemented for com.github.k1rakishou.fsaf.file.ExternalFile, fileManagerId = FileManagerId(id='ExternalFile')
E/Kuroba | UNCAUGHT: 	at com.github.k1rakishou.fsaf.FileManager.getName(FileManager.kt:672)
E/Kuroba | UNCAUGHT: 	at com.github.k1rakishou.fsaf.FileManager.areTheSame(FileManager.kt:858)
E/Kuroba | UNCAUGHT: 	at com.github.adamantcheese.chan.ui.controller.settings.base_directory.SharedLocationSetupDelegate.askUserIfTheyWantToMoveOldSavedFilesToTheNewDirectory(SharedLocationSetupDelegate.kt:102)
E/Kuroba | UNCAUGHT: 	at com.github.adamantcheese.chan.core.presenter.MediaSettingsControllerPresenter$onSaveLocationUseSAFClicked$1$onResult$2.invoke(MediaSettingsControllerPresenter.kt:147)
E/Kuroba | UNCAUGHT: 	at com.github.adamantcheese.chan.core.presenter.MediaSettingsControllerPresenter$onSaveLocationUseSAFClicked$1$onResult$2.invoke(MediaSettingsControllerPresenter.kt:120)
E/Kuroba | UNCAUGHT: 	at com.github.adamantcheese.chan.core.presenter.MediaSettingsControllerPresenter$withCallbacks$1.run(MediaSettingsControllerPresenter.kt:263)
E/Kuroba | UNCAUGHT: 	at android.os.Handler.handleCallback(Unknown Source:2)
E/Kuroba | UNCAUGHT: 	at android.os.Handler.dispatchMessage(Unknown Source:4)
E/Kuroba | UNCAUGHT: 	at android.os.Looper.loop(Unknown Source:242)
E/Kuroba | UNCAUGHT: 	at android.app.ActivityThread.main(Unknown Source:98)
E/Kuroba | UNCAUGHT: 	at java.lang.reflect.Method.invoke(Native Method)
E/Kuroba | UNCAUGHT: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(Unknown Source:11)
E/Kuroba | UNCAUGHT: 	at com.android.internal.os.ZygoteInit.main(Unknown Source:275)

java.lang.IllegalStateException: Failed to touch /storage/emulated/0/Kuroba (1)/1557043536290.jpg: java.io.IOException: No such file or directory

java.lang.IllegalStateException: Failed to touch /storage/emulated/0/Kuroba (1)/1557043536290.jpg: java.io.IOException: No such file or directory
	at android.os.Parcel.readException(Parcel.java:2037)
	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
	at android.content.ContentProviderProxy.call(ContentProviderNative.java:651)
	at android.content.ContentProviderClient.call(ContentProviderClient.java:483)
	at android.provider.DocumentsContract.createDocument(DocumentsContract.java:1178)
	at android.provider.DocumentsContract.createDocument(DocumentsContract.java:1160)
	at com.github.k1rakishou.fsaf.manager.ExternalFileManager.create(ExternalFileManager.kt:128)
	at com.github.k1rakishou.fsaf.manager.ExternalFileManager.create(ExternalFileManager.kt:25)
	at com.github.k1rakishou.fsaf.FileManager.create(FileManager.kt:342)
	at com.github.k1rakishou.fsaf.FileManager.create(FileManager.kt:318)
	at com.github.adamantcheese.chan.core.saver.ImageSaveTask.copyToDestination(ImageSaveTask.java:198)
	at com.github.adamantcheese.chan.core.saver.ImageSaveTask.onSuccess(ImageSaveTask.java:149)
	at com.github.adamantcheese.chan.core.cache.FileCacheV2$handleFileImmediatelyAvailable$1$1.run(FileCacheV2.kt:537)
	at android.os.Handler.handleCallback(Handler.java:790)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:164)
	at android.app.ActivityThread.main(ActivityThread.java:7000)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

Need more help in creating a folder and storing files in it.

As name implies, the library is fcuking awesome, Really its a pain reliver.
But as the SAF is new and complex thing to implement, the library helped a lot, still I am requesting you to guide me some more

  1. creating folder in root directory not this one Android/data/package/files/.....
  2. asking permission for only the created folder not others
  3. store files in the created folder i.e. Image, Video (png, jpeg, mp4 etc)

[Question/Discussion] How to use SAF uriStrings to request a MediaStore scan?

Prior to migrating to SAF, I used to scan my mediaFile like below

MediaScannerConnection.scanFile (
                                applicationContext,
                                listOf(file.absolutePath).toTypedArray(), null, null
                            ) 

Now since the above approach only works with java.io.File Paths, and when using SAF we have content URI Strings, How to do a media scan on media files like mp3 using their URIs?

Apparently, Google Decided to not fix this issue: https://issuetracker.google.com/issues/129089149
So we devs are on our own again, f*** SAF!

java.lang.IllegalArgumentException: Parent document isn't a directory

E/DirectoryManager: dir content://com.android.providers.downloads.documents/tree/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2FKuroba/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2FKuroba is not a directory
E/Kuroba | UNCAUGHT: Called from unhandled exception handler.
E/Kuroba | UNCAUGHT: java.lang.IllegalArgumentException: Parent document isn't a directory
E/Kuroba | UNCAUGHT: 	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:170)
E/Kuroba | UNCAUGHT: 	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
E/Kuroba | UNCAUGHT: 	at android.content.ContentProviderProxy.call(ContentProviderNative.java:658)
E/Kuroba | UNCAUGHT: 	at android.content.ContentResolver.call(ContentResolver.java:2058)
E/Kuroba | UNCAUGHT: 	at android.provider.DocumentsContract.createDocument(DocumentsContract.java:1327)
E/Kuroba | UNCAUGHT: 	at com.github.k1rakishou.fsaf.manager.ExternalFileManager.create(ExternalFileManager.kt:129)
E/Kuroba | UNCAUGHT: 	at com.github.k1rakishou.fsaf.manager.ExternalFileManager.create(ExternalFileManager.kt:25)
E/Kuroba | UNCAUGHT: 	at com.github.k1rakishou.fsaf.FileManager.create(FileManager.kt:342)
E/Kuroba | UNCAUGHT: 	at com.github.k1rakishou.fsaf.FileManager.create(FileManager.kt:318)
E/Kuroba | UNCAUGHT: 	at com.github.adamantcheese.chan.core.saver.ImageSaveTask.copyToDestination(ImageSaveTask.java:202)
E/Kuroba | UNCAUGHT: 	at com.github.adamantcheese.chan.core.saver.ImageSaveTask.onSuccess(ImageSaveTask.java:153)
E/Kuroba | UNCAUGHT: 	at com.github.adamantcheese.chan.core.cache.FileCacheV2$handleFileImmediatelyAvailable$1$1.run(FileCacheV2.kt:538)
E/Kuroba | UNCAUGHT: 	at android.os.Handler.handleCallback(Handler.java:883)
E/Kuroba | UNCAUGHT: 	at android.os.Handler.dispatchMessage(Handler.java:100)
E/Kuroba | UNCAUGHT: 	at android.os.Looper.loop(Looper.java:224)
E/Kuroba | UNCAUGHT: 	at android.app.ActivityThread.main(ActivityThread.java:7520)
E/Kuroba | UNCAUGHT: 	at java.lang.reflect.Method.invoke(Native Method)
E/Kuroba | UNCAUGHT: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
E/Kuroba | UNCAUGHT: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.