- Home /
[Android] StreamingAsset problems with XML files
Hello, just to clarify: I am aware, that this question has been asked quite a few times, but so far, none of the solutions proposed worked for me and my specific case. So as I am pretty much at wits end here, I hope that someone out there might be able to help me.
My setup:
I have a leveleditor-scene, which is simply there to create levels. Once created, these are then saved as XML-files in my project. The destinationpath is in this example "Assets/StreamingAssets/XML/Difficulty01/level_data1.xml".
These XML-files are then being read in my actual game-scene to generate levels at runtime. On my PC this works perfectly. But once I try this on Android it doesn't anymore. Now I know, that i can't use the same method on Android as on the PC. Files in the .apk are compressed, so to read and deserialize my XML-files I first have to "unzip" them. So on Android I try something like this:
if (Application.platform == RuntimePlatform.Android)
{
// Android
string realPath = Application.streamingAssetsPath + "/XML/Difficulty01/level_data1.xml";
reader = new WWW (realPath);
while(!reader.isDone)
{
}
XmlSerializer serializer = new XmlSerializer(typeof(Levels));
FileStream stream = new FileStream(reader.url, FileMode.Open);
if(stream != null)
{
lvls = serializer.Deserialize(stream) as Levels;
}
stream.Close();
}
So I try to feed the path of my XML-File to my "WWW reader" to access my zipped files and then try to proceed to deserialize what's at the end of that path. The problem is, that my Filestream doesn't find anything at the path that i feed to him (being reader.url).
The path that is behind the reader.url on Android is the following:
"jar:file:///data/app/com.DefaultCompany.PuzzleGame-1/base.apk!/assets/XML/Difficulty01/level_data1.xml"
Where as I don't really know why there is a "-1" appended to my BundleIdentifier. Anyways, I looked into my .apk file and there is an XML-file at the path "assets/XML/Difficulty01/level_data1".
Why can't i seem to access that file then? is there something wrong with my approach? Is the path in reader.url somehow wrong? I really hope someone here sees my mistake, because i have been trying multiple things for the past week. to no avail.
Please, anyone. It probably is just one tiny error in my code. I just need the proper syntax to make it work. Like I said. The file is on my phone. I can see it, I just don't know how on earth I am supposed to navigate to and read it on android. Every attempt of $$anonymous$$e seems futile. What path is correct in my example? How do i really make use of the www-class in order to access and deserialize my file on android? There has to be someone out there, with the ability to help me.
I don't know if this helps but the manual says:
"On Android, use:
path = "jar:file://" + Application.dataPath + "!/assets/";
"
Unfortunately not. Your snippet amounts to the same thing as
path = Application.strea$$anonymous$$gAssetsPath;
Answer by KathunBen · Sep 30, 2016 at 12:21 PM
Thanks to
saschandroid
who provided a very crucial piece of information, I was finally able to solve this one. Here is my solution and a few insights, that might help others who are stuck with the same problem.
First of: Make sure you actually have .xml-files and not .txt-files in your project. As arbitrary as that sounds, this can be easy to overlook, when you are testing on your PC. Because, when deserializing .txt-files on the PC, Unitys XMLSerializer is capable of interpreting these as if they were .xml-files. But once you switch over to Android this doesn't seem to work anymore. If you aren't sure, just double-click on the file and it should open in your standard-webbrowser, if your file really is an .xml-file.
Another thing to pay attention to is the top line in your .xml-file. To see that, open your file in any texteditor you want. Some web-browsers don't show it, if you try to open it that way.
<?xml version="1.0" encoding="utf-8"?>
Make sure, that it says encoding = "utf-8" , so any phone anywhere can really interpret your .xml-file. If you do it like me and generate your .xml-files through code, make sure you use the Streamwriter-class instead of the Filewriter-class, to change your encoding to the desired encoding = "utf-8". Unfortunately the Streamwriter-class will always overwrite a file, that has the same name in your save-to-path, instead of creating a new one. So make sure your save-to-path really is unique, if you don't want to overwrite existing data. Example:
XmlSerializer serializer = new XmlSerializer(typeof(Levels));
var encoding = Encoding.GetEncoding("UTF-8");
//we will use this to give our xml-file a unique number at the end to prevent it from overwriting an existing file
int uniqueIndex = 1;
//Path you want your xml-files to be saved to
string newPath = "YOURPATH"+"FILENAME"+uniqueIndex.ToString() + ".xml";
//if a file with your name is already there, generate a unique name
while(File.Exists(newPath))
{
uniqueIndex ++;
newPath = "YOURPATH"+"FILENAME"+uniqueIndex.ToString() + ".xml";
}
StreamWriter stream = new StreamWriter(newPath, false, encoding);
serializer.Serialize(stream, lvls);
stream.Close();
And last, but certainly not least, use the MemoryStream-class to deserialize on Android. Your Code should look something like this:
if (Application.platform == RuntimePlatform.Android)
{
string streamingAssetsPath = Application.streamingAssetsPath;
//Make sure your path doesn't miss any '/'
string realPath = streamingAssetsPath + "YOURPATH" + "FILENAME" + ".xml";
WWW reader = new WWW (realPath);
while(!reader.isDone)
{
//wait for the reader to finish downloading
}
XmlSerializer serializer = new XmlSerializer(typeof(Levels));
MemoryStream stream = new MemoryStream(reader.bytes);
if(stream != null)
{
lvls = serializer.Deserialize(stream) as Levels;
}
stream.Close();
}
Thank you very much, this worked perfectly! Thank you very much for sharing!
Answer by monikap_digifit · Dec 07, 2017 at 12:40 PM
@KathunBen Unfortunately I got the error with deserializing my xml file: " XmlException: Document element did not appear. Line 1, position 1." My file includes and it is xml-file, not txt-file. I have no idea what can be the cause. Can you recommend something?I would be really grateful!
Regards, Monika
Your answer
Follow this Question
Related Questions
Read .xml file content with WWW class 0 Answers
How to read xml file on Android using www and StreamingAssets? 2 Answers
Android Streaming asset path won't open 2 Answers
StreamReader can't read Android internal storage path 0 Answers
Saving data 1 Answer