Search Unity

Cannot Load file on Android!

Discussion in 'Editor & General Support' started by DavidMilot, May 6, 2014.

  1. DavidMilot

    DavidMilot

    Joined:
    Oct 21, 2013
    Posts:
    12
    I've been trying to get this fixed for several nights! I tried to Google and go through this forum for answers. I've tried using Application.persistantDataPath, Application.dataPath, Application.streamingAssetsPath and also tried using the WWW method of reading my file and still cannot get my game to read the files.

    My old code worked on my PC but on Android, nothing. Both files are XML files, they are in my root directory, Assets/<fileName>.xml and they need to be read and written. I'm sure if I get one file to read and written to correctly I can know how to deal with the second XML file. So the GameState.XML file is this.

    Code (csharp):
    1.  
    2. <GameStates>
    3.   <highestLevel>2</highestLevel>
    4.   <solutionCounter>1</solutionCounter>
    5.   <lastPlayDate>635348352983972859</lastPlayDate>
    6. </GameStates>
    7.  
    Code (csharp):
    1.  
    2. public XmlDocument xmlDoc;
    3.  
    4. public void readGameStateFile(){
    5.         xmlDoc = new XmlDocument(); // xmlDoc is the new xml document.
    6.        
    7.         string path1 = Application.streamingAssetsPath + "/GameState.xml";
    8.         XmlReader reader = XmlReader.Create(path1);
    9.         xmlDoc.Load(reader); // load the file.
    10.        
    11.         XmlNode gameStateNode = xmlDoc.DocumentElement;            
    12.         XmlNodeList gameStateContent = gameStateNode.ChildNodes;
    13.        
    14.         foreach (XmlNode stateItems in gameStateContent)
    15.         {
    16.             if(stateItems.Name == "highestLevel"){
    17.                 readHighestLevel(stateItems.InnerText);
    18.             }
    19.            
    20.             if(stateItems.Name == "solutionCounter"){
    21.                 readSolutionCounter(stateItems.InnerText);
    22.             }
    23.            
    24.             if(stateItems.Name == "lastPlayDate"){
    25.                 readLastPlayDate(stateItems.InnerText);
    26.             }
    27.         }      
    28.     }
    29.  
    Everyone's help will be very much appreciated. This loading and file saving issue is my last big hurdle to finishing my game.
     
  2. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    What's the error?

    When you say it "worked on PC", what do you mean? The Editor, a build, what?

    When you say things are in "the root directory", how are you getting them onto the Android device?
     
  3. DavidMilot

    DavidMilot

    Joined:
    Oct 21, 2013
    Posts:
    12
    I'm able to compile and run the game in the Editor. Not on the Android device.

    I'm certain the line causing the problem is:

    Code (csharp):
    1. XmlReader reader = XmlReader.Create(path1);
    Because I have a print( ) statement after that line of code above, it does not show up in the logs. So that's why I strongly believe it's that line causing the problem. I've done more research on finding a solution to this type of problem and haven't found it. I just recently deleted the temp files I had and still doesn't work. Someone talked about file permissions and not sure how to check that.

    The log output that I get is:

    Code (csharp):
    1. 05-06 02:02:42.918: I/Unity(25807):  
    2. 05-06 02:02:42.918: I/Unity(25807): (Filename: C Line: 0)
    3. 05-06 02:02:43.058: I/Unity(25807): UriFormatException: URI scheme must start with a letter and must consist of one of alphabet, digits, '+', '-' or '.' character.
    4. 05-06 02:02:43.058: I/Unity(25807):   at System.Uri.Parse (UriKind kind, System.String uriString) [0x00020] in /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/System/System/Uri.cs:1351
    5. 05-06 02:02:43.058: I/Unity(25807):   at System.Uri.ParseUri (UriKind kind) [0x00000] in /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/System/System/Uri.cs:1215
    6. 05-06 02:02:43.058: I/Unity(25807):   at System.Uri..ctor (System.String uriString, Boolean dontEscape) [0x00064] in /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/System/System/Uri.cs:209
    7. 05-06 02:02:43.058: I/Unity(25807):   at System.Uri..ctor (System.String uriString) [0x00000] in <filename unknown>:0
    8. 05-06 02:02:43.058: I/Unity(25807):   at System.Xml.XmlResolver.ResolveUri (System.Uri baseUri, System.String relativeUri) [0x00064] in /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/System.XML/System.Xml/XmlResolver.cs:66
    9. 05-06 02:02:43.058: I/Unity(25807):   at System.Xml.XmlUrlResolver.ResolveUri (System.Uri baseUri, System.String relativeUri) [0x00000] in /Users/
    I probably didn't use the term root directory correctly, I simply Build the project and have it automatically installed on my device and it starts up immediately. I have Developer Build and Script Debugging checked. Here's the exact location of the GameState.XML file.

    C:\Users\David\Desktop\Popping Bubble Poppers\Assets
     
  4. Graham-Dunnett

    Graham-Dunnett

    Administrator

    Joined:
    Jun 2, 2009
    Posts:
    4,287
    The log file from the android device is basically saying it does not have a c:\ drive. Which I am 100% certain is correct. The documentation for StreamingAssets tells you what the URI needs to be:

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

    ...while on Android, you should use:-

    path = "jar:file://" + Application.dataPath + "!/assets/";
     
  5. DavidMilot

    DavidMilot

    Joined:
    Oct 21, 2013
    Posts:
    12
    I tried writing this:

    Code (csharp):
    1. string path1 = "jar:file://" + Application.dataPath + "!/assets/GameState.xml";
    2. XmlReader reader = XmlReader.Create(path1);
    3. xmlDoc.Load(reader); // load the file.
    Still same error.
     
  6. MakeCodeNow

    MakeCodeNow

    Joined:
    Feb 14, 2014
    Posts:
    1,246
    Make sure your app's manifest has the right permissions, too and/or that your android device has dev SD card access enabled.
     
  7. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    A few things.

    First, from the docs that Graham linked:
    You're trying to access the file directly without accounting for the storage format.

    [quIt's always best to use Application.streamingAssetsPath to get the location of the StreamingAssets folder, it will always point to the correct location on the platform where the application is running.[/quote]

    Secondly, you're writing as well as reading, right? If so then a resource baked into the build won't work. To write the files you'll have to copy them to the app's persistent data path, and use those copies as per any normal file.

    S suggest hitting up the docs to learn about how resources work, it might clear some things up for you. In short, stuff that's in the project folder is not just copied over as files when you do a build. They're baked into some platform-specific binary format which may or may be stored differently on each platform.
     
  8. DavidMilot

    DavidMilot

    Joined:
    Oct 21, 2013
    Posts:
    12
    As far as my Player Settings go:

    Install Location = Prefer External
    Write Access = Internal Only
    Minimum API Level = Android 2.3.1

    I don't think I've touched any of those options. So if these settings aren't correct then tell me and I'll correct them.
     
  9. Sam777

    Sam777

    Joined:
    May 9, 2014
    Posts:
    1
    "...while on Android, you should use:-

    path = "jar:file://" + Application.dataPath + "!/assets/";

    Note that on Android, the files are contained within a compressed .jar file (which is essentially the same format as standard zip-compressed files). This means that if you do not use Unity's WWW class to retrieve the file then you will need to use additional software to see inside the .jar archive and obtain the file."
     
  10. uzairamirs

    uzairamirs

    Joined:
    Jan 7, 2015
    Posts:
    8
    Hi, after almost 4 years, did anyone find the solution to this? I tried what is written in Unity's documentation, i.e.
    path = "jar:file://" + Application.dataPath + "!/assets/";

    but am unable to get a result. However Mr. Sam777's answer confuses me more as I don't know how to use WWW class in Unity.. Can anyone please help?
     
  11. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,276
    The www class does deal with the zip compression of the files that are in the streaming asset path inside the jar file / app.
    You can just use Application.streamingAssetsPath to get the correct path.


    Code (CSharp):
    1.     public string url = [URL='https://docs.unity3d.com/ScriptReference/Application-streamingAssetsPath.html']Application.streamingAssetsPath[/URL] + FilenameWitchExtention;
    2.     IEnumerator Start()
    3.     {
    4.         using (WWW www = new WWW(url))
    5.         {
    6.             yield return www;
    7.             //use www.bytes to get access the bytes of the file.
    8.             // if the file is a image you can use www.texture to get acess to the image texture.
    9.         }
    10.     }
    https://docs.unity3d.com/Manual/StreamingAssets.html
    https://docs.unity3d.com/ScriptReference/WWW.html