Search code examples
javac#androidunity-game-engineaar

onActivityResult Not Being Called For UnityPlayerActivity


I don't have a lot of experience creating Java (.aar) plugins for Unity3d, but I am attempting to setup google authentication with firebase from such a plugin. To give an example of my problem, I begin by opening a unity android application, then I run the c# code below, and get a popup on my display to sign-in with google. I then choose the correct google account, then the google intent/activity disappears, then I receive no indication that "onActivityResult" has been called. No errors occur and I am unable to to do anything with the google account information that I chose.

In the image below, I click submit -> it opens the google sign-in activity in the next picture -> then it returns back to the submit screen (closing the google sign-in activity). enter image description hereenter image description here

I think my issue is in this line:

activity.startActivityForResult(signInIntent, RC_SIGN_IN);

The "activity" in this case is a UnityPlayerActivity sent from the c# unity code below. I think this is making it so my code is looking for an "onActivityResult" method in the C# unity code rather than the java code. Any help would be greatly appreciated. Let me know if you need any other info or screenshots. Please call me out if I am being a moron.

Here is my code for calling the Google Signin Plugin From C# & Unity3d:

        AndroidJNIHelper.debug = true; 
        using (AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
            activity_context = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
        }
        using (AndroidJavaClass pluginClass = new AndroidJavaClass("com.package.class")) {
            if (pluginClass != null) {
                GoogleSignInActivity = pluginClass.CallStatic<AndroidJavaObject>("instance");
                GoogleSignInActivity.Call("SetContext", activity_context);
                GoogleSignInActivity.Call("StartGoogleLogin", activity_context);

                activity_context.Call("runOnUiThread", new AndroidJavaRunnable(() => {
                    GoogleSignInActivity.Call("ShowMessage", "You signed in as " + display_name);
                }));
            }
        }

Here is the code for creating the Google SignIn Activity:

public void StartGoogleLogin(UnityPlayerActivity activity) {
    gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken("some url")
            .requestEmail()
            .build();

    mGoogleSignInClient = GoogleSignIn.getClient(activity, gso);

    Intent signInIntent = mGoogleSignInClient.getSignInIntent();
    activity.startActivityForResult(signInIntent, RC_SIGN_IN);
    Log.d(TAG, "Activity Started; Waiting For Result");
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.d(TAG, "Result Received!");

    if (requestCode == RC_SIGN_IN) {
        Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
        try {
            // Google Sign In was successful
            GoogleSignInAccount account = task.getResult(ApiException.class);
            someMethod(account);
        } catch (ApiException e) {
            // Google Sign In failed, update UI appropriately
            Log.d(TAG, "Google sign in failed", e);
        }
        setResult(RESULT_OK);
    }
}

Thank you for your time.


Solution

  • Well, I solved my own problem of getting Google Authentication to work between the Android .aar plugin and Unity c#. Been working tirelessly and found some kickbutt resources.

    First and foremost, I referenced the code written by a guy named cwgtech HERE.

    I also went through all of his videos.

    Instead of using UnitySendMessage, I was able to use a callback method similar to what CWGTech does to send a googleIdToken back to Unity and sign-in with Google into Firebase. I was also correct in thinking that my mistake was with the statement below:

    activity.startActivityForResult(signInIntent, RC_SIGN_IN);
    

    Instead of doing this, I followed CWGTech's advice and removed "activity." portion. I ran the startActivityForResult in a ResultCallback class that extends Activity. If you are still confused, dm me or comment on this post. Thanks!

    Here is some of the code I used to send a callback string to Unity via a Java Proxy in written in C#. Information about writing a Java proxy can be found in the cwgtech information above. Writing the java proxy is extremely important if you want to get information to flow from Android activities to Unity C#. CWGTech explains the intricacies of java proxies way better than I could do justice.

    public static final String LOGTAG = GoogleSignInActivity.TAG + "_OnResult";
    public static GoogleSignInActivity.ShareStringCallback shareStringCallback;
    
    private static final int RC_SIGN_IN = 9001;
    private GoogleSignInClient mGoogleSignInClient;
    private GoogleSignInOptions gso;
    
    private CallbackManager mCallbackManager;
    
    public void myFinish(String myresult) {
    
        if (shareStringCallback != null) {
            shareStringCallback.onLoginComplete(myresult);
        }
    
        shareStringCallback = null;
        finish();
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(LOGTAG, "onCreateBundle");
        Intent intent = getIntent();
    
        setContentView(R.layout.login_activity);
        findViewById(R.id.buttonFacebookLogin).setOnClickListener(this);
        findViewById(R.id.signInButton).setOnClickListener(this);
        findViewById(R.id.buttonAnonymousSignIn).setOnClickListener(this);
    }
    
    /* GOOGLE SIGN-IN CODE */
    public Intent StartGoogleLogin() {
        /*
        Google Sign In Client Init Code Goes Here
        */
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        return signInIntent;
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //Detects some type of result from an activity, in this case Google
        String id_result = "Send This To Unity";
        myFinish(id_result);
    }
    

    Here is a bit more code from a different java class file. The 'Login' method is called from Unity c#.

    /* INTERFACES FOR CALLBACK FUNCTIONAILITY */
    public interface ShareStringCallback {
        public void onLoginComplete(String result);
    }
    
    public void Login(final ShareStringCallback callback)
    {
        mainActivity.runOnUiThread(new Runnable() {
    
            @Override
            public void run() {
                try {
                    Log.i(TAG,"Starting Authentication");
    
                    try {
                        try {
                            Intent shareIntent = new Intent();
                            shareIntent.setAction(Intent.ACTION_SEND);
                            shareIntent.setClass(mainActivity,OnResultCallback.class);
                            OnResultCallback.shareStringCallback = callback;
                            mainActivity.startActivity(shareIntent);
                        }
                        catch (Exception e)
                        {
                            e.printStackTrace();
                            Log.i(TAG,"error sharing intent: " + e);
                        }
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                        Log.i(TAG,"Error getting Uri: " + e);
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    Log.i(TAG,"Error writing file: " + e);
                }
            }
        });
    }