Adapting to android with 3.1

So I moved from 3.05 to 3.1. Went fine on desktop.

When turning it into a android game again, I’m facing some problems:
a) The generated MainActivity now extends Activity instead of AndroidHarness, whime means I can’t access variables such as splashPicID, mouseEventsEnabled, etc anymore. I tried making it extend AndroidHarness instead, but seems now I’m missing access to the getFilesDir() method.

b) I have a ic_launcher.png in the correct spot, but I get this problem when I run my game on my android phone:
E/AndroidRuntime(30160): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cis.pipesandstuff.test/com.cis.pipesandstuff.test.MainActivity}: android.content.res.Resources$NotFoundException: File res/drawable-hdpi/ic_launcher.png from xml type layout resource ID #0x7f020000
E/AndroidRuntime(30160): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2092)
E/AndroidRuntime(30160): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2117)
E/AndroidRuntime(30160): at android.app.ActivityThread.access$700(ActivityThread.java:134)
E/AndroidRuntime(30160): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1218)
E/AndroidRuntime(30160): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(30160): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(30160): at android.app.ActivityThread.main(ActivityThread.java:4867)
E/AndroidRuntime(30160): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(30160): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(30160): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
E/AndroidRuntime(30160): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
E/AndroidRuntime(30160): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(30160): Caused by: android.content.res.Resources$NotFoundException: File res/drawable-hdpi/ic_launcher.png from xml type layout resource ID #0x7f020000
E/AndroidRuntime(30160): at android.content.res.Resources.loadXmlResourceParser(Resources.java:2178)
E/AndroidRuntime(30160): at android.content.res.Resources.loadXmlResourceParser(Resources.java:2133)
E/AndroidRuntime(30160): at android.content.res.Resources.getLayout(Resources.java:865)
E/AndroidRuntime(30160): at android.view.LayoutInflater.inflate(LayoutInflater.java:394)
E/AndroidRuntime(30160): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
E/AndroidRuntime(30160): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:316)
E/AndroidRuntime(30160): at android.app.Activity.setContentView(Activity.java:1901)
E/AndroidRuntime(30160): at com.cis.pipesandstuff.test.MainActivity.onCreate(MainActivity.java:24)
E/AndroidRuntime(30160): at android.app.Activity.performCreate(Activity.java:5047)
E/AndroidRuntime(30160): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
E/AndroidRuntime(30160): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2056)
E/AndroidRuntime(30160): … 11 more
E/AndroidRuntime(30160): Caused by: java.io.FileNotFoundException: Corrupt XML binary file
E/AndroidRuntime(30160): at android.content.res.AssetManager.openXmlAssetNative(Native Method)
E/AndroidRuntime(30160): at android.content.res.AssetManager.openXmlBlockAsset(AssetManager.java:487)
E/AndroidRuntime(30160): at android.content.res.Resources.loadXmlResourceParser(Resources.java:2160)

I haven’t modified the Android Manifest, apart from changing screenOrientation: android:screenOrientation=“landscape”.

Any help welcome :smile:

Please disregard first post… it’s garbage… don’t know how that happened, but I didn’t install the netbeans android plugin. Now works fine. If I can give an advice to people: don’t migrate your android application to 3.1 directly… first, create a new BasicGame and get that one running then work on migrating.

I’m now facing a lil problem where the assetManager doesn’t seem to behave the same way under desktop and under android.
Under desktop:

  • works fine
    Under android:
  • Texture tex = assetManager.loadTexture(“Interface/corsicansinspace.png”); //works fine
  • Texture tex = assetManager.loadTexture("**/**Interface/corsicansinspace.png"); //ends up with:
    E/com.jme3.app.AndroidHarnessFragment(14412): com.jme3.asset.AssetNotFoundException: /Interface/corsicansinspace.png (Flipped) (Mipmapped)
    E/com.jme3.app.AndroidHarnessFragment(14412): at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:373)
    E/com.jme3.app.AndroidHarnessFragment(14412): at com.jme3.asset.DesktopAssetManager.loadTexture(DesktopAssetManager.java:393)
    E/com.jme3.app.AndroidHarnessFragment(14412): at com.jme3.asset.DesktopAssetManager.loadTexture(DesktopAssetManager.java:403)
    E/com.jme3.app.AndroidHarnessFragment(14412): at com.cis.pipesandstuff.manictubes2.ManicTubes2.simpleInitApp(ManicTubes2.java:51)
    E/com.jme3.app.AndroidHarnessFragment(14412): at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:227)
    E/com.jme3.app.AndroidHarnessFragment(14412): at com.jme3.app.AndroidHarnessFragment.initialize(AndroidHarnessFragment.java:556)
    E/com.jme3.app.AndroidHarnessFragment(14412): at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:328)
    E/com.jme3.app.AndroidHarnessFragment(14412): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1522)
    E/com.jme3.app.AndroidHarnessFragment(14412): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

Used to work fine under 3.0. Not complaining, just:

  • want to be sure I got it right before going through all of my code and toneGodGUI code to remove those leading “/”.
  • maybe warn others that if they want to target android, they have to not use a leading “/” with asset paths.

Added a bug report here:

1 Like

@loopies
If you have some spare time, could you try

https://github.com/zzuegg/jmonkeyengine/tree/AndroidFix

i have no android device around currently for testing :frowning:

2 Likes

Thanks to both of you… I feel like a princess at her wedding day with all that attention :D.

@zzuegg : took me a while to test your changes, but well, didn’t know anything about git, gradle, building the sdk and I stink at ant and so on, so took a while. Anyway, cloned your version, gradlew built it and ran the ant sdk builder, unzipped it and ran it (with some additional plugins).
Then, I created a new project, and used assetManager to load a texture.

Sadly, I get the same error message at the same location under android.

So I checked with a java decompiler that your changes were present in the AndroidLocator class of the snapshot jme3-android library and they are. Then I checked in the dexed libs and mobile/libs folders and your libs are there. *

I’m a little uncomfortable telling you it doesn’t work because I’m out of my comfort zone here.

Somewhere in the AndroidLocator, they check for “//”… wondering if that needs to be taken into account.

  • I see small differences between the code you linked to in your post and what I see in the decompiled file… here is it’s content, in case it’s of any help:

    package com.jme3.asset.plugins;

    import android.content.Context;
    import android.content.res.AssetFileDescriptor;
    import android.view.View;
    import com.jme3.asset.AssetInfo;
    import com.jme3.asset.AssetKey;
    import com.jme3.asset.AssetLoadException;
    import com.jme3.asset.AssetLocator;
    import com.jme3.system.android.JmeAndroidSystem;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.logging.Logger;

    public class AndroidLocator implements AssetLocator
    {
    private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName());
    private android.content.res.AssetManager androidManager;
    private String rootPath = “”;

    private AndroidAssetInfo create(com.jme3.asset.AssetManager assetManager, AssetKey key, String assetPath)
      throws IOException
    {
      try
         {
           InputStream in = this.androidManager.open(assetPath);
           if (in == null) {
              return null;
           }
      return new AndroidAssetInfo(assetManager, key, assetPath, in);
    

    }
    catch (IOException ex)
    {
    }
    return null;
    }

    public AndroidLocator()
    {
    this.androidManager = JmeAndroidSystem.getView().getContext().getAssets();
    }

    public void setRootPath(String rootPath) {
    this.rootPath = rootPath;
    }

    public AssetInfo locate(com.jme3.asset.AssetManager manager, AssetKey key)
    {
    String assetPath = this.rootPath + key.getName();

    if (assetPath.startsWith("/"))
    {
    assetPath = assetPath.substring(1);
    }
    assetPath = assetPath.replace("//", “/”);
    try {
    return create(manager, key, assetPath);
    }
    catch (IOException ex)
    {
    throw new AssetLoadException("Failed to open asset " + assetPath, ex);
    }
    }

    public class AndroidAssetInfo extends AssetInfo
    {
    private InputStream in;
    private final String assetPath;

    public AndroidAssetInfo(AssetKey<?> assetManager, String key, InputStream assetPath)
    {
    super(key);

    if (assetPath.startsWith("/"))
      this.assetPath = assetPath.substring(1);
    else {
      this.assetPath = assetPath;
    }
    this.in = in;
    

    }

    public AssetFileDescriptor openFileDescriptor() {
    try {
    return AndroidLocator.this.androidManager.openFd(this.assetPath);
    } catch (IOException ex) {
    throw new AssetLoadException("Failed to open asset " + this.assetPath, ex);
    }
    }

    public InputStream openStream()
    {
    if (this.in != null)
    {
    InputStream in2 = this.in;
    this.in = null;
    return in2;
    }
    try
    {
    return AndroidLocator.this.androidManager.open(this.assetPath);
    } catch (IOException ex) {
    throw new AssetLoadException("Failed to open asset " + this.assetPath, ex);
    }
    }
    }
    }

Sorry, I can’t seem to make the code to display correctly

Nah, you are right, did the quick changes afer a long working day. (Note to myself: don’t)
There was already some code in the android locator that should remove the leading /. Without a device availabe hard to track the issue down.
Maybe i am able to setup a old broken device to a level where i can use at least the debugger.

Thx for the help :). You can send stuff my way if you need it tested.

Hi there,

Ive scetched some fixes and workarounds for this issue in Asset paths that begin with "/" don't work on Android · Issue #352 · jMonkeyEngine/jmonkeyengine · GitHub

The simplest workaround is this:
assetManager.unregisterLocator("/", AndroidLocator.class);
assetManager.registerLocator("",AndroidLocator.class);