Unity Android Plugins and `onActivityResult` callback

Taras Leskiv
Jan 7, 2017 · 3 min read
Image for post
Image for post

I am currently developing some native plugins for Asset Store and one of them is Android Goodies which allows you to do lots of Android native things.

One of the problems that I encountered was getting callback. This is needed for example when you want to pick an image and receive the receive the result.

static void dispatchPickImageIntent(Activity context, int requestCode) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
context.startActivityForResult(photoPickerIntent, requestCode);
}

And should look something like this:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
Log.d(Constants.LOG_TAG, ">>> onActivityResult: " + requestCode + " " + resultCode + " " + intent);
currentStatus = Status.IDLE;

switch (requestCode) {
case REQ_CODE_PICK_IMAGE:
PhotoPickerUtils.handlePhotoReceived(resultCode, intent, this);
break;
case REQ_CODE_TAKE_PHOTO_SMALL:
case REQ_CODE_TAKE_PHOTO_BIG:
TakePhotoUtils.handlePhotoReceived(requestCode, resultCode, intent, this);
break;
default:
finish();
break;
}

finish();
}

The problem is that Unity has its own `UnityPlayerActivity` which handles `onActivityResult` itself.

I found two possible ways of dealing with this problem:

  1. Extending with my activity and forcing developers to substitute the main activity with my custom activity in the manifest file. I quickly gave up this approach as only one plugin can override Unity activity and people sometimes use multiple Android plugins.
  2. Creating a custom activity that will be short-lived and its sole purpose would be to get created, do the job (user picks a photo from gallery e.g.), deliver the result (picked image) into and terminate itself. I chose this approach.

So the only thing the user has to do is to add my custom activity to file (the translucent theme is for activity not to have any visual effects):

<activity android:name="com.deadmosquitogames.AndroidGoodiesActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>

Now to implementation details:

Activity has static methods that are invoked from Unity (AndroidJavaObject API) to prepare it for certain tasks just before they are executed e.g. for picking photo:

public static void prepareToPickPhoto(OnTextureReceivedListener listener, int format, int maxSize) {
resetStatus();
currentActionReqCode = REQ_CODE_PICK_IMAGE;
PhotoPickerUtils.setImagePickSettings(listener, format, maxSize);
}

Then launch the activity from C# (some details are skipped for brevity):

public static void StartAndroidGoodiesActivity()
{
using (var clazz = AGUtils.ClassForName(AndroidGoodiesActivityClassSignature))
{
using (var intent = new AndroidIntent(AGUtils.Activity, clazz))
{
AGUtils.StartActivity(intent.AJO);
}
}
}

Of course, has its method overridden which handles the result, passes it over to unity side via AndroidJavaProxy API and is called to terminate the activity instance.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
Log.d(Constants.LOG_TAG, ">>> onActivityResult: " + requestCode + " " + resultCode + " " + intent);
currentStatus = Status.IDLE;

switch (requestCode) {
case REQ_CODE_PICK_IMAGE:
PhotoPickerUtils.handlePhotoReceived(resultCode, intent, this);
break;
case REQ_CODE_TAKE_PHOTO_SMALL:
case REQ_CODE_TAKE_PHOTO_BIG:
TakePhotoUtils.handlePhotoReceived(requestCode, resultCode, intent, this);
break;
default:
finish();
break;
}

finish();
}

To recap: set static data to tell Activity what it should do, launch the Activity and pass the delivered results from to Unity.

Hope this article helped you, if you have any questions don’t hesitate to reach me out on FB and check out my plugins on Asset Store or check our company website.

nineva

Technical and other challenges

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store