Building Android plugins with UnityPlayerActivity

May
30

Building Android plugins with UnityPlayerActivity

On this post I’m going to explain how to build your own Android plugins on Unity, generate a valid manifest and how to establish a bidirectional communication between your Android plugin and Unity.

Setup

First of all we need to prepare our environment and link the correct libraries on Eclipse (that’s the IDE I’m going to use on this post).

  1. Create an empty Android project on Eclipse and mark your project as libray. Right-button on your project / Properties / Android / Is Library. On this tutorial the name of package would be: com.codestalkers.plugin
  2. Copy the file classes.jar from your Unity installation folder (Unity\Editor\Data\PlaybackEngines\androidplayer\bin\classes.jar) to libs folder on your Eclipse project.
  3. Create a Main class on your Eclipse project. Right-button on your project / New / Class
  4. 
Prepare your code with UnityPlayerActivity on your Main class.
import com.unity3d.player.UnityPlayerActivity;
 
public class Main extends UnityPlayerActivity {
 
	public static Context mContext;
 
	@Override
	protected void onCreate(Bundle bundle)
	{
		super.onCreate(bundle);
		mContext = this;
	}
}

5. Export your Eclipse project to your Unity plugins folder: Assets/Plugins/Android/plugin.jar. Right-click on your project / Export… / JAR file

Modify your Android manifest

We need to create or modify the Android Manifest file on our Unity project. Create or modifiy the file Assets/Plugins/Android/AndroidManifest.xml. It would look like:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.codestalkers.plugin" android:versionName="1.0" android:versionCode="1"> 
  	<application android:icon="@drawable/app_icon" android:label="@string/app_name">
		<activity android:name="com.codestalkers.plugin.Main" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="landscape">
 			<meta-data android:name="android.app.lib_name" android:value="unity" />
  			<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
    		<intent-filter>
        		<action android:name="android.intent.action.MAIN" />
        		<category android:name="android.intent.category.LAUNCHER" />
      		</intent-filter>
    	</activity>
  	</application>
</manifest>

Communicate from Unity to Android

Call to non-static method
If we need to call a non-static method on our Android plugin, we need to retrieve the current Android activity. For this reason I saved as static the Android Context, we can easy get this value and call our non-static method. Let assume we need to call the following non-static method on our Java plugin:

public class Main extends UnityPlayerActivity {
 
	public static Context mContext;
 
	@Override
	protected void onCreate(Bundle bundle)
	{
		super.onCreate(bundle);
		mContext = this;
	}
 
	public void nonStaticMethod()
	{
		Log.d("TAG","Non-static method was called");
	}
}

The call to nonStaticMethod() method of our plugin from Unity side will be:

public void AndroidCallNonStatic()
{
	using (AndroidJavaClass javaClass = new AndroidJavaClass("com.codestalkers.plugin.Main"))
	{
		using (AndroidJavaObject activity = javaClass.GetStatic("mContext"))
		{
			activity.Call("nonStaticMethod");
		}
	}
}

Call to static method
If we’re going to call a static method we don’t need to get the current Android activity. For example, let’s assume we need to call the following static method:

import com.unity3d.player.UnityPlayerActivity;
import android.util.Log;
 
public class Main extends UnityPlayerActivity {
 
	@Override
	protected void onCreate(Bundle bundle)
	{
		super.onCreate(bundle);
	}
 
	public static void StaticMethod()
	{
		Log.d("TAG","Static method was called");
	}
}

The call to StaticMethod() method of our plugin from Unity side will be:

public void AndroidCallStatic()
{
	using (AndroidJavaClass javaClass = new AndroidJavaClass("com.codestalkers.plugin.Main"))
	{
		javaClass.CallStatic("StaticMethod");
	}
}

Communicate from Android to Unity
To communicate from our Android plugin to Unity we can pass data with the method UnitySendMessage of UnityPlayer.

import com.unity3d.player.UnityPlayerActivity;
import com.unity3d.player.UnityPlayer;

public class Main extends UnityPlayerActivity {

	@Override
	protected void onCreate(Bundle bundle)
	{
		super.onCreate(bundle);
		UnityPlayer.UnitySendMessage("GameManager", "HelloFromAndroid", "Hello!");
	}
}

There are 3 parameters on this function UnitySendMessage:

1. GameObject name (in the previous example, will send a message to object GameManager, we need to have an object on our scene with this name)
2. Function to call on this GameObject
3. Data to pass on this function

On Unity: create a GameObject called GameManager and add the following C# code on this GameObject:

using UnityEngine;

public class GameManager : MonoBehaviour
{
	public void HelloFromAndroid(string dataReceived)
	{
		Debug.Log("Received data from Android plugin: " + dataReceived);
	}
}

If we compile this project we will receive the messages on log console. Feel free to modify and adapt the code to your needs.

Thank you for reading! 🙂