Access Unity StreamingAssets on Android

I wrote the code to get all the folders inside the folder inside StreamingAssets, and then get all the files in this folder. It works fine on Windows, but I can't get it to work on Android.

Here is the code:

foreach (string s in Directory.GetDirectories(model.path + "/Levels")) { GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity); el.transform.SetParent(grid1.transform); string[] words = s.Split('/'); #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN words = s.Split('\\'); #endif el.GetComponentInChildren<Text>().text = words[words.Length - 1]; el.GetComponent<Button>().onClick.AddListener(() => { MapSizeButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text)); }); } 

I had to add #if UNITY_STANDALONE_WIN for windows due to '\'.

Then for the files inside this folder, I wrote the following:

 foreach (string s in Directory.GetFiles(model.path + "/Levels/" + model.mapSize + "/" + model.colorNumber)) { string[] words = s.Split('/'); #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN words = s.Split('\\'); #endif words = words[words.Length - 1].Split('.'); if (words[1] == "json") { GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity); el.transform.SetParent(grid3.transform); el.GetComponentInChildren<Text>().text = words[0]; el.GetComponent<Button>().onClick.AddListener(() => { levelButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text)); }); } } 

I use UnityEngine.UI.Directory, but I read that it cannot be used on Android, and I should use WWW instead. Something like that:

 string xmlSetUpPath = "jar:file://" + Application.dataPath + "!/assets/xml/xmlSetUp.xml"; WWW book1WWW = new WWW(book1Path); yield return book1WWW; if(!File.Exists(Application.persistentDataPath + "/xml/book1.xml")) { File.WriteAllBytes(Application.persistentDataPath + "/xml/book1.xml", book1WWW.bytes); } 

However, I could not find anything like Directory.getFiles () or Directory.getFolder (). So I thought I could use the WWW to check if a file exists (since the file names are: 1.json, 2.json, 3.json) and iterate until the file exists.

But I also need to check if a folder exists for the 1st part of the script, and I can not find how to check if a folder exists from the WWW. (My folder names are also 1,2,3,4 ...)

So how to check if a folder with www exists?

Or what else can I do?

UPDATE:

I updated the code, now it looks like this:

 for (int i = 0; i < 100; i++) { if (Directory.Exists(Path.Combine(model.path, "Levels/" + i.ToString()))){ GameObject el = (GameObject)Instantiate(listButton, Vector3.zero, Quaternion.identity); el.transform.SetParent(grid1.transform); el.GetComponentInChildren<Text>().text = i.ToString(); el.GetComponent<Button>().onClick.AddListener(() => { MapSizeButtonClick(Int32.Parse(el.GetComponentInChildren<Text>().text)); }); } } 

I use path.combine () and check every folder from 0 to 100. It works on Windows, but it still does not work on Android.

The path is set as follows:

 #if UNITY_IPHONE path = Application.dataPath + "/Raw"; #endif #if UNITY_ANDROID path = "jar:file://" + Application.dataPath + "!/assets"; #endif #if UNITY_STANDALONE || UNITY_EDITOR path = Application.dataPath + "/StreamingAssets"; #endif 

UPDATE QUESTION

I created a script that generate file paths. The paths are always the same: "FolderNumerotedFromYToX / FolderNumerotedFromYToX / FileNumerotedFrom1ToX.json." Generation works, but there is no writing in JSON. It displays "{}".

  // Generate level list List<KeyValuePair<int, List<KeyValuePair<int, List<int>>>>> l; l = new List<KeyValuePair<int, List<KeyValuePair<int, List<int>>>>>(); for (int i = 1; i < 100; i++) { if (Directory.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i.ToString()))) { l.Add(new KeyValuePair<int, List<KeyValuePair<int, List<int>>>>(i, new List<KeyValuePair<int, List<int>>>())); for (int j = 1; j < 100; j++) { if (Directory.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i + "/" + j))) { l[l.Count - 1].Value.Add(new KeyValuePair<int, List<int>>(j, new List<int>())); int k = 1; while (true) { if (File.Exists(Path.Combine(Path.Combine(Application.dataPath, "StreamingAssets"), "Levels/" + i + "/" + j + "/" + k + ".json"))) { l[l.Count - 1].Value[l[l.Count - 1].Value.Count - 1].Value.Add(k); } else break; k++; } } } } } string ljson = JsonUtility.ToJson(l); var lsr = File.CreateText("Assets/StreamingAssets/levels.json"); lsr.WriteLine(ljson); lsr.Close(); 

Can you help me find a way to save this in a file?

+6
source share
2 answers

This may sound complicated, but you really need to use the WWW class to access your files from StreamingAssets on Android.

And you have to keep a list of your file names in order to access them, since there seems to be no way to use something like File.Exists or Directory.GetFiles .

Example:

 WWW www = new WWW(source); yield return www; if (string.IsNullOrEmpty(www.error)) { // make sure the destination directory exists File.WriteAllBytes(destination, www.bytes); } else { // error handling } 

The path to the source files (base) should look like this: jar:file://" + Application.dataPath + "!/assets/


From the docs:

Please note that on Android files are contained in a compressed .jar file (which is essentially the same format as standard zip-compressed files). This means that if you are not using the Unitys WWW class to extract the file, then you will need to use additional software to view the .jar inside the archive and get the file.

Source: http://docs.unity3d.com/Manual/StreamingAssets.html

+5
source

To solve this problem, I created a pre-compilation script that will be run before compilation; this script will list the names of the files you want to get later in a text file

  #if UNITY_EDITOR using UnityEditor.Build; using UnityEditor; using System.IO; public class BM_AndroidBuildPrepartion : IPreprocessBuild { public int callbackOrder { get { return 0; } } public void OnPreprocessBuild(BuildTarget target, string path) { // Do the preprocessing here string[] fileEntries = Directory.GetFiles("Assets/Resources/Prefabs/alphabet", "*.prefab"); System.IO.Directory.CreateDirectory("Assets/StreamingAssets/"); using (StreamWriter sw = new StreamWriter("Assets/StreamingAssets/alphabet.txt", false)) { foreach (string filename in fileEntries) { sw.WriteLine(Path.GetFileNameWithoutExtension(filename)); } } } } #endif 

then I read the text file and you can access the files the same way, but you have to put them in your project in Assets / StreamingAssets /

 #if UNITY_ANDROID string path = "jar:file://" + Application.dataPath + "!/assets/alphabet.txt"; WWW wwwfile = new WWW(path); while (!wwwfile.isDone) { } var filepath = string.Format("{0}/{1}", Application.persistentDataPath, "alphabet.t"); File.WriteAllBytes(filepath, wwwfile.bytes); StreamReader wr = new StreamReader(filepath); string line; while ((line = wr.ReadLine()) != null) { //your code } #endif 
+1
source

All Articles