Unfortunately it doesn't seem to work too well with Irrlicht and I'm getting a little frustrated that this is such a big process for audio.
Thanks for your help.
I copied a lot of that sfmlActivity file like so:
#ifdef _IRR_ANDROID_PLATFORM_
namespace {
typedef void (*activityOnCreatePointer)(ANativeActivity*, void*, size_t);
}
const char *getLibraryName(JNIEnv* lJNIEnv, jobject& objectActivityInfo)
{
// This function reads the value of meta-data "sfml.app.lib_name"
// found in the Android Manifest file and returns it. It performs the
// following Java code using the JNI interface:
//
// ai.metaData.getString("sfml.app.lib_name");
static char name[256];
// Get metaData instance from the ActivityInfo object
jclass classActivityInfo = lJNIEnv->FindClass("android/content/pm/ActivityInfo");
jfieldID fieldMetaData = lJNIEnv->GetFieldID(classActivityInfo, "metaData", "Landroid/os/Bundle;");
jobject objectMetaData = lJNIEnv->GetObjectField(objectActivityInfo, fieldMetaData);
// Create a java string object containing "sfml.app.lib_name"
jobject objectName = lJNIEnv->NewStringUTF("sfml.app.lib_name");
// Get the value of meta-data named "sfml.app.lib_name"
jclass classBundle = lJNIEnv->FindClass("android/os/Bundle");
jmethodID methodGetString = lJNIEnv->GetMethodID(classBundle, "getString", "(Ljava/lang/String;)Ljava/lang/String;");
jstring valueString = (jstring)lJNIEnv->CallObjectMethod(objectMetaData, methodGetString, objectName);
// No meta-data "sfml.app.lib_name" was found so we abort and inform the user
if (valueString == NULL)
{
Game::log("No meta-data 'sfml.app.lib_name' found in AndroidManifest.xml file");
exit(1);
}
// Convert the application name to a C++ string and return it
const jsize applicationNameLength = lJNIEnv->GetStringUTFLength(valueString);
const char* applicationName = lJNIEnv->GetStringUTFChars(valueString, NULL);
if (applicationNameLength >= 256)
{
Game::log("The value of 'sfml.app.lib_name' must not be longer than 255 characters.");
exit(1);
}
strncpy(name, applicationName, applicationNameLength);
name[applicationNameLength] = '\0';
lJNIEnv->ReleaseStringUTFChars(valueString, applicationName);
return name;
}
void* loadLibrary (const char* libraryName, JNIEnv* lJNIEnv, jobject& ObjectActivityInfo)
{
// Find out the absolute path of the library
jclass ClassActivityInfo = lJNIEnv->FindClass("android/content/pm/ActivityInfo");
jfieldID FieldApplicationInfo = lJNIEnv->GetFieldID(ClassActivityInfo, "applicationInfo", "Landroid/content/pm/ApplicationInfo;");
jobject ObjectApplicationInfo = lJNIEnv->GetObjectField(ObjectActivityInfo, FieldApplicationInfo);
jclass ClassApplicationInfo = lJNIEnv->FindClass("android/content/pm/ApplicationInfo");
jfieldID FieldNativeLibraryDir = lJNIEnv->GetFieldID(ClassApplicationInfo, "nativeLibraryDir", "Ljava/lang/String;");
jobject ObjectDirPath = lJNIEnv->GetObjectField(ObjectApplicationInfo, FieldNativeLibraryDir);
jclass ClassSystem = lJNIEnv->FindClass("java/lang/System");
jmethodID StaticMethodMapLibraryName = lJNIEnv->GetStaticMethodID(ClassSystem, "mapLibraryName", "(Ljava/lang/String;)Ljava/lang/String;");
jstring LibNameObject = lJNIEnv->NewStringUTF(libraryName);
jobject ObjectName = lJNIEnv->CallStaticObjectMethod(ClassSystem, StaticMethodMapLibraryName, LibNameObject);
jclass ClassFile = lJNIEnv->FindClass("java/io/File");
jmethodID FileConstructor = lJNIEnv->GetMethodID(ClassFile, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
jobject ObjectFile = lJNIEnv->NewObject(ClassFile, FileConstructor, ObjectDirPath, ObjectName);
// Get the library absolute path and convert it
jmethodID MethodGetPath = lJNIEnv->GetMethodID(ClassFile, "getPath", "()Ljava/lang/String;");
jstring javaLibraryPath = static_cast<jstring>(lJNIEnv->CallObjectMethod(ObjectFile, MethodGetPath));
const char* libraryPath = lJNIEnv->GetStringUTFChars(javaLibraryPath, NULL);
// Manually load the library
void * handle = dlopen(libraryPath, RTLD_NOW | RTLD_GLOBAL);
if (!handle)
{
Game::log("dlopen(" + (std::string)libraryPath + "): " + (std::string)dlerror());
exit(1);
}
// Release the Java string
lJNIEnv->ReleaseStringUTFChars(javaLibraryPath, libraryPath);
return handle;
}
void createSFML()
{
JavaVM* lJavaVM = Game::state->activity->vm;
JNIEnv* lJNIEnv = Game::state->activity->env;
// Retrieve the NativeActivity
jobject ObjectNativeActivity = Game::state->activity->clazz;
jclass ClassNativeActivity = lJNIEnv->GetObjectClass(ObjectNativeActivity);
// Retrieve the ActivityInfo
jmethodID MethodGetPackageManager = lJNIEnv->GetMethodID(ClassNativeActivity, "getPackageManager", "()Landroid/content/pm/PackageManager;");
jobject ObjectPackageManager = lJNIEnv->CallObjectMethod(ObjectNativeActivity, MethodGetPackageManager);
jmethodID MethodGetIndent = lJNIEnv->GetMethodID(ClassNativeActivity, "getIntent", "()Landroid/content/Intent;");
jobject ObjectIntent = lJNIEnv->CallObjectMethod(ObjectNativeActivity, MethodGetIndent);
jclass ClassIntent = lJNIEnv->FindClass("android/content/Intent");
jmethodID MethodGetComponent = lJNIEnv->GetMethodID(ClassIntent, "getComponent", "()Landroid/content/ComponentName;");
jobject ObjectComponentName = lJNIEnv->CallObjectMethod(ObjectIntent, MethodGetComponent);
jclass ClassPackageManager = lJNIEnv->FindClass("android/content/pm/PackageManager");
jfieldID FieldGET_META_DATA = lJNIEnv->GetStaticFieldID(ClassPackageManager, "GET_META_DATA", "I");
jint GET_META_DATA = lJNIEnv->GetStaticIntField(ClassPackageManager, FieldGET_META_DATA);
jmethodID MethodGetActivityInfo = lJNIEnv->GetMethodID(ClassPackageManager, "getActivityInfo", "(Landroid/content/ComponentName;I)Landroid/content/pm/ActivityInfo;");
jobject ObjectActivityInfo = lJNIEnv->CallObjectMethod(ObjectPackageManager, MethodGetActivityInfo, ObjectComponentName, GET_META_DATA);
// Load our libraries in reverse order
#if defined(STL_LIBRARY)
#define _SFML_QS(s) _SFML_S(s)
#define _SFML_S(s) #s
loadLibrary(_SFML_QS(STL_LIBRARY), lJNIEnv, ObjectActivityInfo);
#undef _SFML_S
#undef _SFML_QS
#endif
loadLibrary("openal", lJNIEnv, ObjectActivityInfo);
#if !defined(SFML_DEBUG)
loadLibrary("sfml-system", lJNIEnv, ObjectActivityInfo);
loadLibrary("sfml-window", lJNIEnv, ObjectActivityInfo);
loadLibrary("sfml-graphics", lJNIEnv, ObjectActivityInfo);
loadLibrary("sfml-audio", lJNIEnv, ObjectActivityInfo);
loadLibrary("sfml-network", lJNIEnv, ObjectActivityInfo);
#else
loadLibrary("sfml-system-d", lJNIEnv, ObjectActivityInfo);
loadLibrary("sfml-window-d", lJNIEnv, ObjectActivityInfo);
loadLibrary("sfml-graphics-d", lJNIEnv, ObjectActivityInfo);
loadLibrary("sfml-audio-d", lJNIEnv, ObjectActivityInfo);
loadLibrary("sfml-network-d", lJNIEnv, ObjectActivityInfo);
#endif
void* handle = loadLibrary(getLibraryName(lJNIEnv, ObjectActivityInfo), lJNIEnv, ObjectActivityInfo);
// Call the original ANativeActivity_onCreate function
activityOnCreatePointer ANativeActivity_onCreate = (activityOnCreatePointer)dlsym(handle, "ANativeActivity_onCreate");
if (!ANativeActivity_onCreate)
{
Game::log("sfml-activity: Undefined symbol ANativeActivity_onCreate");
exit(1);
}
}
/* Main application code. */
void android_main(android_app* app)
{
// Make sure glue isn't stripped.
app_dummy();
SIrrlichtCreationParameters param;
//param.DriverType = EDT_OGLES1; // android:glEsVersion in AndroidManifest.xml should be "0x00010000" (requesting 0x00020000 will also guarantee that ES1 works)
param.DriverType = EDT_OGLES2; // android:glEsVersion in AndroidManifest.xml should be "0x00020000"
param.WindowSize = dimension2d<u32>(0,0); // using 0,0 it will automatically set it to the maximal size
param.PrivateData = app;
param.Bits = 24;
param.ZBufferBits = 16;
param.AntiAlias = 0;
param. EventReceiver = &Game::receiver;
#ifndef _DEBUG
param.LoggingLevel = ELL_NONE;
#endif
IrrlichtDevice *device = createDeviceEx(param);
if (device == 0)
return;
Game::device = device;
Game::driver = device->getVideoDriver();
Game::smgr = device->getSceneManager();
Game::guienv = device->getGUIEnvironment();
Game::logger = device->getLogger();
Game::fs = device->getFileSystem();
ANativeWindow* nativeWindow = static_cast<ANativeWindow*>(Game::driver->getExposedVideoData().OGLESAndroid.Window);
int32_t windowWidth = ANativeWindow_getWidth(app->window);
int32_t windowHeight = ANativeWindow_getHeight(app->window);
Game::state = app;
createSFML();
//...
From this I am getting the crash trace:
10-13 21:06:04.078 8084 8084 F DEBUG : backtrace:
10-13 21:06:04.078 8084 8084 F DEBUG : #00 pc 002387fc /system/lib/libart.so (_ZN3art9JavaVMExt8JniAbortEPKcS2_+47)
10-13 21:06:04.078 8084 8084 F DEBUG : #01 pc 0023903f /system/lib/libart.so (_ZN3art9JavaVMExt9JniAbortVEPKcS2_St9__va_list+58)
10-13 21:06:04.078 8084 8084 F DEBUG : #02 pc 000ca31b /system/lib/libart.so (_ZN3art11ScopedCheck6AbortFEPKcz+46)
10-13 21:06:04.078 8084 8084 F DEBUG : #03 pc 000c9e37 /system/lib/libart.so (_ZN3art11ScopedCheck11CheckThreadEP7_JNIEnv+154)
10-13 21:06:04.078 8084 8084 F DEBUG : #04 pc 000c8f1f /system/lib/libart.so (_ZN3art11ScopedCheck22CheckPossibleHeapValueERNS_18ScopedObjectAccessEcNS_12JniValueTypeE+26)
10-13 21:06:04.078 8084 8084 F DEBUG : #05 pc 000c83fb /system/lib/libart.so (_ZN3art11ScopedCheck5CheckERNS_18ScopedObjectAccessEbPKcPNS_12JniValueTypeE+802)
10-13 21:06:04.078 8084 8084 F DEBUG : #06 pc 000c0f75 /system/lib/libart.so (_ZN3art8CheckJNI14GetObjectClassEP7_JNIEnvP8_jobject+444)
10-13 21:06:04.078 8084 8084 F DEBUG : #07 pc 0014a9b1 /data/app/com.Project-1/lib/arm/libProject.so (_Z10createSFMLv+36)
10-13 21:06:04.078 8084 8084 F DEBUG : #08 pc 0014ad1d /data/app/com.Project-1/lib/arm/libProject.so (android_main+448)
10-13 21:06:04.078 8084 8084 F DEBUG : #09 pc 002bf8ff /data/app/com.Project-1/lib/arm/libProject.so
10-13 21:06:04.078 8084 8084 F DEBUG : #10 pc 00046eb3 /system/lib/libc.so (_ZL15__pthread_startPv+22)
10-13 21:06:04.078 8084 8084 F DEBUG : #11 pc 00019acd /system/lib/libc.so (__start_thread+6)