Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android can't open file using LibGDX

I'm currently writing a LibGDX game and I need to open an XML file for a spritesheet. Unfortunately, when I try to open the file, I get an IOException. The files exist in the right places, the project's cleaned and up to date, etc.

Here's the kicker: LibGDX will open and display image files in the same directory, and in fact will obtain the XML file in its own FileHandle object (I've had it logcat the size and it matches up). Yet when I send the file off to a SAX parser, I get an exception leading me back to the file saying that it can't open it.

Here's the problem line of code inside the ClipSprite class:

private void parseConfigFile(FileHandle file) throws ParserConfigurationException, SAXException 
{
    //Use a SAX parser to get the data out of the XML file.
    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser = factory.newSAXParser();
    XMLConfigHandler handler = new XMLConfigHandler();

    //Parse through the document
    try
    {
        parser.parse(file.path(),handler); //IOException here
    }

And here is the code where I select the file in the game in the create method in the main LibGDX class

    //This loads a png file
    texture = new Texture(Gdx.files.internal("data/graphics/CDE1/CDE1.png"));
    texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);      
    TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);

     //Here I load the xml file and it tells me how many bytes it is
    Gdx.app.error("File","xml bytes:"+Gdx.files.internal("data/graphics/CDE1/CDE1.xml").length());

     //Here I load the same file and it crashes
     //Note that it looks in the subdirectory and finds /CDE1.xml properly
    animation = new ClipSprite("data/graphics/CDE1");

Error from logcat:

java.io.IOException: Couldn't open data/graphics/CDE1/CDE1.xml

Why can it identify the file, yet I still get IOExceptions about being unable to open it? Thanks for the help, and I'll provide any more information if necessary.

like image 401
GraphicsMuncher Avatar asked Jan 27 '13 05:01

GraphicsMuncher


1 Answers

Just to coalesce all the comments above into a single answer in case someone else runs into this or something similar:

Try Gdx.files.local() to load your file, instead of Gdx.files.internal(), as the "internal" files are read out of the (compressed) APK and may not be "visible" like a normal file. (This depends a lot on what the code you're passing a pathname to wants to do with it.)

For a libGDX FileHandle file object use file.file() to pass a File handle, instead of file.path() to pass a String that might get misinterpreted.

For a libGDX FileHandle file use file.read() to pass an InputStream directly to the consumer (instead of passing a string or file handle and expecting them to open it).

A libGDX "internal" file maps to an Android AssetManager file, so they can be a bit wonky in some cases. Specifically, they may be compressed and stored within a .jar or .apk and not visible to traditional file reading functions.

like image 188
P.T. Avatar answered Oct 05 '22 22:10

P.T.