com.jme3.asset.AssetNotFoundException: Interface/Fonts/Default.fnt

1. Due to functional requirements, android app needs to be set as a system application;
2. To set it as a system application, I need to add android:shareduserid = "android.uid.system" in AndroidManifest.xml, but JME initialization fails after setting it as a system application; The log is as follows:
   com.jme3.app.AndroidHarnessFragment: 严重 Exception thrown in Thread[GLThread 165,5,main]
   com.jme3.asset.AssetNotFoundException: Interface/Fonts/Default.fnt
    at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:385)
    at com.jme3.asset.DesktopAssetManager.loadFont(DesktopAssetManager.java:434)
    at com.jme3.app.SimpleApplication.loadGuiFont(SimpleApplication.java:193)
    at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:201)
    at com.jme3.app.AndroidHarnessFragment.initialize(AndroidHarnessFragment.java:555)
    at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:342)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1546)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1257)
  1. How do I deal with this phenomenon.

Hi welcome to jme community, why you want to use the app as a system app ?

Some functions may not work properly when the app is a system app including the android application files reader used by jme, so its not recommended to do so, there would be adverse effects, and doing so in Manifest won’t make the app “a system app”.

Check this :

That would probably mean that if you have changed the user app ID, then you cannot access the game package resources & files which in turn would violate the use of Assets & AssetManager.

BTW, app can be settled as system app easily through rooted devices, but that also disrupts the behavior of the app, as setting the app as a system app does nothing but copying the package to the system !

How to deal with this :

  1. remove the uid flag.
  2. Better use the Android Intents, Services, ContentProviders & JobSchedulers to communicate with other apps & system apps within your app, w/o changing your user id or setting the app as system app.
1 Like

It is set as a system application because some functions can only be completed after obtaining permissions, which are only owned by the system application;

Can you give out some examples for those permissions ?

As a substitute, your app can do anything via root permissions, to give your app root permissions use :

final Process = Runtime.getRuntime().exec("su");

Then, you shall proceed from that point to use the Process & the ProcessBuilder with the regular linux commands like cp ,mv & control the I/O to the system, check the docs for Process :
https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html

For example, to obtain such permission, this permission can only be obtained by the system application:

  android.permission.DEVICE_POWER

AFAIK, you will build a bloatware if this can take place & the app is on Google play, but for custom usages you can achieve this through being a superuser(aka using root permission) & running the command “reboot” through a ProcessBuilder.

Example :


I can use commands like :

  1. poweroff.
  2. shutdown.
  3. reboot.
  4. reboot recovery.
  5. mv, cp, rm on file system.
  6. any other Linux native command. May be running a shell script.

You cannot ask a user to control his device power(haven’t seen a permission like this before), but you can ask him for superuser permissions, that would control the device power.

I think maybe you meant malware?

For example, if I found an app on my phone that could turn it off then I’d reset to factory settings and report it to the google store. Like any other malicious software.

Yes, but a bloatware which is preinstalled as a system app, anyway the final result isn’t good for the user.

I wrote a test demo and added it in androidmanifest. XML

 android:shareduserid = "android.uid.system". 

You can use
android.content.res.AssetManager
to load resource files normally, which indicates that assetmanager can work normally. Why can’t it work in jmonkeyengine;

1 Like

android: shareduserid = “android.uid.system” is added to AndroidManifest.xml.
Is there any way to make jmonkeyengine work normally?

Jmonkeyengine uses the android.Resources class, the Android AssetManager is a low level APi a byte level, and the rest of calls is handled by the jme DesktopAssetManager.

The location getassets () still gets

android.content.res.AssetManager

Idk from where the problem is, but all I know that google android developer has warned from the instability behavior resulted from setting shared user id as a system app, besides the feature got deprecated since API level 29, for me I use APi 30, so I cannot go back and test a deprecated feature, sorry.

What is the APi level you are currently using ?

for me I alse use APi 3020211015-180601

Do you have the source code address of Android? GitHub is all the code, not what I want

What do you mean by the source code address of Android ? The android.jar & other androids dependencies can be found on google repositories as well as AOSP.

https://source.android.com/setup/build/downloading

Sorry, I didn’t describe it clearly. Do you have the source code on the Android side of jmonkeyengine 3 (jme3),GitHub is all the code, not what I want(GitHub - jMonkeyEngine/jmonkeyengine: A complete 3-D game development suite written in Java.)

jme3-android
jme3-android-native

Modules on jme3 github repo, the one you linked.