简体   繁体   中英

List txt files on SD card on Android with Unity

I want to list all txt files in a folder on an SD card on Android using the Unity game engine.

  • permissions READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE are given
  • the txt files exist, I can see them using my file browser on Android. I can also see them in Windows when I connect my phone

But Unity's C# API is not listing any txt files in the folder:

// sdCardFolder is for example "/storage/9C33-6BBD/MyFolderOnSdCard"
string[] filePaths = Directory.GetFiles(sdCardFolder, "*", SearchOption.AllDirectories);
filePaths.ForEach(filePath => Debug.Log(filePath));

But it shows only some of the files. It seems to list images (jpg, png), audio files (mp3, ogg), video files (avi), and maybe more. But it does not list any txt file.

I renamed a file from bla.txt to bla.jpg and bla.foo . The jpg file was listed, but bla.foo was not. Thus, I assume that Android by default only provides access to "typical" media and application files.

Question:

  • Why are the txt files not listed by Unity's C# API?
  • How do I get access to the txt files?
  • Maybe the app requires more permissions?
  • Is it possible to ask Android for full access to a specific folder on an SD card?
    • Some of my Android apps show a dialog to select a folder on an SD card before accessing stuff. Maybe this is required?

I am testing with Android 12, Unity 2021.3.4f1.

Motivation

I have a karaoke game where users can add their own songs. The song format uses txt (plain text) files. I want to enable users to put their song library on an SD card.

Android indeed seems to limit the visiblity of files. But not inside folders that belong to the app itself. You can find these folders via getExternalFilesDirs on Android.

Here is an explanation how to call getExternalFilesDirs in Unity: http://anja-haumann.de/unity-how-to-save-on-sd-card/

private static string GetAndroidExternalFilesDir()
{
     using (AndroidJavaClass unityPlayer = 
            new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
     {
          using (AndroidJavaObject context = 
                 unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
          {
               // Get all available external file directories (emulated and sdCards)
               AndroidJavaObject[] externalFilesDirectories = 
                                   context.Call<AndroidJavaObject[]>
                                   ("getExternalFilesDirs", (object)null);

               AndroidJavaObject emulated = null;
               AndroidJavaObject sdCard = null;

               for (int i = 0; i < externalFilesDirectories.Length; i++)
               {
                    AndroidJavaObject directory = externalFilesDirectories[i];
                    using (AndroidJavaClass environment = 
                           new AndroidJavaClass("android.os.Environment"))
                    {
                        // Check which one is the emulated and which the sdCard.
                        bool isRemovable = environment.CallStatic<bool>
                                          ("isExternalStorageRemovable", directory);
                        bool isEmulated = environment.CallStatic<bool>
                                          ("isExternalStorageEmulated", directory);
                        if (isEmulated)
                            emulated = directory;
                        else if (isRemovable && isEmulated == false)
                            sdCard = directory;
                    }
               }
               // Return the sdCard if available
               if (sdCard != null)
                    return sdCard.Call<string>("getAbsolutePath");
               else
                    return emulated.Call<string>("getAbsolutePath");
            }
      }
}

Note that READ_EXTERNAL_STORAGE permission is still required.

I found that in the folders returned by getExternalFilesDirs , all files are visible to Unity's C# API.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM