How to use XMLSerializer and Filestream on Android? (C#)

I’ve been using the example from this tutorial: Saving and Loading Data: XMLSerializer

to load data from an XML file saved in a “Resources” folder using the XML.Serialization library, and then create classes from the information in that file. Everything works fine when I test the code in the Unity Editor, but not when I build the game for Android.

From the example code, Filestream takes a string for the path as an argument, but since I have to include the “Assets” folder in the path (e.g. “Assets/Resources/file.xml”) the game can’t find the file when I build to Android (because Android doesn’t see the “Assets” folder, only the “Resources” folder e.g. Resources/file) while it works fine in the Editor. Is there any way to get this to work on Android, or am I missing something about paths in Android?

I managed to get my game working on Android, using the StreamingAssets hint that robertbu provided (thanks), although getting it to work was a bit more involved and hacky than I’d like it to be.

I basically had to use the WWW api to begin downloading the file from my Assets/StreamingAssets folder in a Coroutine, wait for the file to finish downloading, then copy the downloaded file to the Application.persistentDataPath directory. I was then able to read the copied file using Filestream and use XMLSerializer on it. I hate how I have to download a file already included in the game in order to read from it, but I guess that’s just how it is.

Here’s the relevant code for those who are interested:

using UnityEngine;
using System.Collections;
using System.IO;

public class readTheFile : MonoBehavior {
	
	WWW www;
	
	void Start () {
		StartCoroutine("Downloader");
	}
	
	void Update () {
		
	}
}

IEnumerator Downloader ()
		{
				#if UNITY_ANDROID && !UNITY_EDITOR //For running in Android
				www = new WWW ("jar:file://" + Application.dataPath + "!/assets/Cards.xml");
				#endif
				#if UNITY_EDITOR // For running in Unity
				www = new WWW ("file://" + Application.streamingAssetsPath + "/Cards.xml");
				#endif
				yield return www; //will wait until the download finishes
				if (www.isDone == true) {
					File.WriteAllBytes (Application.persistentDataPath + "/Cards.xml", www.bytes);
				}		
		}

Now I can close my 50 tabs I have open about this. Or if anyone has a better answer i’d like to see it.

Updated to be more bug free for those interested in more dynamic solutions.
Google ftw?

using UnityEngine;
using System.Collections;
using System.IO;

public class XMLSaveLoad : MonoBehaviour
{
    WWW www;

    void Start()
    {
        StartCoroutine(SaveXML("CharacterData", false));
    }

    IEnumerator SaveXML(string SaveXML, bool save)
    {
        //first time run
        if (!Directory.Exists(Application.dataPath + "/XMLData/"))
            Directory.CreateDirectory(Application.dataPath + "/XMLData/");
        //create file if it's missing
        if (!File.Exists(Application.dataPath + "/XMLData/" + SaveXML + ".xml"))
            File.Create(Application.dataPath + "/XMLData/" + SaveXML + ".xml");

#if UNITY_ANDROID && !UNITY_EDITOR //For running in Android
         www = new WWW ("jar:file://" + Application.dataPath + "!/assets/XMLData/" + SaveXML + ".xml");
#endif
#if UNITY_EDITOR // For running in Unity
        www = new WWW("file://" + Application.dataPath + "/XMLData/" + SaveXML + ".xml");
#endif
        yield return www; //will wait until the download finishes
        if (www.isDone == true)
        {
            if (save)
                File.WriteAllBytes(Application.dataPath + "/XMLData/" + SaveXML + ".xml", www.bytes);
        }
    }
}