Using AAR in Android project

I’ve gone into Unreal/Build/Android/Java/aar-imports.txt and added my aar like so:


com.google.android.gms,kt-bridge,11.0.4

(for now I’m just using com.google.android.gms for testing purposes)

I also know that its properly being packaged into my apk because in my output log I’m getting:


UATHelper: Packaging (Android (ASTC)): Extracting AAR kt-bridge-11.0.4
...
UATHelper: Packaging (Android (ASTC)): Updating project.properties, local.properties, and build.xml for kt-bridge-11.0.4...

now in my code I would like to get the aar and call the method “getInstance”.

I’ve included in my .h file:
“Android/AndroidJNI.h” and “Android/AndroidApplication.h”

and in my .cpp I do:


#if PLATFORM_ANDROID
if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
{
     jclass foundClass = Env->FindClass("com/google/android/gms/kt-bridge");
     if (foundClass)
          return "found class";

     return "did not find class";
}
#endif

which results in:


Abort message: 'java_vm_ext.cc:534] JNI DETECTED ERROR IN APPLICATION: JNI NewStringUTF called with pending exception java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.kt-bridge" on path: DexPathList[directory "."],nativeLibraryDirectories=[/system/lib, /vendor/lib, /system/lib, /vendor/lib]]'

I’m not really sure what I’m doing wrong and can’t seem to find any useful help online.

While aar-imports.txt does still work, the better way is to have your game’s Build.cs register a UPL file to add a dependency block to the build.gradle. The UPL would be something like this:


<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android">
<!-- init section is always evaluated once per architecture -->
<init>
</init>

<buildGradleAdditions>
<insert>
dependencies {
implementation('com.google.android.gms,kt-bridge,11.0.4')
}
</insert>
</buildGradleAdditions>

</root>


As for the failure to find the class, you should use the AndroidJavaEnv::FindJavaClass(“com/google/android/gms/kt-bridge”) instead since it uses the proper ClassLoader. Use AndroidJavaEnv::FindJavaClassGlobalRef() if you need to keep a global reference.

Hey Chris. I decided to take your advice and use UPL.

My XML file:



<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android">
<init>
<log text="KT Bridge"/>
</init>
<resourceCopies>
</resourceCopies>
<!-- AAR dependencies -->
<AARImports>
<insertValue value="com.kt.supervrgame.unityplugin,Bridge,11.0.4" />
<insertNewline/>
</AARImports>
<gameActivityImportAdditions>
<insert>
import com.kt.supervrgame.unityplugin.Bridge;
</insert>
</gameActivityImportAdditions>
<gameActivityClassAdditions>
<insert>
private Bridge KTBridge;
public Bridge getKTBridge() { return KTBridge; }

public String AndroidThunkJava_KTBridge_Init()
{
    String result = "Failed";
    if (KTBridge != null)
    {
        KTBridge.init(App.getContext());
        result = KTBridge.checkAuthenticate();
    }

    return result;
}
</insert>
</gameActivityClassAdditions>
<gameActivityOnCreateAdditions>
<insert>
KTBridge = Bridge.getInstance();
</insert>
</gameActivityOnCreateAdditions>
</root>


and the CPP:



static jmethodID KTBridgeMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_KTBridge_Init", "()Ljava/lang/String;", bIsOptional);

jstring jsString = (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, KTBridgeMethod);
const char* nativeName = Env->GetStringUTFChars(jsString, NULL);
FString ResultName = FString(nativeName);


Is this correct?
No matter what string I try to return I always get the following error using logcat:



Abort message: 'java_vm_ext.cc:534] JNI DETECTED ERROR IN APPLICATION: JNI GetStringUTFChars called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Application.getApplicationContext()' on a null object reference'


I need it to return a string because authenticate returns json.

EDIT: In case someone sees this in the future I fixed it. My issue was with getting the app context incorrectly. My final code looks exactly like what is listed above but instead of “KTBridge.init(App.getContext());” I now have “KTBridge.init(getWindow().getDecorView().getRootView().getContext());”