简体   繁体   English

未为 UnityPlayerActivity 调用 onActivityResult

[英]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.我没有很多为 Unity3d 创建 Java (.aar) 插件的经验,但我正在尝试使用来自此类插件的 firebase 设置 google 身份验证。 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.举一个我的问题的例子,我首先打开一个统一的 android 应用程序,然后我运行下面的 c# 代码,并在我的显示器上弹出一个使用谷歌登录的弹出窗口。 I then choose the correct google account, then the google intent/activity disappears, then I receive no indication that "onActivityResult" has been called.然后我选择正确的谷歌帐户,然后谷歌意图/活动消失,然后我没有收到“onActivityResult”被调用的指示。 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).在下图中,我单击提交 -> 它在下一张图片中打开谷歌登录活动 -> 然后返回到提交屏幕(关闭谷歌登录活动)。 在此处输入图片说明 在此处输入图片说明

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.在这种情况下,“活动”是从下面的 c# 统一代码发送的 UnityPlayerActivity。 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.我认为这样做是为了让我的代码在 C# 统一代码而不是 java 代码中寻找“onActivityResult”方法。 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:这是我从 C# 和 Unity3d 调用 Google Signin 插件的代码:

        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:下面是创建 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.感谢您的时间。

Well, I solved my own problem of getting Google Authentication to work between the Android .aar plugin and Unity c#.好吧,我自己解决了让 Google 身份验证在 Android .aar 插件和 Unity c# 之间工作的问题。 Been working tirelessly and found some kickbutt resources.一直在不知疲倦地工作,并找到了一些 kickbutt 资源。

First and foremost, I referenced the code written by a guy named cwgtech HERE .首先,我参考了一个叫 cwgtech HERE的人写的代码。

I also went through all of hisvideos .我还浏览了他所有的视频

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.我没有使用 UnitySendMessage,而是使用类似于 CWGTech 所做的回调方法将 googleIdToken 发送回 Unity 并使用 Google 登录到 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."我没有这样做,而是遵循了 CWGTech 的建议并删除了“活动”。 portion.部分。 I ran the startActivityForResult in a ResultCallback class that extends Activity.我在扩展 Activity 的 ResultCallback 类中运行了 startActivityForResult。 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#.下面是一些我用来通过 Java 代理向 Unity 发送回调字符串的代码,用 C# 编写。 Information about writing a Java proxy can be found in the cwgtech information above.有关编写 Java 代理的信息可以在上面的 cwgtech 信息中找到。 Writing the java proxy is extremely important if you want to get information to flow from Android activities to Unity C#.如果您想获取从 Android 活动流到 Unity C# 的信息,编写 java 代理非常重要。 CWGTech explains the intricacies of java proxies way better than I could do justice. CWGTech 比我公正地解释了 Java 代理的复杂性。

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.这是来自不同 java 类文件的更多代码。 The 'Login' method is called from Unity c#. 'Login' 方法是从 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);
            }
        }
    });
}

When you start a activity from UnityPlayerActivity, the onActivityResult will be called when finished, but will have its default return value.当您从 UnityPlayerActivity 启动 Activity 时,onActivityResult 将在完成时调用,但将具有其默认返回值。 What you can do is create a new Activity in Android, and extends UnityPlayerActivity.您可以做的是在 Android 中创建一个新的 Activity,并扩展 UnityPlayerActivity。

  1. In Android, create a new Activity在 Android 中,创建一个新的 Activity
import com.unity3d.player.UnityPlayer;

public class OverrideUnityPlayerActivity extends UnityPlayerActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public Activity getCurrentActivity(){
        return mUnityPlayer.currentActivity;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 0) {
            switch (resultCode) {
                case Activity.RESULT_OK:
                    //do something
                    break;
                case Activity.RESULT_CANCELED:
                    //do something
                    break;
            }
        }
    }
}
  1. You need to set this override activity as launch endpoint in AndroidManifest.XML您需要将此覆盖活动设置为 AndroidManifest.XML 中的启动端点
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="false"
        tools:replace="android:allowBackup">
        <activity 
            android:name="com.example.unitylibrary.manager.OverrideUnityPlayerActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="app_name" android:value="app_value"/>
        </activity>
    </application>
</manifest>

3.Then in Unity, you can get this activity and context, also get the onActivityResult 3.然后在Unity中,可以得到这个activity和context,也可以得到onActivityResult

AndroidJavaObject overridePlayerActivity;
AndroidJavaObject overrideActivity;

public void init(){
    overridePlayerActivity = new AndroidJavaObject("com.example.unitylibrary.manager.OverrideUnityPlayerActivity");
    overrideActivity= overridePlayerActivity.Call<AndroidJavaObject>("getCurrentActivity");
}

public void startAct(){
    anonymousFunction.Call("StartActForRes", overrideActivity);
}

Hope this will solve your problem.希望这能解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM