Search Unity

Simple File Browser [Open Source]

Discussion in 'Assets and Asset Store' started by yasirkula, Nov 19, 2016.

  1. Andefob

    Andefob

    Joined:
    Sep 17, 2018
    Posts:
    99
    FYI, my beta player managed to crash SimpleFileBrowser by writing "C:/" to the address bar and pressing enter. I don't have the latest version so I don't know if it has been fixed already, but the reason for the crash seemed to be that for some reason, Directory.GetParent throws an exception with "C:/". I managed to fix that by just replacing the two GetParent calls by calling this instead:
    Code (CSharp):
    1.        
    2.         private DirectoryInfo GetParent(string path)
    3.         {
    4.             try
    5.             {
    6.                 return Directory.GetParent(path);
    7.             }
    8.             catch (Exception e)
    9.             {
    10.                 return null;
    11.             }
    12.         }
    13.  
    Not sure if there are other similar issues and why Directory.GetParent does that...
     
    Last edited: Dec 9, 2021
    yasirkula likes this.
  2. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You're right. Typing
    C:
    or
    C:/
    failed while
    C:\
    succeeded. I'll fix this issue locally and push the fix in the next update.
     
  3. VResearch

    VResearch

    Joined:
    Jan 6, 2021
    Posts:
    21
    Hello, thanks for the asset and good work. I have one question, though. When I hit "play" in the editor to try it out for the very first time, everything is working correctly. But from the second time onward, I can no longer see the names of the drives and folders in the "shortcuts" panel. All I can see is "filename" everywhere. There are no Simple File Browser-related errors or warnings in the console. Also, GitHub does not detect any changes in the plugin files. I can fix this by reimporting the asset, and it will again work once, but I imagine there must be a more permanent solution... Thanks a lot if you can point me to one :)
    upload_2021-12-10_21-10-38.png
     
    Last edited: Dec 10, 2021
  4. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    This has never happened to me and there aren't any errors in the console so I don't have much to debug the issue :D It might be a Unity bug where Texts aren't updated for unknown reasons. If you are calling the file browser in Awake, does calling it in Start or later make any difference?
     
  5. polygonfuture

    polygonfuture

    Joined:
    Feb 4, 2016
    Posts:
    20
    Hi @yasirkula ,

    Using your file browser for Unity 2021.1.10 on a Quest 2 (VR) in World space canvas attatched to a hand controller (for a moving menu).

    I'm using the Show() and Hide() functions, but I need to be able to adjust the filters while using the same game object.

    Is there a specific way that I can adjust the file filters with an existing instantiated game object?
    I've looked into changing the FileBrowser class's 'Instance' property to public, but im still not able to access the class different methods.
     
  6. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    If there is only a single instance of FileBrowser in your scene and it's active at the beginning of the game (you can deactivate it in Start if you wish), then all FileBrowser functions will be applied to your instance. So you don't need to modify the source code at all, simply make your FileBrowser active at the beginning of the game and hide it in Start if needed.
     
  7. polygonfuture

    polygonfuture

    Joined:
    Feb 4, 2016
    Posts:
    20
    Ah ok. I think the SetDefaultFilter() method was confusing me as it did not seem to be changing the starting filter on an existing instance.

    For best practices, lets say I want to open a file browser and ensure that it is only showing a single filter visible. Would SetDefaultFilter be the function? It appeared I could not get this method to do anything to the existing FileBrowser instance.

    Instead I simply re-ran the SetFilters() method which seemed to work. Is there any downside to running SetFilters each time the browser is opened (when I need to change what filters are active)?
     
  8. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    If you call SetFilters before SetDefaultFilter, I don't see a reason for it to not work. I may have to see your code. P.S. Make sure to call these in Start and not Awake so that the FileBrowser instance in your scene gets a chance to be registered as the active FileBrowser (i.e. let FileBrowser's Awake function be called first).

    You don't need to call SetFilters more than once if you always pass the same parameters to it. But calling it more than once won't cause any issues either, it will just be wasting performance on that frame (which is negligible tbh).
     
  9. polygonfuture

    polygonfuture

    Joined:
    Feb 4, 2016
    Posts:
    20
    Great thanks so much Yasikurla.

    Another quick question which I havnt seen asked yet.
    Similar to the SetExcludedExtensions, Is there a method to hide specific folders?
     
    yasirkula likes this.
  10. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  11. polygonfuture

    polygonfuture

    Joined:
    Feb 4, 2016
    Posts:
    20
    Ok great. I'll look into implementing my own.

    One other question, when testing I notice the documentation mentions the HideDialogue method's invokeCancelCallback can be used for pre-initializing the dialoge (if instantiating it runtime).

    public static void HideDialog( bool invokeCancelCallback = false );


    Can you give more detail or an example of how you would use this to pre-initialize?
    I understand you could ShowLoadDialog at runtime, and HideDialog right after, but what is the correct way to show it without a reference to its instance? Do we just use ShowLoadDialog? I'm not sure I understand how you would use the invokeCancelCallback in this scenario.

    I wasnt sure if this prevents a second instance from being instantiated during runtime if one already exists.
     
  12. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    All public FileBrowser functions and properties are static so you are always working with a single FileBrowser instance. You can call FileBrowser.HideDialog(); and it will hide the visible dialog. If a dialog doesn't exist, SimpleFileBrowserCanvas will be instantiated and hidden immediately afterwards which is how this initialization works. Later FileBrowser calls will use that instance. invokeCancelCallback is only useful if the dialog is visible and an onCancel callback function was assigned to it. In this case, that onCancel callback will be invoked while hiding the browser.
     
  13. polygonfuture

    polygonfuture

    Joined:
    Feb 4, 2016
    Posts:
    20
    Perfect, thanks Yasirkula.
     
    yasirkula likes this.
  14. csszombie10

    csszombie10

    Joined:
    Oct 20, 2021
    Posts:
    6
    i m new to unity and just found your helpful assets but it seems like i cant get it to work it keep saying that "object reference not set to an instance of an object" and it keep mentioning the "RecycledListView" script but after i assign some object on to the script the "file browser" , "Viewport transform" , and "Content transform" the problem still occured.. is there any tutorial on how to set this properly ?? or i just setting it up incorrectly ?? ;-;
     

    Attached Files:

  15. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    The references must've become null for unknown reasons. I'd recommend you to delete the plugin and reimport it from scratch. Then use FileBrowser.ShowLoadDialog to display the dialog.
     
  16. csszombie10

    csszombie10

    Joined:
    Oct 20, 2021
    Posts:
    6
    also did i import the part correctly ?? or it was my fault on putting the component incorrectly, because i want to be sure that if i did it correctly or not before proceeding to reimport the plugins again ;-;
     

    Attached Files:

  17. csszombie10

    csszombie10

    Joined:
    Oct 20, 2021
    Posts:
    6
  18. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You don't need to modify the plugin's files in any way so a clean reimport would be the safest option. You can check out both the documentation and the example code at that page to learn ShowLoadDialog's usage.
     
  19. csszombie10

    csszombie10

    Joined:
    Oct 20, 2021
    Posts:
    6
    so i just need to reimport the plugin, put all the parts together and rerun it ?? kk got it >w<
     
  20. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    "put all the parts together" You definitely do not need to do anything remotely close to this as I've been trying to explain in my previous messages.
     
  21. csszombie10

    csszombie10

    Joined:
    Oct 20, 2021
    Posts:
    6
    ok i already redo everything before like importing and re-assign the parts of the "FileBrowser" and the problem still persist also i m already trying to use the "FileBrowser.ShowLoadDialog" but it somehow wont work because the ShowLoadDialog is not declared ?? do i have to declared it first ?? because you said that the function has been declared inside the "SimpleFileBrowser" plugin file before ?? ;-; upload_2021-12-21_15-59-8.png upload_2021-12-21_15-59-33.png
     
  22. csszombie10

    csszombie10

    Joined:
    Oct 20, 2021
    Posts:
    6
    then how do i use the plugin ?? do i just need to make an empty game object and put the "FileBrowser" script to the empty game object assign it to the button and run it ?? o.o
     
  23. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @polygonfuture Added
    FileBrowser.DisplayedEntriesFilter
    event to programmatically filter the displayed entries in the latest update (available on GitHub, pending review on Asset Store).
     
  24. urashid957

    urashid957

    Joined:
    Mar 4, 2020
    Posts:
    2
    Thanks for this Amazing Asset,
    I have a little issue, when I run it on Android and try to get the folder path, It gives ma a wrong path and it's like this.
    content://com.android.extrnalstorage.documents/tree/primary%3ADocument%2FModel%2Fphone
    Because of this %2 or %3 like text in path couldn't write anything in the folder
    @yasirkula
     
  25. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Hi! This is a Storage Access Framework path. To work with these paths, I've created the FileBrowserHelpers class. Please use its functions for IO operations on the returned paths.
     
  26. urashid957

    urashid957

    Joined:
    Mar 4, 2020
    Posts:
    2
    @yasirkula
    Which function of FileBrowserHelpers will be needed to get the correct Path?
     
  27. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    There isn't a way to convert SAF path to raw file path. I've now replied to your private message.
     
  28. unityChu

    unityChu

    Joined:
    Feb 2, 2018
    Posts:
    7
    Hello,
    First, thanks for your product.
    Second, it keeps rendering my script unloadable, it imported alright, but once I do some coding in my script, "all" my scripts become "unloadable"!

    https://imgur.com/gZ00Oyk


    The whole project is ruined!
    Good thing I made a backup 3 days ago.
    But once I reimport the asset and do some coding, the same thing happened again!
    Could you please be so kind and teach me how to fix it?

    Much appreciated!
     
  29. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    What are the compiler errors in the Console? Hitting Clear won't clear them, that's how you can distinguish them.
     
  30. unityChu

    unityChu

    Joined:
    Feb 2, 2018
    Posts:
    7
    OH! I fixed it! Thanks for your help!
    Sorry for bothering you with such a stupid mistake!
     
    yasirkula likes this.
  31. coolcup

    coolcup

    Joined:
    Jan 5, 2022
    Posts:
    1
    Hello
    I'd like to say thank you at first for sharing.
    I am very beginner for unity and I have no idea about what to do next after importing package. ^^;;;;;
    Please let me know to launch file browser on my android phone.
    Thanks in advance.
     
  32. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Hi! You'll need some level of scripting knowledge to be able to use this plugin. You can find an example code and detailed instructions on the GitHub page.
     
    coolcup likes this.
  33. ComeOnAndSam

    ComeOnAndSam

    Joined:
    Nov 8, 2016
    Posts:
    62
    So I haven't been able to get this to work. I throw the canvas prefab into my scene and press play and nothing pops up, in editor and in builds for all platforms, and there's no errors
    upload_2022-2-2_13-47-37.png

    I don't know if there's some kind of setup step I'm missing, but I been able to find any additional instructions in the documentation.
     
    Last edited: Feb 2, 2022
  34. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  35. JPMay

    JPMay

    Joined:
    Dec 13, 2021
    Posts:
    6
    cheers @yasirkula ! Does it work on Mac desktop build? I'll give it a try now!

    ... actually it WORKS PERFECTLY on Mac, @yasirkula !

    We immediately sent you a fatass "tip" on PayPal - thank you so much for this. Perfect.
     
    Last edited: Feb 10, 2022
    yasirkula likes this.
  36. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Happy to help and thank you for your support :)
     
  37. ComeOnAndSam

    ComeOnAndSam

    Joined:
    Nov 8, 2016
    Posts:
    62
    So I figured out the reason my file browser is just blank is because it never initializes. I had to add "InitializeQuickLinks()" to the end of the Awake() function to make everything appear. quickLinksInitialized is false otherwise and that variable needs to be true to make the drives/directories appear when it's checked later.

    That can't be right, why did I have to do that?
     
  38. ComeOnAndSam

    ComeOnAndSam

    Joined:
    Nov 8, 2016
    Posts:
    62
    Additionally, its not properly granting permissions for android

    "UnauthorizedAccessException: Access to the path '/storage/emulated/0' is Denied"
     
  39. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You definitely don't need to do that. You need to show the file browser with ShowLoadDialog or ShowSaveDialog functions. It might be related to UnauthorizedAccessException, as well.
     
  40. ComeOnAndSam

    ComeOnAndSam

    Joined:
    Nov 8, 2016
    Posts:
    62
    That's what I was missing, thanks!
     
    yasirkula likes this.
  41. wztk

    wztk

    Joined:
    Feb 25, 2020
    Posts:
    36
    Hi guys,

    Is there any way to use this asset with Android 11 +?
    I'm making a game which has a copy and a move file option but whenever I try it it throws a following error: java.io.FileNotFoundException: Failed to open for writing: java.io.FileNotFoundException: open failed: EISDIR (Is a directory). I can't seem to figure out any way to make it work.

    Here's the code I'm working with:
    Code (CSharp):
    1. try
    2.         {
    3.             FileBrowserHelpers.MoveFile(FileBrowser.Result[0], $"{Constants.persistentDataPath}/levels/{pathText.text}");
    4.             exitMessage.SetActive(true);
    5.         }
    6.         catch
    7.         {
    8.             errorMessage.SetActive(true);
    9.         }
    10. }
    Note: Constants.persistentDataPath is the same as Application.persistentDataPath.
    Has anybody encountered a similar issue and knows how to resolve it or has any ideas? I would much appreciate any response.
     
  42. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Hi, did you pick files or folders with the file browser? Does levels folder exist in persistentDataPath?
     
  43. wztk

    wztk

    Joined:
    Feb 25, 2020
    Posts:
    36
    Hi, I used pick files as an option with the file browser. And yes, levels folder does exist in persistentDataPath.
    I've also tried adding following lines to the Manifest, to no avail.

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
    +<application android:requestLegacyExternalStorage="true">

    Unfortunately I had no idea that there's a thing called Scoped Storage which makes file access really difficult, so the game is already released, but has limited functionality on Android 11.
     
  44. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    What do these functions log:
    Code (CSharp):
    1. Debug.Log( FileBrowser.Result[0] );
    2. Debug.Log( FileBrowserHelpers.FileExists( FileBrowser.Result[0] ) );
    3. Debug.Log( FileBrowserHelpers.DirectoryExists(FileBrowser.Result[0] ) );
    4. Debug.Log( FileBrowserHelpers.DirectoryExists($"{Constants.persistentDataPath}/levels" ) );
     
  45. wztk

    wztk

    Joined:
    Feb 25, 2020
    Posts:
    36
    I used copy function instead since it was easier to log stuff from there. The code is practically the same but you choose folder instead.
    Here's a short snippet:
    Code (CSharp):
    1. string name = $"{selectLevel.currentMenuDetails.artist} - {selectLevel.currentMenuDetails.title}.rb";
    2.             FileBrowserHelpers.CopyFile($"{Constants.persistentDataPath}/levels/{name}", $"{Path.Combine(FileBrowser.Result[0], name)}");
    And these are the logs:
    Code (CSharp):
    1. content://com.android.externalstorage.documents/tree/primary%3AMusic/document/primary%3AMusic
    2. False
    3. True
    4. False
    Obviously in this case it should be false, true, true, so I did some further digging and tried adding /files/ to the path since android 11 has that extra folder, but then it returned following:
    Code (CSharp):
    1. java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.WMS.RhythmBlaster/files/files/levels/Dy - dy.rb: open failed: ENOENT (No such file or directory)
    I've checked if the file exists and it absolutely does, so it's probably a permission error if I had to guess.
     
  46. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Could you please give this code a try:
    Code (CSharp):
    1. yield return FileBrowser.WaitForLoadDialog( FileBrowser.PickMode.Files );
    2. FileBrowserHelpers.CopyFile( FileBrowser.Result[0], Path.Combine( Application.persistentDataPath, FileBrowserHelpers.GetFilename( FileBrowser.Result[0] ) ) );
     
  47. wztk

    wztk

    Joined:
    Feb 25, 2020
    Posts:
    36
    That works fine, the problem lies in doing it the other way around, that is - moving something out of persistentDataPath.
    I tried doing it very carefully, but even though the application has access to a specific folder, it doesn't seem to register it's existence.
    Below code:
    Code (CSharp):
    1. string name = $"{selectLevel.currentMenuDetails.artist} - {selectLevel.currentMenuDetails.title}.rb";
    2.             string folder = Path.Combine(Application.persistentDataPath, "levels/");
    3.             string path = Path.Combine(folder, name);
    4.             Debug.Log(path);
    5.             FileBrowserHelpers.CopyFile(path, FileBrowser.Result[0]);
    returns:
    /storage/emulated/0/Android/data/com.WMS.RhythmBlaster/files/levels/Dy - dy.rb
    java.io.FileNotFoundException: Failed to open for writing: java.io.FileNotFoundException: open failed: EISDIR (Is a directory)
    at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:151)
    at android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:704)
    at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1843)
    at android.content.ContentResolver.openOutputStream(ContentResolver.java:1545)
    at com.yasirkula.unity.FileBrowser.WriteToSAFEntry(FileBrowser.java:343)
    at com.yasirkula.unity.FileBrowser.CopyFile(FileBrowser.java:257)

    I also tried adding filename there as well (Path.Combine(FileBrowser.Result[0], name)), but no help unfortunately, same error.
     
    Last edited: Mar 2, 2022
  48. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Try this:
    FileBrowserHelpers.CopyFile(path, FileBrowserHelpers.CreateFileInDirectory(FileBrowser.Result[0], name));
    But please try overwriting the file, as well. I'm not entirely sure what CreateFileInDirectory does in that case.
     
    wztk likes this.
  49. wztk

    wztk

    Joined:
    Feb 25, 2020
    Posts:
    36
    Thank you! This solution works wonders, brilliant stuff. Writing and overwriting both work exactly as they're supposed to.
     
    yasirkula likes this.
  50. chgeorgiadis

    chgeorgiadis

    Joined:
    Jan 30, 2018
    Posts:
    51
    Thank you for the perfect plug in. It is very usefull for android. is that possible to usa the above solution but WITHOUT open dialog? i would like to save a json file and i would like to store it without opening the dialog, just with the button that makes the json file. Thank you!