Calling an android method from Unity3D with a JAR plugin

| | August 4, 2015

I am developing a game with Unity only for Android platform and I am requiring to share content of my game through an intent so I have implemented a JAR plugin according to several tutorials with this code:

package a.b.c;

import android.content.Intent;
import android.os.Bundle;

import com.unity3d.player.UnityPlayerActivity;

public class UnityBridge extends UnityPlayerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public void callShareIntent() {
        Intent shareIntent = new Intent (Intent.ACTION_VIEW);
        startActivity(shareIntent);
    }
}

The JAR is located at Assets/Plugins/Android with an AndroidManifest file which override the file created by unity, this is its code:

<?xml version="1.0" encoding="utf-8"?>
<manifest android:theme="@*android:style/Theme.NoTitleBar" android:versionCode="1" android:versionName="1.0" android:installLocation="auto" package="a.b.c"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" />
    <application android:label="@string/app_name" android:icon="@drawable/app_icon" android:debuggable="false">
        <activity android:label="@string/app_name" android:name="com.unity3d.player.UnityPlayerNativeActivity" android:launchMode="singleTask" android:screenOrientation="portrait" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|fontScale">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
            <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
        </activity>
        <activity android:name=".UnityBridge"></activity>
    </application>
    <uses-feature android:glEsVersion="0x20000" />
</manifest>

I just copied the manifest created by Unity and added this line:

<activity android:name=".UnityBridge"></activity>

… as you can see.

In the other hand, I have created a C# file in order to launch the share method of the plugin, this is its code:

using UnityEngine;
using System.Collections;

public class BotonCompartir : MonoBehaviour {

    AndroidJavaClass androidClass;

    // Use this for initialization
    void Start () {
        if (Application.platform == RuntimePlatform.Android) {
            AndroidJNI.AttachCurrentThread ();
            androidClass = new AndroidJavaClass ("a.b.c.UnityBridge");
        }
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetMouseButtonDown (0) && Application.platform == RuntimePlatform.Android) {
            androidClass.Call("callShareIntent");
        }
    }
}

… and I have attached it to a gameobject.

When I deploy the apk to an android device nothing happens, so What am I doing wrong? Any other suggestion?

Thank you very much

One Response to “Calling an android method from Unity3D with a JAR plugin”

  1. Since you’re overriding the Main UnityPlayerActivity your AndroidManifest should look like :

    <?xml version="1.0" encoding="utf-8"?>
        <manifest android:theme="@*android:style/Theme.NoTitleBar" android:versionCode="1" android:versionName="1.0" android:installLocation="auto" package="a.b.c" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" />
    <application android:label="@string/app_name" android:icon="@drawable/app_icon" android:debuggable="false">
        <activity android:label="@string/app_name" android:name=".UnityBridge" android:launchMode="singleTask" android:screenOrientation="portrait" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|fontScale">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-feature android:glEsVersion="0x20000" />
    </manifest>
    

    And to successfully call “callSharedIntent” method from Unity you should get the instance of the Activity first and not only its Class as this is not a static call to a static method. Try this :

    package a.b.c;
    
    import android.content.Intent;
    import android.os.Bundle;
    
    import com.unity3d.player.UnityPlayerActivity;
    
    public class UnityBridge extends UnityPlayerActivity {
    
    public static Context context;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
    }
    
    public void callShareIntent() {
        Intent shareIntent = new Intent (Intent.ACTION_VIEW);
        startActivity(shareIntent);
    }
    }
    

    And from Unity :

    using UnityEngine;
    using System.Collections;
    
    public class BotonCompartir : MonoBehaviour {
       #if !UNITY_EDITOR && UNITY_ANDROID
       AndroidJavaClass androidClass;
       AndroidJavaObject androidActivity;
    
    // Use this for initialization
    void Start () {
            AndroidJNI.AttachCurrentThread ();
            androidClass = new AndroidJavaClass ("a.b.c.UnityBridge");
            androidActivity = androidClass.GetStatic<AndroidJavaObject>("context");
    }
    
    // Update is called once per frame
    void Update () {
        if (Input.GetMouseButtonDown (0)) {
            androidActivity.Call("callShareIntent");
        }
    }
    
    void OnDestroy(){
         if (androidClass !=null) androidClass.Dispose();
         if (androidActivity !=null) androidActivity.Dispose();
    }
    #endif
    }
    

Leave a Reply