Announcement

Collapse
No announcement yet.

Run Java(Android) code from C++ using JNI

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Run Java(Android) code from C++ using JNI

    Hey guys,

    I'm new to C++ programming but I can do Java and Android pretty decently. I know the bare basics of CPP to get myself by with making my game.

    I stick with blueprints but only use cpp where it is required.

    I've been using and learning from UE4 for some time now and trying to make my first game for android but blueprints lack some android functionalities that I would like to add in my game like -

    Orientation control.

    Sending intents

    Accessing native android content providers.

    So, I was looking through forums and answerhub to see useful stuff. I learnt about AndroidJNI but am very unclear on how to use it.

    Some questions if someone could answer them -

    1. Do I need UE4 Launcher or UE4 Source to make custom Java (Android) functions to be called from C++?

    2. Do I need to modify or add my Java code in GameActivity.java file in my Project folder or the Engine folder?

    3. How to use the custom AndroidJNI function via blueprints?


    Please I would be really grateful if someone can provide a step by step guide for implementing this because I have not fiddled with Engine files.

    By looking at the forums and answerhub it seems a pretty common thing.

    Any simple example like making an android Toast BP Function that says "Hello World". or makes a Toast with a String input provided.

    It would be really amazing thank you.

    If I can get it done I would be sure to make a new forum post to help someone who is still a novice with making their games on android. :-D
    Last edited by SHOBBIT; 09-08-2016, 02:37 PM.

    #2
    I was able to do it!. With the help of a plugin by GameDNA studio. Lots of thanks to them.

    Comment


      #3
      Hey, could you post any info or link about that? I´m interested into making an interface to call Android GPS api.

      PD: About orientation control, UE4 already comes with BP solutions to that, the node its called somethink like "input motion" and it return gravity, tilt, accel and rot rate.



      Thanks!
      [MARKETPLACE] The forest like gameplay system | building/crafting game
      Dark Souls 2 fighting system style
      Drivable Space Ship
      Run Knight Run | 48h game made
      Unreal Travel | 48h game made

      Comment


        #4
        Using the code

        The CTest.cpp file contains the code that calls different functions from Java classes. Java classes that are used in this project are given here under:

        HelloWorld.java
        ControlDetail.java
        WorkOrder.java
        ReturnData.java

        HelloWorld.java contains the functions that will be called from CTest.cpp. The other three Java classes are simply used in place of structures in Java. As there is no structure concept in Java, we can use classes for that purpose. That is what the other three .java files contain.

        HelloWorld.java contains the following functions that will be called from C/C++ code:
        Hide Copy Code

        public static void main(String args[])
        {
        }

        public static void TestCall(String szArg)
        {
        }

        public static int DisplayStruct(ControlDetail ctrlDetail)
        {
        }

        public static void DisplayStructArray(WorkOrder ArrWO[])
        {
        }

        public static Object ReturnObjFunc()
        {
        }

        To call these functions from C/C++, first you need to load the JVM using the following function:
        Hide Copy Code

        JNIEnv* create_vm(JavaVM ** jvm) {

        JNIEnv *env;
        JavaVMInitArgs vm_args;

        JavaVMOption options;
        //Path to the java source code
        options.optionString = "-Djava.class.path=D:\\Java Src\\TestStruct";
        vm_args.version = JNI_VERSION_1_6; //JDK version. This indicates version 1.6
        vm_args.nOptions = 1;
        vm_args.options = &options;
        vm_args.ignoreUnrecognized = 0;

        int ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args);
        if(ret < 0)
        printf("\nUnable to Launch JVM\n");
        return env;
        }

        Kindly note that to use this code, you will have to modify the options.optionString variable. You will have to set the path of the Java code: where the Java classes are placed. Currently, it being set to D:\Java Src\TestStruct. You can modify it to you situation. You will also need to modify the JDK version information in the above code, as shown below:
        Hide Copy Code

        vm_args.version = JNI_VERSION_1_6; //JDK version. This indicates version 1.6

        Modify it if you have another JDK version installed.

        To call a specific Java function from C, you need to do the following:

        Obtain the class reference using the FindClass(,,) method.
        Obtain the method IDs of the functions of the class that you want to call using the GetStaticMethodID and GetMethodID function calls.
        Call the functions using CallStaticVoidMethod, CallStaticIntMethod, and CallStaticObjectMethod.

        One important thing to be noted here is specifying the function signatures while obtaining the method IDs.

        To obtain the correct method signature, you can use the following Java command:
        Hide Copy Code

        javap -s -p HelloWorld

        It will display you the signature of each function in the HelloWorld class. These signatures can be used to obtain the method IDs. The result of the above command can be seen below:
        Hide Copy Code

        D:\Java Src\TestStruct>javap -s -p HelloWorld
        Compiled from "HelloWorld.java"
        public class HelloWorld extends java.lang.Object{
        public HelloWorld();
        Signature: ()V
        public static void main(java.lang.String[]);
        Signature: ([Ljava/lang/StringV
        public static void TestCall(java.lang.String);
        Signature: (Ljava/lang/StringV
        public static int DisplayStruct(ControlNEDetail);
        Signature: (LControlNEDetailI
        public static void DisplayStructArray(WorkOrder[]);
        Signature: ([LWorkOrderV
        public static java.lang.Object ReturnObjFunc();
        Signature: ()Ljava/lang/Object;
        }

        Kindly note that while specifying the method name in the GetMethodID function, if the method is a constructor, then its method name will be <init>.
        Prerequisites

        Before traveling down a difficult path, it is important to understand the basic concepts and to have various frameworks and tools installed on your computer.

        You will need the Sun Java Developer Kit (JDK). I recommend Java 1.6.0.
        Any C/C++ compiler installed.

        How to run

        To use this code, follow the instructions below:

        Compile the *.java files using the javac command.
        Compile the CTest.cpp file using any C++ compiler; I used MSVC++ 6.
        Last edited by kaufenpreis; 05-20-2017, 07:10 AM.
        1onlineapotheke.de Cialis bestellen levitra kaufen

        Comment


          #5
          A long and detailed explanation, I have to thank you for taking the time to write down that.

          I´ll try to do it the way you say. Thanks for the advices!
          - Nes
          [MARKETPLACE] The forest like gameplay system | building/crafting game
          Dark Souls 2 fighting system style
          Drivable Space Ship
          Run Knight Run | 48h game made
          Unreal Travel | 48h game made

          Comment


            #6
            For those who come across this post I suggest using this plugin and calling Java code with a single line of code: https://forums.unrealengine.com/comm...ne-4-jni-obj-c

            Comment


              #7
              I recommend using the following plugin - https://github.com/Sovahero/PluginMobileNativeCode
              This plugin can help you call any function and get any native data from Android and iOS in one line of code.

              Comment

              Working...
              X