Unity Android 交互 二

系列篇二
其他篇幅
Unity Android 交互
Unity Android 交互 二
Unity Android 交互 三 多个 Module分别生成 aar 导入Unity自动合并 AndroidManifest.xml
Unity 接入 Android SDK - 讯飞SDK 实战

本篇稍作修改,不再继承 UnityPlayerActivity 实现交互

创建一个Module。 File -> New -> New Module
上篇选择的是一个 Phone 一个手机应用,这次选择 Android Library安卓库工程
这里写图片描述

设置工程名,包名和上篇步骤一样,创建完成如下
这里写图片描述

比创建一个 Phone 工程少了一些文件,res 文件夹下只有这几个文件
打开 AndroidManifest.xml 只有最精简的两行
这里写图片描述

(1)将 src -> androidTest 和 src -> test 无用文件删除
(2)修改 build.gradle 、删除无用引用库
(3)不需要添加Unity 库 classes.jar了,也不需要引用classes.jar 了
(4)测试生成 aar 是否成功都同上篇一样

下面开始创建 .java 代码
选择 包路径 :src -> main -> java-> com.singleLibrary.demo
右键 New -> Java Class
这里写图片描述

打开 TestAndroidLibrary

package com.singleLibrary.demo;

/**
 * Created by Dev on 2017/12/12.
 */

public class TestAndroidLibrary {

}

开始写 Java 代码

package com.singleLibrary.demo;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.widget.Toast;

public class TestAndroidLibrary {
    private static Context unityContext;
    private static Activity unityActivity;

    // 初始化方法,用来传入上下文
    // 这里传入 UnityPlayerActivity
    public static void init(Context _context)
    {
        unityContext = _context.getApplicationContext();
        unityActivity = (Activity)_context;
    }

    // 传入两个数返回他们的和
    public static int add(int arg0, int arg1)
    {
        return  arg0 + arg1;
    }

    // 传入 meg,弹出一个 Toast 操作
    public static void showToast(final String meg)
    {
        // 在 UI 主线程中调用UI
        unityActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(unityContext, meg, Toast.LENGTH_LONG).show();
            }
        });
    }

    // 弹出一个提示窗口,窗口需要的文字信息从strings.xml 里面获取,点击确认关闭
    public static void showAlertDialog(final String _title, final String _content)
    {
        unityActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                AlertDialog.Builder builder = new AlertDialog.Builder(unityActivity);
                builder.setTitle(_title).setMessage(_content).setPositiveButton("Down", null);
                builder.show();
            }
        });
    }
}

将 arr 放入 Unity 工程 Plugins/Android 目录下

编写 C# 测试代码

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

public class TestLibrary : MonoBehaviour {

    public Text text;
    public Button buttonA;
    public Button buttonB;
    public Button buttonC;

    // Use this for initialization
    void Start () {
        buttonA.onClick.AddListener(Add);
        buttonB.onClick.AddListener(ShowDialog);
        buttonC.onClick.AddListener(ShowToast);

        Init();
    }

    private void Init()
    {
#if UNITY_ANDROID
        using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))
            {
                // 获取到 TestAndroidLibrary 的 Java Class
                AndroidJavaClass testAndroidLibrary = new AndroidJavaClass("com.singleLibrary.demo.TestAndroidLibrary");

                // 调用初始化将 UnityPlayerActivity 实例传递进去
                testAndroidLibrary.CallStatic("init", jo);
            }
        }
#endif
    }

    public void Add()
    {
#if UNITY_ANDROID
        // 获取到 TestAndroidLibrary 的 Java Class
        using (AndroidJavaClass testAndroidLibrary = new AndroidJavaClass("com.singleLibrary.demo.TestAndroidLibrary"))
        {
            int number = testAndroidLibrary.CallStatic<int>("add", 100, 200);
            string s = number.ToString();
            ShowText( s);
        }
#endif
    }

    public void ShowDialog()
    {
        // 获取到 TestAndroidLibrary 的 Java Class
        using (AndroidJavaClass testAndroidLibrary = new AndroidJavaClass("com.singleLibrary.demo.TestAndroidLibrary"))
        {
            // 调用的是 静态方法
            testAndroidLibrary.CallStatic("showAlertDialog", "标题", "内容");
        }
    }

    public void ShowToast()
    {
#if UNITY_ANDROID
        // 获取到 TestAndroidLibrary 的 Java Class
        using (AndroidJavaClass testAndroidLibrary = new AndroidJavaClass("com.singleLibrary.demo.TestAndroidLibrary"))
        {
            testAndroidLibrary.CallStatic("showToast", "ABCDEFG");
        }
#endif
    }

    private void ShowText( string _str)
    {
        text.text = _str;
    }
}

配置 Bundle Identifier 和 Minimum API Level 和 arr 中配置一致
打包 APK

安装到虚拟机上测试
这里写图片描述

点击按钮 Add
这里写图片描述

点击 ShowDialog 弹出对话框
这里写图片描述

点击按钮 C 弹出 Toast
这里写图片描述

三个按钮测试成功

发现上面都是通过静态方法调用 Android 方法的,

public void ShowDialog()
    {
        // 获取到 TestAndroidLibrary 的 Java Class
        using (AndroidJavaClass testAndroidLibrary = new AndroidJavaClass("com.singleLibrary.demo.TestAndroidLibrary"))
        {
            // 调用的是 静态方法
            testAndroidLibrary.CallStatic("showAlertDialog", "标题", "内容");
        }
    }

怎么加入调用类方法呢,修改 TestAndroidLibrary.java 加入一个静态实例

private static TestAndroidLibrary instance;

// 添加获取静态实例的方法
    public static TestAndroidLibrary GetInstance()
    {
        if (instance == null)
        {
            instance = new TestAndroidLibrary();
        }
        return  instance;
    }

    // 对象方法
    public int sub (final int number1, final int number2)
    {
        return  number1 - number2;
    }

获取这个静态实例,然后利用这个静态实例调用 sub 方法

全部代码如下

package com.singleLibrary.demo;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.widget.Toast;

public class TestAndroidLibrary {
    private static Context unityContext;
    private static Activity unityActivity;

    // 静态实例
    private static TestAndroidLibrary instance;

    // 初始化方法,用来传入上下文
    // 这里传入 UnityPlayerActivity
    public static void init(Context _context)
    {
        unityContext = _context.getApplicationContext();
        unityActivity = (Activity)_context;
    }

    // 添加获取静态实例的方法
    public static TestAndroidLibrary GetInstance()
    {
        if (instance == null)
        {
            instance = new TestAndroidLibrary();
        }
        return  instance;
    }

    public int sub (final int number1, final int number2)
    {
        return  number1 - number2;
    }

    // 传入两个数返回他们的和
    public static int add(int arg0, int arg1)
    {
        return  arg0 + arg1;
    }

    // 传入 meg,弹出一个 Toast 操作
    public static void showToast(final String meg)
    {
        // 在 UI 主线程中调用UI
        unityActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(unityContext, meg, Toast.LENGTH_LONG).show();
            }
        });
    }

    // 弹出一个提示窗口,窗口需要的文字信息从strings.xml 里面获取,点击确认关闭
    public static void showAlertDialog(final String _title, final String _content)
    {
        unityActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                AlertDialog.Builder builder = new AlertDialog.Builder(unityActivity);
                builder.setTitle(_title).setMessage(_content).setPositiveButton("Down", null);
                builder.show();
            }
        });
    }
}

修改 C# 代码,将ShowToast() 方法修改如下

    public void ShowToast()
    {
#if UNITY_ANDROID
        // 获取到 TestAndroidLibrary 的 Java Class
        using (AndroidJavaClass testAndroidLibrary = new AndroidJavaClass("com.singleLibrary.demo.TestAndroidLibrary"))
        {
            // 获取静态实例
            using (AndroidJavaObject testAndroidLibraryObj = testAndroidLibrary.CallStatic<AndroidJavaObject>("GetInstance"))
            {
                testAndroidLibrary.CallStatic("showToast", "ABCDEFG");

                // 静态实例调用对象方法 sub
                int result = testAndroidLibraryObj.Call<int>("sub", 1000, 100);
                ShowText(result.ToString());
            }
        }
#endif
    }

重新打包 APK 测试 C 按钮,返回 1000 - 100 的结果
这里写图片描述

测试通过

到此一个不继承 UnityPlayerActivity 不依赖 Unity classes.jar 库的 Unity Android 交互 Demo 完成

### 如何在 Unity 中实现与 Android交互 #### 使用 UnityAndroid 接口进行交互Unity3D 开发中,可以通过 Unity 提供的 `AndroidJavaObject` 和 `AndroidJavaClass` 类来访问 Android 原生 API。这使得开发者可以在 Unity 中调用 Android 的功能模块,例如显示 Toast 消息、启动 Activity 或者操作其他 Android 组件。 以下是通过 Unity 调用 Android Toast 消息的一个简单示例: ```csharp using UnityEngine; public class AndroidInteraction : MonoBehaviour { public void ShowToast(string message) { if (Application.platform == RuntimePlatform.Android) { using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(() => { var toastClass = new AndroidJavaClass("android.widget.Toast"); var toastObject = toastClass.CallStatic<AndroidJavaObject>( "makeText", currentActivity, message, toastClass.GetStatic<int>("LENGTH_SHORT") ); toastObject.Call("show"); })); } } } } ``` 此代码片段展示了如何利用 Unity 的 `AndroidJavaObject` 来获取当前活动 (`currentActivity`) 并在其线程上调用 Android 的 `Toast` 方法[^1]。 --- #### 启动 Android 自定义 Activity 除了简单的消息提示外,还可以通过 Unity 启动自定义的 Android Activity。这种情况下通常需要创建一个带有特定入口点的 Android 应用程序,并将其打包到 APK 文件中以便于集成。 以下是如何从 Unity 启动 Android Activity 的方法: 1. **准备 Android 工程** 在 Android Studio 中构建一个新的项目并导出其 AAR 文件或直接编译成 APK。 2. **配置 Unity 项目** 将生成的文件导入至 Unity Assets/Plugins/Android 下面作为依赖库加载。 3. **编写脚本以触发 Activity 加载** ```csharp using UnityEngine; using System.Collections; public class LaunchAndroidActivity : MonoBehaviour { private const string ACTIVITY_CLASS_NAME = "com.example.MyCustomActivity"; IEnumerator Start() { if (Application.platform != RuntimePlatform.Android) yield break; try { using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { var activityContext = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); using (var intent = new AndroidJavaObject("android.content.Intent")) { intent.Call<AndroidJavaObject>("setClassName", activityContext.Call<string>("getPackageName"), ACTIVITY_CLASS_NAME); activityContext.Call("startActivity", intent); } } } catch (System.Exception e) { Debug.LogError($"Failed to start custom Android activity: {e.Message}"); } } } ``` 这段代码演示了如何动态构造 Intent 对象并通过它激活指定名称的目标 Activity[^2]。 --- #### 更复杂的交互方式——双向通信 对于更复杂的应用需求来说,可能还需要支持数据交换以及事件回调等功能。此时可以考虑采用 JNI(Java Native Interface)技术或者借助插件工具简化流程。具体做法如下所示: - 定义接口类用于接收来自 C# 层的消息; - 实现该接口并将实例传递给 Java 部分处理逻辑; - 当有响应返回时再通知回 Unity 端更新界面状态或其他动作。 更多细节可参阅官方文档说明[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值