i’ve asked this on answers, yet nobody answered for days, so I’m asking from the forum. If someone knows how to solve the problem, please help, stuck badly at here.
I’m currently trying to extend the java part of a game i’m developing for Android. We need to access photo gallery and camera from the device. So we have added a few java classes to [FONT=Courier New]Build/Android/src/…/ folder to call from c++. However, when we tried to access the classes, we are receiving a not found error on jni. We created a simple java class, and tried to call it from an emptry project with also no luck.
I added a few lines to proguard-project.txt to keep the class if it was being removed, yet it was not. I can see that the class exists in dex file.
There is also another problem. We cannot add any files under Build/Android folder (custom proguard file, build file, extended manifest, etc), as it crashes the UnrealBuildTool with a “pak file not found error”, or sometimes, “file already exists”… but that is a different problem.
So… here are the codes that you can use to re-create the circumstances: [FONT=Courier New]proguard-project.txt (C:\Program Files\Epic Games\4.13\Engine\Build\Android\Java)
-keep class com.markakod.hitme.Tools {
public *;
}
This is our simple test class:
package com.markakod.hitme;
import android.content.Context;
import android.widget.Toast;
public class Tools {
public static void openPhotoGallery(Context context, String fileLocation){
Toast.makeText(context, fileLocation, Toast.LENGTH_LONG).show();
}
public static void openCamera(Context context, String fileLocation){
Toast.makeText(context, fileLocation, Toast.LENGTH_LONG).show();
}
}
And this is the code we are using to call the class (exception occurs in FindClass line):
#if PLATFORM_ANDROID
#include "Android/AndroidApplication.h"
#include "Android/AndroidJNI.h"
#endif
void UCaller::CallPhotoGallery(FString Location)
{
UE_LOG(HITMELOG, Error, TEXT("[UCaller::CallPhotoGallery] For %s"), *Location);
CreateFolder();
FString CurrentLocation = LocalImageFolder() + "/" + Location;
FString ClassName = "[Lcom/markakod/hitme/Tools;";
FString MethodName = "openPhotoGallery";
FString MethodSignature = "(Landroid/content/Context;Ljava/lang/String;)V";
#if PLATFORM_ANDROID
UE_LOG(HITMELOG, Error, TEXT("[UCaller::CallPhotoGallery] Get java environment..."));
JNIEnv* Env = FAndroidApplication::GetJavaEnv(false);
FAndroidApplication::CheckJavaException();
UE_LOG(HITMELOG, Error, TEXT("[UCaller::CallPhotoGallery] Get main activity"));
jobject Activity = FAndroidApplication::GetGameActivityThis();
FAndroidApplication::CheckJavaException();
UE_LOG(HITMELOG, Error, TEXT("[UCaller::CallPhotoGallery] Get class %s"), *ClassName);
jclass Class = Env->FindClass(TCHAR_TO_ANSI(*ClassName));
FAndroidApplication::CheckJavaException();
if (Class != NULL) {
UE_LOG(HITMELOG, Error, TEXT("[UCaller::CallPhotoGallery] Get static method %s"), *MethodName);
jmethodID Method = Env->GetStaticMethodID(Class, TCHAR_TO_ANSI(*MethodName), TCHAR_TO_ANSI(*MethodSignature));
FAndroidApplication::CheckJavaException();
if (Method != NULL) {
UE_LOG(HITMELOG, Error, TEXT("[UCaller::CallPhotoGallery] Create string from %s"), *CurrentLocation);
jstring jLocation = Env->NewStringUTF(TCHAR_TO_ANSI(*CurrentLocation));
UE_LOG(HITMELOG, Error, TEXT("[UCaller::CallPhotoGallery] Call static method %s"), *MethodName);
Env->CallStaticVoidMethod(Class, Method, Activity, jLocation);
FAndroidApplication::CheckJavaException();
UE_LOG(HITMELOG, Error, TEXT("[UCaller::CallPhotoGallery] Done..."));
Env->DeleteLocalRef(jLocation);
}
}
#endif
}
From the crash log…
12-28 10:53:08.001 13360 13380 W System.err: java.lang.ClassNotFoundException: Didn't find class "com.markakod.hitme.Tools" on path: DexPathList[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
12-28 10:53:08.001 13360 13380 W System.err: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
12-28 10:53:08.001 13360 13380 W System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
12-28 10:53:08.001 13360 13380 W System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
12-28 10:53:08.001 13360 13380 W System.err: Suppressed: java.lang.ClassNotFoundException: com.markakod.hitme.Tools
12-28 10:53:08.001 13360 13380 W System.err: at java.lang.Class.classForName(Native Method)
12-28 10:53:08.001 13360 13380 W System.err: at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
12-28 10:53:08.001 13360 13380 W System.err: at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
12-28 10:53:08.001 13360 13380 W System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
12-28 10:53:08.001 13360 13380 W System.err: ... 1 more
12-28 10:53:08.001 13360 13380 W System.err: Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
And at last, this is from the dexdump of classes.dex:
dexdump.exe classes.dex | findstr Tools
Class descriptor : 'Lcom/markakod/hitme/Tools;'
#0 : (in Lcom/markakod/hitme/Tools;)
0x0000 - 0x0004 reg=0 this Lcom/markakod/hitme/Tools;
#1 : (in Lcom/markakod/hitme/Tools;)
#2 : (in Lcom/markakod/hitme/Tools;)
source_file_idx : 14003 (Tools.java)
Decompiling the apk proves again that the Tools class exists.
.class public Lcom/markakod/hitme/Tools;
.super Ljava/lang/Object;
.source "Tools.java"