6

I am trying to write an Android Plugin for Unity3D to interface with the Google Play In App Billing. I am aware that there are existing plugins out there for this, but I wish to do it on my own.

It appears that I need to catch Android's Activity::onActivityResult to handle a successful purchase through the GPlay IAB SDK. My issue is that my Java class does not contain an Activity because I want it to run in the background behind the actual Unity application.

This is the code from the GPlay IAB SDK which initiates the Purchase flow. If I pass "UnityPlayer.currentActivity" as the activity, Google Play pops up, and you can successfully purchase the product. However, you do not receive a successful message to the OnIabPurchaseFinishedListener. If the purchases is unsuccessful (ie: you already own the product) then I do receive the callback there.

public void launchPurchaseFlow(Activity act, String sku, String itemType, int requestCode,
                        OnIabPurchaseFinishedListener listener, String extraData)
...
...
act.startIntentSenderForResult(pendingIntent.getIntentSender(),
                                           requestCode, new Intent(),
                                           Integer.valueOf(0), Integer.valueOf(0),
                                           Integer.valueOf(0));

Full Source Here: http://pastebin.com/xwUbrwTz

And here is the section from the Google Play In App Billing SDK's (example code) which posts the successful callback (which I am not receiving)

/**
     * Handles an activity result that's part of the purchase flow in in-app billing. If you
     * are calling {@link #launchPurchaseFlow}, then you must call this method from your
     * Activity's {@link android.app.Activity@onActivityResult} method. This method
     * MUST be called from the UI thread of the Activity.
     *
     * @param requestCode The requestCode as you received it.
     * @param resultCode The resultCode as you received it.
     * @param data The data (Intent) as you received it.
     * @return Returns true if the result was related to a purchase flow and was handled;
     *     false if the result was not related to a purchase, in which case you should
     *     handle it normally.
     */
    public boolean handleActivityResult(int requestCode, int resultCode, Intent data)

Full Source: http://pastebin.com/VTfxJhKx

Here is how Google's example code processes the onActivityResult callback:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);

        // Pass on the activity result to the helper for handling
        if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
            // not handled, so handle it ourselves (here's where you'd
            // perform any handling of activity results not related to in-app
            // billing...
            super.onActivityResult(requestCode, resultCode, data);
        }
        else {
            Log.d(TAG, "onActivityResult handled by IABUtil.");
        }
    }

Now, the reason I don't want to override the UnityPlayerActivity class (Search "Extending the UnityPlayerActivity Java Code" on Google, it's the second link. Lack of reputation prevents me from posting the direct link.) is because this requires you to modify the androidmanifest.xml to point to the new "Launcher" - this is a problem because several of the existing Ad platforms for Android already require you to modify the launcher to point to their own Java class. I would like to be able to co-exist with these which prevents me from extending the existing Unity Activity.

I attempted to start my own Activity within my Java class (which is spawned by Unity without issues) but that minimizes the Unity application and pulls up a blank Activity - obviously not what I want.

My question(s): Can I extend/catch/hook into the existing UnityAndroidPlayer class and add an onActivityResult function (it doesn't have one by default).

If no, can I make an activity within an Android plugin that doesn't take focus on the phone?

If no, can I modify the code from the Google Play SDK (act.startIntentSenderForResult(..)) to notify me in a different way?

If no, what can I do?

Matt Hoffman
  • 61
  • 1
  • 2
  • I am attempting to write a plugin for In-App Billing and have the exact same question. Were you able to solve this? The approach I am planning is to have my own Activity but not start it until I'm making a purchase (and have a transparent background when it is launched so only the purchase dialog shows). All the other initialization and calls will be from another non-Activity class and I plan to use UnityPlayer.currentActivity for the "Context". – Goat Jan 22 '14 at 20:07
  • I was not able to solve it. I ended up just making a custom activity (which I passed to Google Play's example code) and then manually setting the activity to mine in the Android Manifest for Unity. It looks like Prime31 was also unable to solve this issue as his plugin works the same way. – Matt Hoffman Jan 23 '14 at 00:40
  • Can you please clarify on what you mean by "passing it on to Google Play's example code" as well as "manually setting the activity to mine"? What do you do about hiding your Activity and showing the game? – Goat Jan 23 '14 at 18:18
  • In my case I realized that the only UI I will show from Android is during the purchase process. That is also when I need an Activity to handle the onActivityResult. So I work with a Singleton non-Activity class for the most way and only start an Activity during the Purchase call. The Activity calls finish() after the Purchase call. – Goat Jan 23 '14 at 18:20
  • @Goat I made a custom Activity that simple extended the default UnityPlayerActivity and put the code related to Google Play (from their SDK example) into this Activity. – Matt Hoffman Jan 24 '14 at 01:59
  • hey MattHoffman, i'm also trying to implement android IAB plugin for unity everything working fine but onPurchaseFinished and onActivityResult callback is not called. I've created activity of type UnityPlayerActivity. I got pop-up of Google Play Billing Services but no purchase result when finished purchase. If you have solution kindly share on this post. thanks – Santosh May 29 '14 at 11:50

1 Answers1

0

The best suggestion I can give is to use the Export build option (this will give you an Eclipse workspace-worth of projects, ready to run). Unity's activities are just code - so you can hook your own code into them, without having to subclass them. This does mean that you won't be able to use the normal Build and Build and Run builds (at least not when you want to test this particular functionality), but it will work. To make the process automatic on each build, you can write a post-build script in Unity.

Vladimir Gritsenko
  • 1,669
  • 11
  • 25