How to make Android Plugin for Unity: Take photo from camera and gallery

Capture and Share in-game moment is a very important feature of mobile game nowadays. During the making of Kingdom Reborn — Art of War and Penguin Fight we write a simple plug in for Unity which can take photo from camera and gallery to use in game.

Write the plugin with Android Studio

Create a project in Android Studio

Create Project in Android Studio

Create a project with no activity, click next few times and you are ready to code

Add Unity’s Library to your Project

If your plugin wants to communicate with Unity, you have to add the Classes.jar file in

<Unity-install-directory>\Editor\Data\
PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

to your project

This library contains the com.unity3d.player.UnityPlayer class which will be used in our plugin.

Copy Classes.jar to

<Your-Project-Dir>/app/libs 

then add it as Library as shown below:

Add Unity’s library

The UnitySendMessage function

The Java class com.unity3d.player.UnityPlayer has a static method UnitySendMessage which can be used in Java to pass data to script code.

This then calls back to the Unity code to deliver the message to the object in Unity’s Scene. We’ll name it KoiGameObject.

Setup the KoiGameObject

KoiGameObject has a Script attached to it: KoinCallBack

public class KoiCallBack : MonoBehaviour {
//Plugin calls this function by UnitySendMessage to KoinGameObject
void KoiCamera_PickDone(string param)
{
Koi.getInstance().handleImage(param);
}
//Plugin calls this function by UnitySendMessage to KoinGameObject
void KoiGallery_PickDone(string param)
{
Koi.getInstance().handleImage(param);
}
}

The Koi Java Class

The plugin code is pretty straight forward, we have Koi class which can launch two Android activites: Camera and Gallery.

/**
* Open phone’s gallery
*/
public void launchGallery(Context context){
launchAndroidActivity(context,KoiGalleryActivity.class );
}

/**
* Start phone’s camera
*/
public void launchCamera(Context context){
launchAndroidActivity(context,KoiCameraActivity.class );
}

The Koi has sendMessageToKoiObject which is used to send message to a GameObject (named “KoiGameObject”) in Unity’s Scene

It also has setPluginData and getPluginData to store/return image data

public static void sendMessageToKoiObject(String method, 
String message)
{
UnityPlayer.UnitySendMessage(Koi.KOI_GAMEOBJECT, method, message);
}
/**
* Same as sendMessageToKoiObject, but use JSONArray as message
*/
public static void sendMessageToKoiObject(String method,
JSONArray parameters)
{
sendMessageToKoiObject(method, parameters.toString());

}
/**
* Return the result to Unity
*/
public byte[] getPluginData(){
return pluginData;
}

/**
* Set the data result to return later
*/
public void setPluginData(byte[] data){
pluginData = data;
}

In KoiGalleryActivity class, after the user choose an image, we set image data to KoiPlugin to use later, then send message to KoiGameObject in Unity:

//The method name of script attached to KoiGameObject
public static final String KOI_GALLERY_CALL_BACK = "KoiGallery_PickDone";
Bitmap bm;//the image which is chosen by user
….
JSONObject jso = new JSONObject();
try {
jso.put(“width”, bm.getWidth());
jso.put(“height”, bm.getHeight());
} catch (JSONException e) {
e.printStackTrace();
}
JSONArray jsa = new JSONArray();
jsa.put(jso);
Koi.instance.setPluginData(byteArray);
Koi.sendMessageToKoiObject(KOI_GALLERY_CALL_BACK, jsa);

The KoiGallery_PickDone will be called in Unity, with the width and height of image passed as its parameters.

Build and Use the Plugin

Build the project using Gradle

You need to export you project as jar file in order to use in Unity.

Change the content of build.gradle as shown below

apply plugin: 'com.android.library'

android {
compileSdkVersion 24
buildToolsVersion "24.0.1"

defaultConfig {

minSdkVersion 15
targetSdkVersion 24

}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:24.1.1'
compile files('libs/classes.jar')
}

//task to delete the old jar
task cleanJar(type: Delete) {
delete 'release/KoiPlugin.jar'
}

//task to export contents as jar
task exportJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
rename('classes.jar', 'KoiPlugin.jar')
}

exportJar.dependsOn(cleanJar, build)

ReSync the project and you will have a new exportJar task in Gradle:

Create ExportJar task

Execute the task and you will have KoiPlugin.jar in

<Your-Project-Dir>/app/release

Add KoiPlugin into Unity

Copy KoiPlugin.jar into

Assets\Plugins\Android

Because we have two Android activities for Gallery and Camera, we also need to describe them in Assets\Plugins\Android\AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.grepgame.test.koi">
<uses-sdk android:minSdkVersion="9"/>
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="unityplayer.UnityActivity"
android:value="true" />
</activity>
<activity android:name=
"com.grepgame.android.plugin.grplugin.KoiGalleryActivity"/>
<activity android:name=
"com.grepgame.android.plugin.grplugin.KoiCameraActivity"/>
</application>
<uses-permission android:name=
"android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>

(If your Unity project does not have Android folder and AndroidManifest.xml, just create them)

Use KoiPlugin in Unity

Create an emty GameObject in your Scene, name it KoiGameObject. From this scene, use the following code to open the Gallery

//instance of Koi plugin
AndroidJavaObject androidObject;
//Reference to Unity Player
AndroidJavaObject unityObject;


AndroidJavaClass unityClass =
new AndroidJavaClass(“com.unity3d.player.UnityPlayer”);
unityObject = 
unityClass.GetStatic<AndroidJavaObject>(“currentActivity”);
  
AndroidJavaClass androidClass =
new AndroidJavaClass
(“com.grepgame.android.plugin.grplugin.Koi”);
androidObject = 
androidClass.GetStatic<AndroidJavaObject>(“instance”);
}
public void openGallery()
{
//call the launchGallery method of Koi Plugin
androidObject.Call(“launchGallery”, unityObject);
}

The instance of Koi Java class in Plugin will be created. It then launch the Gallery for user to pick, if an image is picked, the plugin will callback to KoiGallery_PickDone.

At this point, we know that the Plugin is holding the actual image data, we can get this data by calling

androidObject.Call<byte[]>(“getPluginData”)

Source code

Sorry for the long post, all source code of this post can be found at: