在使用C#Unity连接本机Java时遇到问题

时间:2019-09-04 14:38:10

标签: java c# android unity3d

我尝试为Unity中的InputField创建自己的android键盘,因为标准输入字段存在一些问题。

我已经为Java和C#编写了代码,已经通过模拟器测试了Java代码,并且可以根据需要运行,但是无法与c#连接。

JAVA CODE:

package com.serrviex.nativekeyboardmodule;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;

import android.os.Handler;

public class NativeKeyboard extends Application {

    private Handler handler;

    public String Value;

    public void ShowKeyboard(final Context context, final String value) {
        final LinearLayout linearLayout = new LinearLayout(context);

        Activity activity = (Activity) context;
        activity.setContentView(linearLayout);

        linearLayout.setOrientation(LinearLayout.VERTICAL);
        linearLayout.setY(9999);

        ViewGroup.LayoutParams layoutParams = linearLayout.getLayoutParams();

        linearLayout.setLayoutParams(layoutParams);

        final EditText editText = new EditText(context);
        editText.setText(value);
        linearLayout.addView(editText);

        editText.requestFocus();

        editText.postDelayed(new Runnable() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                        inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
                    }
                });
            }
        }, 100);

        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                Value = editText.getText().toString();
            }

            @Override
            public void afterTextChanged(Editable editable) { }
        });
    }

    public void HideKeyboard(final Activity activity) {
        View view = activity.getCurrentFocus();
        if (view != null) {
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }

    public NativeKeyboard(Context context){
        handler = new Handler(context.getMainLooper());
    }

    private void runOnUiThread(Runnable r) {
        handler.post(r);
    }
}

C#代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NativeKeyboard : MonoBehaviour
{
    public void ShowKeyboard()
    {
        AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject unityActivity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");

        AndroidJavaObject nativeKeyboard = new AndroidJavaObject("com.serrviex.nativekeyboardmodule.NativeKeyboard");

        object[] parameters = new object[2];
        parameters[0] = unityActivity;
        parameters[1] = "Koni";

        nativeKeyboard.Call("ShowKeyboard", parameters);
    }
}

我得到的错误:

  

只有创建视图层次结构的原始线程可以触摸其视图。

今天是我第一次尝试创建自己的插件,这是我第一次使用Java编写。 对不起,ENG。

我解决了(解决方案): Java:

package com.serrviex.nativekeyboardmodule;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;

public class NativeKeyboard extends Application {

    private Activity activity;
    private LinearLayout linearLayout;
    private EditText editText;

    private String Value;

    public void showKeyboard(final Context context, final String value) {
        // Create test toast for verify if this method work
        Toast toast = Toast.makeText(context, value, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0,0);
        toast.show();

        // Get unity activity
        activity = (Activity) context;

        // Create layout for show 'EditText'
        linearLayout = new LinearLayout(context);

        // Run on runned thread
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // Add layout in current activity
                activity.addContentView(linearLayout, new LinearLayout.LayoutParams(0,0));

                linearLayout.setOrientation(LinearLayout.VERTICAL);
                linearLayout.setY(9999);

                // Create 'EditText', and set value from selected unity input
                editText = new EditText(context);
                editText.setText(value);

                // Add view 'EditText' in layout
                linearLayout.addView(editText);

                // Set 'EditText' selected for appear keyboard on tap on input from unity
                editText.requestFocus();

                int randomId = 9999;
                linearLayout.setId(randomId);

                // Appear keyboard
                editText.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                        inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
                    }
                }, 100);

                // Add 'EditText' listeners
                editText.addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

                    @Override
                    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                        Value = editText.getText().toString();
                    }

                    @Override
                    public void afterTextChanged(Editable editable) { }
                });
            }
        });
    }

    public void hideKeyboard(final Activity activity) {
        View view = activity.getCurrentFocus();

        if (view != null) {
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }

        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                int randomId = 9999;
                View linearLayout =  (View)activity.findViewById(randomId);
                ViewGroup parent = (ViewGroup) linearLayout.getParent();
                parent.removeView(linearLayout);
            }
        });
    }
}

C#:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NativeKeyboard : MonoBehaviour
{
    public void ShowKeyboard()
    {
        AndroidJNI.AttachCurrentThread();
        AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject unityActivity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");

        AndroidJavaObject nativeKeyboard = new AndroidJavaObject("com.serrviex.nativekeyboardmodule.NativeKeyboard");

        object[] parameters = new object[2];
        parameters[0] = unityActivity;
        parameters[1] = "Koni";

        nativeKeyboard.Call("showKeyboard", parameters);
    }

    public void HideKeyboard()
    {
        AndroidJNI.AttachCurrentThread();
        AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject unityActivity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");

        AndroidJavaObject nativeKeyboard = new AndroidJavaObject("com.serrviex.nativekeyboardmodule.NativeKeyboard");

        object[] parameters = new object[1];
        parameters[0] = unityActivity;

        nativeKeyboard.Call("hideKeyboard", parameters);
    }
}

0 个答案:

没有答案