Create An Android Plugin For Unity Using Android Studio

This is one post which I wanted to write badly, not because it is difficult but because it is so useful to know how to add the core Android features which Unity doesn't have built in. In this post we will be Creating a Share Your Game / App Plugin using Intents. Of course, this is very simple. But hey, it's pretty useful to let users have the luxury of sharing your game with just a click.

We will write an Android Activity which will let the users share some text / description about your game, for instance, the Play Store link to your game. Isn't that super useful? You bet it is. Let's get started.

Exporting the jar from the Android Studio for Unity

Watch the video below to export the jar or simply follow the steps listed beneath the video




This step used to be straight forward using Eclipse IDE. However, there are some modifications to be done in the Gradle file in terms of creating new tasks so as to be able to export the jar file. Some of them tend to export the jar by adding a Module. However, TGC will show you a very simple way to achieve this by adding task to the Gradle which will let you build the jar using Android Studio.

1. Create a new Android Studio project


Fig 1: Android Plugin For Unity using Android Studio - New Android Studio Project

Create a New Android Studio Project and specify the details as in Fig 1. Press Next and it should ask you to select the Form Factors the app will run on. Keep the default settings and press Next. Now, it will ask you to add an Activity. Keep it to default (Blank Activity) as well and press Next. We do not want to customize the Activity and we press Finish. Once you click on Finish, it will take some time to load the new Project.

2. Add External Jar file as Library in Android Studio

Until it loads, navigate to the following location C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\androidplayer\release\bin and copy the Classes.jar file.

The Android Studio should have loaded the new project by now. Switch to the Project view and you should have something like the screenshot below

Fig 2: Android Plugin For Unity using Android Studio - Project View


Paste the copied Classes.jar file into the libs folder under app. Right click on the the Classes.jar file added and select Add as Library for us to use import the UnityPlayerActivity class and other contents of this jar.
Many of them don't know how to add an external jar as library in the Android Studio, well, maybe you can show them how it's done now that you know it.

Fig 3: Android Plugin For Unity using Android Studio - Add external jar as Library 
If you have correctly followed the steps, then you should have the build.gradle file under the app folder as below

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.thegamecontriver.sharetext"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

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


The 25th line being the one which is added as a result of adding the jar as Library.

3. Write code to Share text using Intents

Paste the below code inside the MainActivity.java file

package com.thegamecontriver.sharetext;

import android.content.Intent;
import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity {
    
    public void shareText(String subject, String body) {
        Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
        sharingIntent.setType("text/plain");
        sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
        sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);
        startActivity(Intent.createChooser(sharingIntent, "Share via"));
    }
    
}

The above class has a method shareText which takes in two string parameters subject and body, which as they say are the subject and body of the text that is to be shared.

4. Adding tasks to build.gradle file to export as jar

Change the contents of the build.gradle under the app folder to the content given below

//indicates that this is a library
apply plugin: 'com.android.library'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"
    sourceSets {
        main {
            //Path to your source code
            java {
                srcDir 'src/main/java'
            }
        }
    }

    defaultConfig {

        minSdkVersion 15
        targetSdkVersion 21

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

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

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

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

exportJar.dependsOn(deleteOldJar, build)

Resync the project and Rebuild it just to confirm that everything is all fine.
Once this is done, you should have a new task created in the Gradle tab which will be named as exportJar.

Fig 4: Android Plugin For Unity using Android Studio - Export JAR 
Double click on exportJar and it should start building a jar file. Once you see the BUILD SUCCESSFUL message in the Run window. Navigate to \AndroidStudioProjects\ShareText\app\release and you should have a AndroidPlugin.jar file built. That is the file we needed. That is the plugin which we will be using in our Unity project to Share text.

Copy this file and navigate to Unity and create a New Folder called Plugins under the Assets folder of you project. Under the Plugins folder, create another folder named Android. Paste the AndroidPlugin.jar file under this folder.
Create a new xml file named AndroidManifest.xml in the same Android folder and paste the following content

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.thegamecontriver.sharetext"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="9" />
    <application android:label="@string/app_name">
        <activity android:name=".MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Save the file and move to Unity. Now, you are ready to use this Share Feature. You just need to call it from your script.

Use the JAR in Unity 

Create a new C# Script named ShareApp and add the following code to it

using UnityEngine;
using System.Collections;

public class ShareApp : MonoBehaviour {

 string subject = "WORD-O-MAZE";
 string body = "PLAY THIS AWESOME. GET IT ON THE PLAYSTORE";

 public void callShareApp(){
  AndroidJavaClass unity = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
  AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject> ("currentActivity");
  currentActivity.Call ("shareText", subject, body);
 }
}

Save the script and move back to unity. Attach this script to the Main Camera.
Create a new Button and add an On Click event to this button. Drag and drop the Main Camera under the GameObject field and select ShareApp->callShareApp function in the function to be called field.

Save the scene and now this little app is ready to be tested. However, there is one last change to be made. The Bundle Identifier should be changed to the package name that we used while creating the Android plugin, i.e., com.thegamecontriver.shareapp

Fig 5: Android Plugin For Unity using Android Studio - Bundle Identifier
Once you build the app and test it. On clicking the button you should get something like the one that is shown screenshot below

Fig 5: Android Plugin For Unity using Android Studio - Share App
Hope this post will be of some use to you guys.

Also, check out
How To Add Custom Duration Vibration

See you around.


Share on Google+

About Sujit Horakeri

Sujit Horakeri is a game freak just like any other next door guy you would come across. He is a Web Developer by Profession, Game Developer by Choice.
Connect with him on:
    Blogger
    Facebook

74 comments:

  1. Copying file failed (2) ??????????????

    ReplyDelete
    Replies
    1. pls mention which file failed to copy?

      Delete
  2. I have google In-App sample project running excellent in the android I want to make its plugin for unity.
    can u help me in this regards

    ReplyDelete
  3. hi, i have a problem with the Androidmanifest.xml file because i already have one for the facebook plugin , so i was wondering if there is a way to include your file

    ReplyDelete
    Replies
    1. These might help you
      http://forum.unity3d.com/threads/android-plugin-multiple-android-activity-problems.149089/#post-1059268

      http://answers.unity3d.com/questions/202424/multiple-plugins-on-android.html

      Delete
  4. thanks,this post is very useful for me
    but i think there is a mistake here:

    task deleteOldJar(type: Delete) {
    delete 'build/libs/AndroidPlugin.jar'
    //delete 'release/AndroidPlugin.jar'

    }

    ReplyDelete
    Replies
    1. You are right! Post updated. Thanks for the correction :) Cheers!

      Delete
  5. I'm having trouble with this, I don't get any /release directory, and the build/intermediates/bundles directory is also never created when I build. When I run "exportJar" it says "Build successful" but again, no "Release" directory is created anywhere, and I don't see a jar at all.

    Do I need to set something on my module to make sure that it is built? I'm not sure what I am doing wrong, I followed your directions very specifically.

    ReplyDelete
    Replies
    1. Figured it out, my build.gradle still had "com.android.application" at the top instead of "com.android.library", fixed that and now it is working.

      Delete
    2. haha had the same issue, thanks man

      Delete
    3. Could you resolve this? I have the same problem.. I change the first line "apply plugin: 'com.android.application'" to "apply plugin: 'com.android.library'" but nothing change.

      Delete
    4. This is the error message

      Error:Library projects cannot set applicationId. applicationId is set to 'com.nomada.book' in default config.

      Delete
    5. Remove applicationId lines in defaultConfig

      Delete
    6. in the latest android studio, I followed everything but there's still no release folder... Please help

      Delete
  6. I have followed these instructions in detail. Running Android Studio 1.1 on OS X. But when running on the Android device, the app throws the following error:

    AndroidJavaException: java.lang.NoSuchMethodError: no method with name='shareText'

    Please help
    Andres

    ReplyDelete
    Replies
    1. OK, I'm getting mad trying to solve this..
      Seems like this is related with the activity name in AndroidManifest. If I follow the instructions here and use the following:
      in a sandbox project, the JAVA call is executed. However, in my project, the activity is called: . If I try to change mine to ".MainActivity" my application crashes on loading..

      What I'm doing wrong here?

      Delete
    2. SOLVED! Take a look at this post: http://forum.unity3d.com/threads/android-plugin-multiple-android-activity-problems.149089/

      Delete
    3. This happens because the class MainActivity that extends UnityPlayerActivity is not instantiated as an app launcher.

      Make sure that in android manifest file, MainActivity is the app launcher, and it would work as must.

      Delete
  7. sir can you make a tutorial native plugin for take screenshot and save it to gallery in unity3d?

    ReplyDelete
  8. thanks a lot for this excellent guide! I'm currently building a plugin wich uses resources, but everytime a resource is called, the unity-app crashes. At first, i noticed the resources weren't in the .jar, so i added them via "resources { srcDir 'src/main/res' }" in the app folders build.gradle. However the app still crashes. It looks like the resources aren't found by the app. Do you have any ideas?

    ReplyDelete
    Replies
    1. Done!

      sourceSets {
      main {
      resources.srcDirs = ['src']
      }
      }

      Delete
    2. Great post. Thanks.... I have doubts.. How can i use two of my plugins in the same game in unity? I means both same time. I can use them one at a time but not both. How can i do both same time? Pls help. Sorry for my bad english

      Delete
    3. This comment has been removed by the author.

      Delete
  9. gostaria de que me ajudasse a salvar jogos do unity em android segue meus erros https://www.youtube.com/watch?v=mxkx-0o78Ek

    ReplyDelete
  10. This was a great help! Thanks for sharing! :)

    ReplyDelete
  11. Great post, but I having a problem when Im running the unity generated apk.

    java.lang.NoClassDefFoundError: Failed resolution of: Lcom/wizard3d/unityplugin01/R$layout;

    Any ideas?

    ReplyDelete
  12. I followed your tutorial and my projects build with out any errors. But i could not found export.jar in app: build/ any suggestions? I m using Android studio 2.0

    ReplyDelete
  13. Thanks for sharing,but I come across some problems.
    I create my application in android-studio,which import external libraries.Now I need to import the existed project from android-studio to Unity,but I don't know how to place my 'libs' and 'res' folder in Unity.
    I wander if you can offer some advice to me,thanks a lot!

    ReplyDelete
  14. Thank you very much for the article. I couldn't find this kind of article other than this.
    I have two questions, I hope you don't mind to answer if you know about this.
    First, do you think we can make plugin for android background services? I am trying to figure out how, but still don't know. Second, in the step 4 above (4. Adding tasks to build.gradle file to export as jar), you wrote "sourceSet". Is it optional or we have to add it? I wonder what directory I should write because I am using mac.

    Thank you very much for your time

    ReplyDelete
  15. Nice article, got a good idea. I could able to create jar from android studio. struck at manifest file & calling from unity.. ant tips

    ReplyDelete
  16. I would like to ask what is the usage of new AndroidManifest.xml.
    What is the different between the original one and new one?
    I am new on Unity-Android, thanks in advance.

    ReplyDelete
  17. Everything works but there is a issue in sharing!
    it says. Play this awesome game. get it on google play.
    from where does this thing is getting set

    ReplyDelete
    Replies
    1. that's an insane question! I am really sorry! I got that working :D

      Delete
  18. I installed the latest version of unity and I do not have the \release folder path in
    C:\Program Files\Unity\Editor\Data\PlaybackEngines\androidplayer
    There are 4 classes.jar files in there :/ I can't check them all up.
    Also I got an error on the MainActivity.java on the first line of code:
    (package com.thegamecontriver.sharetext;)
    it says:
    "Package name 'com.thegamecontriver.sharetext' does not correspond to the file path 'com.example.user.gctest2' less... (Ctrl+F1)
    Detects package statements that do not correspond to the project directory structure and reports classes without package statements. "

    ReplyDelete
  19. I followed your tutorial and many others in the same subject.Spend several sleepless nights in troubleshooting.
    However, everything ends up in following error:

    Exception: JNI: Init'd AndroidJavaClass with null ptr!
    UnityEngine.AndroidJavaClass..ctor (IntPtr jclass) (at C:/buildslave/unity/build/Runtime/Export/AndroidJavaImpl.cs:539)
    UnityEngine.AndroidJavaObject.get_JavaLangClass () (at C:/buildslave/unity/build/Runtime/Export/AndroidJavaImpl.cs:517)
    UnityEngine.AndroidJavaObject.FindClass (System.String name) (at C:/buildslave/unity/build/Runtime/Export/AndroidJavaImpl.cs:508)
    UnityEngine.AndroidJavaClass._AndroidJavaClass (System.String className) (at C:/buildslave/unity/build/Runtime/Export/AndroidJavaImpl.cs:528)
    UnityEngine.AndroidJavaClass..ctor (System.String className) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/AndroidJava.gen.cs:93)
    ShareApp.callShareApp () (at Assets/ShareApp.cs:10)...................

    .................................................................. etc...


    Any lights please...

    I can see that you stoped responding to this tread anymore.

    But I will wait for a solution how ever long it takes from you too...

    ReplyDelete
    Replies
    1. well, the error says it can't create a class AndroidJavaClass.
      If you are not running this on an android device it is only logical to happen. Try deploying to an Android device and tell us if everything is ok.

      Delete
  20. Just got this working - thanks immensely for this.

    Update Notes -
    1) Newer versions of Android Studio have a slightly different structure for the gradle tab - I found exportJar under appname/appname/tasks/other/exportJar
    2) Unity has moved the classes.jar file slightly, on mac I found mine under :/Applications/Unity_5_3/PlaybackEngines/AndroidPlayer/Variations/mono/Release/Classes

    Also I did a quick modification of the gradle tasks to deploy directly into unity :
    //task to delete the old jar
    task deleteOldJar(type: Delete) {
    delete '../../Assets/Plugins/Android/PomaBridge.jar'
    }

    //task to export contents as jar
    task exportJar(type: Copy) {
    from('build/intermediates/bundles/release/')
    into('../../Assets/Plugins/Android/')
    include('classes.jar')
    ///Rename the jar
    rename('classes.jar', 'PomaBridge.jar')
    }

    ReplyDelete
    Replies
    1. can you please explain the steps more clearly because i miss some points, please it's important for my grad project

      Delete
  21. I'm not sure I'm doing right or not, cause I just bump in unity just 2 days.
    For me, for the android activity code,
    I put onCreate method, it works well
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Log.i(TAG, "onCreate is called");
    }

    ReplyDelete
  22. That was a great tutorial! It worked just fine for me, thank you very much!
    I was windering, if I make a plugin that uses some functions from a different .jar/library do I need to do something else or just export my jar and use it in unity as you showed us ?

    ReplyDelete
    Replies
    1. Well, I just tried it out and it seems that no further action is actually needed

      Delete
  23. Thanks for the awesome tutorial. I was wondering if you had some tips on how we can test this Library project from within Android Studio.

    Things I've tried:
    * Created a new 'Phone & Tablet' Module
    * Added the Extension Module as a dependancy
    * Extended App MainActivity, from Extension MainActivity
    * Call shareText() from App Module's Main Activity

    The app compiles, and launches on the device, but immediately crashes. Any ideas?

    ReplyDelete
  24. Hello, is it possible to make an android native plugin for unity3d, in which some files will be downloaded from server in background, I mean, to make it run in parallel thread and avoid freezes. Tried everything I could think of in Unity, but there is only one main thread and downloading freezes the app anyway.

    ReplyDelete
  25. Hey, is there any way to use a plugin created from your tutorial together with another plugin ? I've tried everything but they don't work!
    (I want to use it together with Cardboard)

    ReplyDelete
  26. Hello,
    Thanks for the effort. However the app crashes right after click on the icon. Unity complains about missing unity activity during the build. Any ideas?
    Thank you!

    ReplyDelete
  27. Hello @Sujit Horakeri
    Thanks for the effort.This's good,and it works.However,if i add a layout(eg:layout/activity_main.xml) in Android studio project,it crash when i run apk in my phone,version:android studio + Unity4.6.3/Unity4.6.8.But android studio + Unity5.2.4f1 is alright.Any ideas?
    Thank you!

    ReplyDelete
  28. Thanks for this tuto, is very useful :)

    ReplyDelete
  29. YOU ARE MY HERO!!! thank you so much for this post. works like a charm!

    ReplyDelete
  30. awesome. works like a charm!
    unity 5.3 64bit classes.jar directory: Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

    ReplyDelete
    Replies
    1. Is it located in the same directory in unity 32bit?

      Delete
  31. Can you please tell me about app indexing plugin . how to implement it ?

    ReplyDelete
  32. there is a file under the src/test/java/ExampleUnitTest.java. I ma getting errors while compliling. The errors are following.
    Error:(3, 17) error: package org.junit does not exist
    Error:(11, 6) error: cannot find symbol class Test
    Error:(13, 9) error: cannot find symbol method assertEquals(int,int)

    ReplyDelete
  33. Thank you very much for the article, but the article did not explain how to add resources, I will res folder are copied to the Android catalog, or when the package will be reported this error
    Error building Player: CommandInvokationFailure: Failed to re-package resources See the Console for details..

    ReplyDelete
  34. Hello, for some reason the AndroidPlugin.jar wasn't build after executing the exportJar task (it ran without errors). I don't see any file in that name, even after following all your steps. any ideas plz?

    ReplyDelete
  35. Unable to convert classes into dex format. See the Console for details.

    Giving me this error in unity.

    ReplyDelete
    Replies
    1. A main reason this error occurs is because you have multiple .jar files that contain the same function (a function with the same name at least) try removing the jar files you don't need from the plugins folder and try again.

      Delete
  36. Replies
    1. C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

      Delete
  37. I am getting no such method error. Please help

    ReplyDelete
  38. i need to integrate android UI into unity. please help me with that.

    ReplyDelete
  39. When I run and build the unity project this message appears "Unable to convert classes into dex format"

    ReplyDelete
  40. Not work. All in Studio and Unity compile well, but when start on phone - error "Unfortunatley, ShareApp has stopped". And default icon of app not unity, and splash screen of unity not shows - very strange... Android Studio 2.12. Unity 5.3.4F1, phone: 2 Core 512 RAM, Android 4.1.1.

    ReplyDelete
  41. I don't find anything which call "AndroidPlugin" when build successful.Why? in file build.gradle I apply plugin: 'com.android.library'
    Please show me where is AndroidPlugin?

    ReplyDelete
  42. iZombie Season 3 will portray Liv gulping down the brain of a dominatrix. Therefore, we can expect the upcoming installment to be more engaging than the previous ones. iZombie Season 3 Release Date

    ReplyDelete
  43. Any chance of an update to the latest Android Studio, 2.3.1?

    ReplyDelete