Search Unity

Android Plugin - Call C# from Java

Discussion in 'Android' started by robhuhn, Feb 18, 2011.

  1. robhuhn

    robhuhn

    Joined:
    Jun 21, 2009
    Posts:
    113
    I want to call a method in C# from Java via JNI. Did someone try this before with Unity or is it even possible?
     
  2. robhuhn

    robhuhn

    Joined:
    Jun 21, 2009
    Posts:
    113
    aww, I was looking for this for hours but finally I found a solution.
    Code (csharp):
    1.  
    2. UnityPlayer.UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
    Same as in iOS but it's not documented for android or am I missing something?
     
  3. Wozik

    Wozik

    Joined:
    Apr 10, 2009
    Posts:
    662
    Robhuhn, it's documented, but the docs will be available with the next release.
     
  4. Filip Van Bouwel

    Filip Van Bouwel

    Joined:
    May 11, 2011
    Posts:
    5
    I'm trying to do this as well, but I can't seem to get it to work. The problem is probably that my java doesn't know the UnityPlayer class or the UnitySendMessage() function. Do I need to add a reference to the UnityEngine or anything in my java library (I'm using Eclipse to generate the .jar file)?
     
  5. Milan_cool

    Milan_cool

    Joined:
    Jan 24, 2011
    Posts:
    22
    yes you need to import classes.jar files.Also i like to suggest you use AndroidJavaObject for that.It would be easy.We neednt require jni part.
     
    sj631 likes this.
  6. Filip Van Bouwel

    Filip Van Bouwel

    Joined:
    May 11, 2011
    Posts:
    5
    That part I have. Calling Java from C# with AndroidJavaObject works. But I wanna call C# code from within my java code (as I need to wait for a callback in java before I can return the return value to my C# code). And that should be done (as I understand it) with the UnitySendMessage() function from within java. But I can't get that to work.
     
    Last edited: May 11, 2011
  7. ahmed_ameen21

    ahmed_ameen21

    Joined:
    May 15, 2011
    Posts:
    4
    Hi,
    I want to call C# function from java.
    I made a call from java as below:
    UnityPlayer.UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
    and in the unity script i have created the function GameObjectName1.
    but, i don't know how to specify a receiver for the function.

    When i run the code, i get the below error:
    object GameObjectName1 doesn't have receiver for function MethodName1.
    I tried to define the GameObjectName1 as static but the same error still appears.

    Please, help i am stuck with this problem.
     
  8. eriQue

    eriQue

    Unity Technologies

    Joined:
    May 25, 2010
    Posts:
    595
    GameObjectName1 is the name of the GameObject, not the function. I.e. "Main Camera" or something like that. Your function name should match MethodName1 instead.
     
  9. HazeTI

    HazeTI

    Joined:
    Jan 12, 2012
    Posts:
    83
    To try and resurrect this thread can anyone tell me what package I need to import in Java in order to be able to use UnityPlayer?
     
  10. HazeTI

    HazeTI

    Joined:
    Jan 12, 2012
    Posts:
    83
    Matti-Jokipii likes this.
  11. tato469

    tato469

    Joined:
    Jun 22, 2012
    Posts:
    16
    Hello, the second param in the fuction: UnityPlayer.UnitySendMessage("GameObjectName1", "MethodName1", "Message to send") is the method in javascript code in Unity? I know the part of Android and I know JavaScript programming but I'm very noob with Unity :S

    for example If in unity i have:
    PHP:
    function readMessage(message){
        
    guiText.text message;
        }
    Should I call sendMessage in this way?
    PHP:
     UnityPlayer.UnitySendMessage("guiText""readMessage""Hello World!")
    Could u put me some example please? Thanks for All!
     
    Last edited: Jul 5, 2012
  12. Kantharr

    Kantharr

    Joined:
    Aug 14, 2012
    Posts:
    18
    Hey, could anyone tell me how to properly use UnitySendMessage? I am trying to get a string of what callback function the android phone called so I can do certain actions in each one. Here are some codes that I have:

    AndroidActivity.java:
    Code (csharp):
    1. package com.companytest.companygame;
    2.  
    3. import com.unity3d.player.UnityPlayerActivity;
    4. import com.unity3d.player.UnityPlayer;
    5. import android.content.res.Configuration;
    6. import android.os.Bundle;
    7. import android.view.KeyEvent;
    8.  
    9. public class AndroidActivity extends UnityPlayerActivity
    10. {
    11.     private UnityPlayer mUnityPlayer;
    12.    
    13.     // UnityPlayer.init() should be called before attaching the view to a layout.
    14.     // UnityPlayer.quit() should be the last thing called; it will terminate the process and not return.
    15.     @Override
    16.     protected void onCreate (Bundle savedInstanceState)
    17.     {
    18.         mUnityPlayer.UnitySendMessage("TestObject", "sendEventStatus", "onCreate");
    19.         super.onCreate(savedInstanceState);
    20.     }
    21.    
    22.     @Override
    23.     protected void onDestroy ()
    24.     {
    25.         mUnityPlayer.UnitySendMessage("TestObject", "sendEventStatus", "onDestroy");
    26.         super.onDestroy();
    27.         mUnityPlayer.quit();
    28.     }
    29.  
    30.     // onPause()/onResume() must be sent to UnityPlayer to enable pause and resource recreation on resume.
    31.     @Override
    32.     protected void onPause()
    33.     {
    34.         mUnityPlayer.UnitySendMessage("TestObject", "sendEventStatus", "onPause");
    35.         super.onPause();
    36.         mUnityPlayer.pause();
    37.     }
    38.    
    39.     @Override
    40.     protected void onResume()
    41.     {
    42.         mUnityPlayer.UnitySendMessage("TestObject", "sendEventStatus", "onResume");
    43.         super.onResume();
    44.         mUnityPlayer.resume();
    45.     }
    46.    
    47.     @Override
    48.     public void onConfigurationChanged(Configuration newConfig)
    49.     {
    50.         mUnityPlayer.UnitySendMessage("TestObject", "sendEventStatus", "onConfigChanged");
    51.         super.onConfigurationChanged(newConfig);
    52.         mUnityPlayer.configurationChanged(newConfig);
    53.     }
    54.    
    55.     @Override
    56.     public void onWindowFocusChanged(boolean hasFocus)
    57.     {
    58.         mUnityPlayer.UnitySendMessage("TestObject", "sendEventStatus", "onFocusChanged");
    59.         super.onWindowFocusChanged(hasFocus);
    60.         mUnityPlayer.windowFocusChanged(hasFocus);
    61.     }
    62.  
    63.     // Pass any keys not handled by (unfocused) views straight to UnityPlayer
    64.    
    65.     @Override
    66.     public boolean onKeyDown(int keyCode, KeyEvent event)
    67.     {
    68.         mUnityPlayer.UnitySendMessage("TestObject", "sendEventStatus", "onKeyDown");
    69.         return mUnityPlayer.onKeyDown(keyCode, event);
    70.     }
    71.    
    72.     @Override
    73.     public boolean onKeyUp(int keyCode, KeyEvent event)
    74.     {
    75.         mUnityPlayer.UnitySendMessage("TestObject", "sendEventStatus", "onKeyUp");
    76.         return mUnityPlayer.onKeyUp(keyCode, event);
    77.     }
    78. }
    79.  
    AndroidEventHandler.cs:
    Code (csharp):
    1.     void sendEventStatus(string eventStatus)
    2.     {
    3.         switch(eventStatus)
    4.         {
    5.             case "onResume":
    6.             {
    7.                 Debug.Log("onResume Received");
    8.             }break;
    9.         default:break;
    10.         }
    11.     }
    What I'm trying to do on my code is to try to see if waking the phone up from standby mode would send an onResume message. I have tried but it didn't work so either I am getting the wrong message or I need to change my sendEventStatus function.
     
    DmitryAVasin and KorHakcer like this.
  13. eriQue

    eriQue

    Unity Technologies

    Joined:
    May 25, 2010
    Posts:
    595
    Calling UnityPlayer.UnitySendMessage() in onCreate will have no affect since the Unity runtime isn't initialized nor running at that point.
    In general you need to make sure Unity is running when calling UnitySendMessage(), since if it isn't those messages will just be dropped.
    Moreover, to get callbacks for onResume/onPause please use OnApplicationPause.
     
  14. Kantharr

    Kantharr

    Joined:
    Aug 14, 2012
    Posts:
    18
    Thank you for the info, and I have tried OnApplicationPause for both true and false but they haven't worked for me. The steps that I am trying to test this on is:

    1. Turn on App
    2. Click on input to bring up touch screen keyboard
    3. Press Power button to go into standby mode.
    4. Press Power button again to turn back on and unlock phone.

    I just want to know if any messages are being called when the phone enters or exits standby mode.
     
  15. eriQue

    eriQue

    Unity Technologies

    Joined:
    May 25, 2010
    Posts:
    595
    You are saying you don't get any calls to OnApplicationPause (or OnApplicationFocus)? If so, then that sounds like a bug. If you can report the bug and attach your project as repro, then that would be great. Please state information such as what device you are using, it's Android OS version etc. Thanks.
     
  16. Kantharr

    Kantharr

    Joined:
    Aug 14, 2012
    Posts:
    18
    Yeah I haven't been getting any calls on any of those two functions with any of our android devices. I will go report the bug then, thank you.
     
  17. javOnet

    javOnet

    Joined:
    Mar 28, 2013
    Posts:
    1
    Our soution does just this without any additional effort, you don't need to bother about anything, you just copy a file and do your work. Try it for free, check us out at our website!
     
  18. hirenkacha

    hirenkacha

    Joined:
    Apr 4, 2012
    Posts:
    10
    Code (csharp):
    1. private AndroidJavaClass cls_Fb;
    2.    
    3.     public void Share()
    4.     {
    5.         cls_Fb = new AndroidJavaClass("com.example.sample.MainActivity") ;
    6.        
    7.        
    8.            
    9.         using(AndroidJavaClass cls_UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    10.         {
    11.            
    12.             using(AndroidJavaObject obj_Activity = cls_UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
    13.             {
    14.                
    15.                 cls_Fb.CallStatic("loadLeaderboardFromJni","hi");
    16.             }
    17.         }
    actually I want to initialize the instance to this in onCreate (). But its not getting initialized.
     
    Last edited: Apr 30, 2013
  19. evandropaulino

    evandropaulino

    Joined:
    Aug 7, 2012
    Posts:
    21
    Hi people.

    I create a plugin that helps with interaction between Java and C#. You can listen for system messages with broadcast receivers, and pick images from gallery using StartActivityForResult/OnActivityResult methods.

    This is the link for Asset Store: Android System for Unity.

    Let me know if it attend your needs.

    Thanks.
     
  20. jvil

    jvil

    Joined:
    Jul 13, 2012
    Posts:
    263
    I really hate all these opportunists trying to sell their product instead of post a solution to this problem, now I know what plugins I don't have to buy.

    This is not for sell your product, and we all know there is an asset store with plugins to buy.
     
    kayy likes this.
  21. evandropaulino

    evandropaulino

    Joined:
    Aug 7, 2012
    Posts:
    21
    Well, instead of you research days and days, and taking more time to launch your game, why not cut time and use something another guy research and made available for you?
     
  22. jvil

    jvil

    Joined:
    Jul 13, 2012
    Posts:
    263
    Man, don't be a jerk.

    Do you feel fair If I'm going to charge $20 to solve the problem of this guy, or any post on this forum?

    Again, this is not the right place to sell your product. Go to the correct forum. This is for FREE help, nobody is posting their problems here expecting to pay for a solution, there are other forums for this.
     
    howlingcat likes this.
  23. maxizrin

    maxizrin

    Joined:
    Apr 13, 2015
    Posts:
    20
  24. kamran-bigdely

    kamran-bigdely

    Joined:
    Jun 19, 2014
    Posts:
    25
    Did you find out how? The link you posted is broken.
     
  25. jimmya

    jimmya

    Joined:
    Nov 15, 2016
    Posts:
    793
  26. kamran-bigdely

    kamran-bigdely

    Joined:
    Jun 19, 2014
    Posts:
    25
    In order to use UnityPlayer in your java plugin (assuming you don't want to export unity project and don't want to extend UnityPlayerActivity), you should:
    1) Copy the following file into 'libs' folder of your android plugin's project:

    C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes \classes.jar

    Note
    : I had to rename it to something else (unity_classes.jar) to prevent name conflict between this and the classes.jar file that Unity makes out of the plugin.

    2) In 'build.gradle' of your module, add the following in the 'dependencies ' section:

    provided files('libs/jars/unity_classes.jar')

    Note: make sure it's 'provided' and not 'compile' because Unity adds this library to your final build again and the project ends up having two copies of that UnityPlayer jar file and complains by saying ''Unable to convert classes into dex format." (you can see my struggle here).

    3) Add the following import to your java code:

    import com.unity3d.player.UnityPlayer;

    4) Add your method call:
    UnityPlayer.UnitySendMessage("Manager", // gameObject name
    "PluginCallback", // this is a callback in C#
    "Hello from android plugin"); // msg
    5) Build your module and then copy the generated .aar file into Assets\Plugins\Android folder of my Unity project.

    I assume you have a gameObject (not your script/class name!) named "Manager" in your scene (obviously this is an arbitrary name). Your C# callback should be written in a script that is attached to "Manager" gameObject and have the following signature:

    Code (CSharp):
    1. public void PluginCallback(string msg)
    2. {
    3.     // Do something like:
    4.     GUI.Label(new Rect(100, 400, 100, 100), msg);
    5.  
    6. }
     
    Last edited: Jun 12, 2017
    ShantiB95, eXistng, Klarzahs and 4 others like this.
  27. Mike_17

    Mike_17

    Joined:
    Jan 30, 2017
    Posts:
    10
    This last message needs to be in Unity documentation. Seriously, I've spent DAYS trying to find THIS !
     
  28. kamran-bigdely

    kamran-bigdely

    Joined:
    Jun 19, 2014
    Posts:
    25
    A general and flexible way to call your Unity C# code from your android java plugin is using AndroidJavaProxy. There are a good examples here and here.
     
    Last edited: Mar 8, 2019
    hafizsaadcb, Thaina and bekici like this.
  29. hafizsaadcb

    hafizsaadcb

    Joined:
    Jan 15, 2024
    Posts:
    11
    It significantly saved me time, even though I couldn't utilize UnitySendMessage. However, AndroidJavaProxy proved to be an excellent solution for facilitating communication between the Unity 3D App and the Android App.