Unity调用安卓接口——实现复制粘贴功能
一、知识点学习
Unity 项目中一些需要访问安卓操作系统的功能,比如获取电量,wifi 状态等,需要 Unity 启动安卓系统的 BroadcastReceiver 监听状态,并在状态更新后通知到 Unity 界面。这就需要一种 Unity 与 Android 互相调用的机制,直观地看就是 C# 与 Java 互相调用的方法。
有 Unity 与 Android 互相调用需求的项目需要在两个开发环境中同时进行,创建两个工程,这时就涉及到如何将两个工程连接起来,有两种方式来连接:
- Android 工程生成 aar/jar 文件,复制到 Unity 工程中,最终使用 Unity 的 Build 机制生成 apk。
- Unity 工程将所有内容和代码导出为一个 Android gradle 项目,然后使用 Android Studio 打开项目进行开发,最终使用 Android Studio 打包 apk。
对比一下两者的优缺点:
Unity 使用 jar/aar 库 |
Unity 导出 gradle 项目 |
|
Unity 与 Android 依赖性 |
Unity 只依赖 Android 库文件,分割清晰,需要同步的文件只有库文件 |
Android 依赖 Unity 导出的场景数据,需要同步的文件太多 |
开发调试速度 |
Android 库文件比较小,调试较快 |
Unity 工程较大,同步较慢,调试周期长 |
Build机制 |
Unity 内置的 Android Build 机制,类似于 eclipse 编译 Android 项目 |
Android Studio gradle |
Build灵活性 |
较差,无法深度定制,库有依赖时需要将全部依赖显式拷贝到 Unity 工程中 |
非常自由,可以使用最新的 Android Build 机制 |
如何打包apk |
Unity Build 机制直接打包 |
Android Studio 打包 |
本项目使用的是第一种方法,因为这个项目中 Unity 工程特别大,导出 Unity 工程的代价太大。但也遇到了库文件依赖问题,不过由于依赖项不是很多,可以手动解决。以下是解决思路:
Unity 调用 Android
Unity官方文档说明需要通过Plugin的方式调用Java代码,但实际上不需要引入任何Plugin就可以调用Java代码。只是一般情况下需要调用的都是封装好的库,这时才需要将 jar 或者 aar 放到 Unity 项目中,然后通过 C# 来访问其中的内容。
jar 或者 aar 文件可以放在Unity任意目录下,为了方便管理,都放在了 Assets/Plugins/Android 目录下。
C# 调用 Java 方法,获取 Java 字段
C# 调用 Java 的底层原理是使用JNI调用,Unity已经提供了很方便的接口:
- 创建对象:C#中使用 AndroidJavaObject 类封装 Java 对象,new 一个 AndroidJavaObject 对象相当于调用对应的 Java 对象的构造函数。借助 C# 可变参数列表,可以给 Java 对象的构造函数传递任意数量的参数。
// 第一个参数是 Java 类的完整包名,剩下的其他参数会传递给构造方法。
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");
- 调用对象方法:使用 AndroidJavaObject 类的 Call 方法,有泛型与非泛型的两个版本。
// 泛型版本,目的是指定返回值的类型
int hash = jo.Call<int>("hashCode");
// 非泛型版本,处理返回值是void的情况。
jo.Call("aMethodReturnVoid"); // String中没有返回void的简单方法。。。
- 获取类,主要用于获取静态字段或调用静态方法,常用来获取 UnityPlayer。
// 传入类的完整包名
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
- 获取静态字段,只有泛型版本,因为不会有void类型的字段。。。
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
二、项目实操环节:
第一步,Unity Part:
新建个 Unity 工程 ,如图实现UI:
绑定一下 按钮 的点击逻辑:
public void onClickCopy()
{Debug.LogWarning("unity copy");// 注意这里的 class 路径 需要跟后面 AS 工程的 JAVA 脚本要对应上!!using (AndroidJavaClass androidClass = new AndroidJavaClass("com.example.moduleb.MainActivity")){// 这里的方法是否是static的也要注意!不是static的,用Call方法!androidClass.CallStatic("copyTextToClipboard", "test text");}
}public void onClickPaste()
{Debug.Log("unity paste ");// 注意这里的 class 路径 需要跟后面 AS 工程的 JAVA 脚本要对应上!!using (AndroidJavaClass androidClass = new AndroidJavaClass("com.example.moduleb.MainActivity")){// 这里的方法是否是static的也要注意!不是static的,用Call方法!string s = androidClass.CallStatic<string>("getTextFromClipboard");Debug.LogWarning("unity paste s=" + s);}
}
unity 部分暂时完成。
第二步,AS Part:
新建个 AS 工程, no activity 就可以。
进去之后,我们 新建一个 module :
然后 再 src 下 新建接口java脚本:
public static void copyTextToClipboard(final String str) {Activity activity = UnityPlayer.currentActivity;activity.runOnUiThread(new Runnable() {@Overridepublic void run() {ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Activity.CLIPBOARD_SERVICE);ClipData clipData = ClipData.newPlainText("data", str);clipboard.setPrimaryClip(clipData);Log.i("speedmobile", "DoCopyText text: " + str);}});
}/** 从剪贴板中获取文本*/
public static String getTextFromClipboard() {Activity activity = UnityPlayer.currentActivity;ClipboardManager clipboard = (ClipboardManager)activity.getSystemService(Activity.CLIPBOARD_SERVICE);if (clipboard != null && clipboard.hasPrimaryClip()&& clipboard.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {ClipData cdText = clipboard.getPrimaryClip();ClipData.Item item = cdText.getItemAt(0);return item.getText().toString();}return "null";
}
注意到 这里 用到的 UnityPlayerActivity 是 Unity 的库类 。这个类需要以 Library 导入到 我们这里的 AndroidTools-module 。 导入的做法是:找到 Unity的安装路径 , 搜索 classes.jar 。
我这里的路径是 :C:\Program Files\Unity\Hub\Editor\2018.4.36f1\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar
然后拷贝到我们module - libs 文件夹内, 右键点击 classes.jar 选择 Add As Library 。
这时候,回头再看我们的java脚本,已经不报错误了。
接下来,需要导出我们当前模块 AndroidTools 为 jar 包 , 给Unity使用。
找到 AndroidTools module 的build.gradle脚本。添加下面task语句:
bundle.gradle 示例:
plugins {id 'com.android.library'
}android {compileSdk 31defaultConfig {minSdk 21targetSdk 31versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"consumerProguardFiles "consumer-rules.pro"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
}dependencies {implementation 'androidx.appcompat:appcompat:1.3.1'implementation 'com.google.android.material:material:1.4.0'implementation files('libs\\classes.jar')testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.3'androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}task clearJar(type: Delete) {delete 'build/libs/androidTools.jar'这行表示如果你已经打过一次包了,再进行打包则把原来的包删掉
}task makeJar(type: Copy) {from('build/intermediates/aar_main_jar/release') //这行表示要打包的文件的路径,根据下面的内容,其实是该路径下的classes.jarinto('build/bin/') //这行表示打包完毕后包的生成路径,也就是生成的包存在哪include('classes.jar') //看到这行,如果你对分包有了解的话,你就可以看出来这行它只是将一些类打包了rename ('classes.jar', 'androidTools.jar')
}makeJar.dependsOn(clearJar, build)
如图:
然后点击 左边的小箭头,运行导出语句。 执行完之后,可以看到在build/bin 下生成了我们需要的jar包。
然后拷贝这个jar包 到 Unity 工程 Assets/Plugins/Android 下。
第三步,build and run!看 logcat !
success!
附上示例项目地址:
https://github.com/zengzhiwei/Unity2Android4Copy.git
Unity调用安卓接口——实现复制粘贴功能相关推荐
- 分享一个unity发布webgl 的复制粘贴功能的插件,unity打包webgl的坑
unity发布webgl 难免需要复制粘贴功能,而自带的UGUI的InputField是不具备的 所以一直在寻找可用的方案,但是unity webgl相关的资料比较少,找下来记录一下,希望可以帮助大家 ...
- android textview 复制粘贴,android app 内 实现文本复制粘贴功能
如果有一天我后悔了自己的决定,希望一切都还来得及. 在app内实现复制粘贴功能,主要分为两种情况.一种是点击按钮,复制指定的文本.一种是长按文本调用系统的复制功能. (一)主要用于复制一些序列号,邀请 ...
- Unity调用安卓相册并支持多选图片
Unity调用安卓相册并支持多选图片 当在Unity中开发Android应用时,有时需要使用安卓设备的相册功能,以便用户可以选择并上传图片.本篇博客将介绍如何在Unity中调用安卓相册,并支持多选图片 ...
- clipboard + element-ui +vue 实现复制粘贴功能与提示
结合 clipboard.js 实现复制.粘贴功能 剪切功能参考官方文档,个人认为用不太上(有富文本编辑器的时候可能才用得上,也或许不需要自己实现) 想要知道怎么使用,优先参考官方文档(如何指定要复制 ...
- 安卓手机如何复制粘贴不重叠_怎么复制粘贴,教您手机怎么复制粘贴
复制黏贴是日常生活中经常会使用到的功能,手机上我们最常用的功能之一就是复制粘贴,但是很多时候,安卓手机直接复制黏贴是很难的.那么安卓手机如何复制粘贴呢?下面,小编给大家讲解手机复制粘贴的操作技巧. A ...
- Unity调用安卓Android的Toast
需求:在游戏中弹窗消息,调起安卓的Toast 项目中需要做Unity和安卓交互时,经常需要通过安卓Toast来做简单的输出,以便于测试. 方法一:Unity中,C#主导 // Unity调用安卓的土司 ...
- 软件测试面试题-如何测试复制粘贴功能
复制粘贴是电脑最普遍的两个操作了,在面试的过程中,有学生被问到如何测试复制粘贴功能的时候,我个人觉得你可以这样去回答 更多学习资源,公众号主页点击领取资料 查看我评论区置顶 首先,这道题目你甚至可以发 ...
- js实现复制粘贴功能
在项目中使用到复制粘贴功能,虽然网上有很多大牛封装了很多的插件,但是还是想不去使用插件,就像自己来实现这个功能. 初步想法: 1. 获取到需要复制的内容,这里我可以将需要复制的内容放在input或者t ...
- 最新js实现复制粘贴功能实例
功能:实现鼠标点击复制内容 描述:使用与手机网站.pc等端. 实现点击复制粘贴功能的代码实例: function common_copy(text){if(text.indexOf('-') !== ...
最新文章
- linux系统yum源,Linux开启安装EPEL YUM源
- Linux 2.6 完全公平调度算法CFS(Completely Fair Scheduler) 分析
- Linux设备驱动开发详解-Note(5)---Linux 内核及内核编程(1)
- Mybatis resultMap空值映射问题解决
- H.264参考软件JM12.2RC代码详细流程
- HDU1286 找新朋友
- redchat怎么编写shell脚本_Linux如何编写shell脚本?
- android ipv6 谷歌,Ipv6使用google服务的DNS
- L44. 通配符匹配
- 阿帕网几台大型计算机网络,阿帕网-互联网的鼻祖(中) | 午夜猫
- MCU 8080规格LCD屏显示优化——RGB666
- 【Scratch案例实操】Scratch字母排序 scratch编程案例教学 scratch创意编程 少儿编程教案
- C++ define的用法
- 地磁传感器还可以用于室内定位?
- JSP开发模型与MVC设计模型
- python访问陌生人qq空间_使用Python+Selenium模拟登录QQ空间
- IT码农进入日企之路——模拟试题
- linux断开其他用户连接,如何Linux中通过命令行注销其他用户ssh连接
- 实训一 思科交换机基础配置
- 微星小飞机怎么调风扇转速?
热门文章
- 使用缓存django、redis
- combo接口(combo接口)
- 解读PMP考点:PMP考试中关于合同计算类型的题目
- 据说99%的程序猿都不懂得这样表白
- 三菱FX5U系列PLC电池安装方法以及GX Works3内相关参数设置
- 科恩第一章Friday, October 29, 2021 10:13 AM
- VirtualBox网络配置:NAT+Host-Only实现连接外网+主机互通
- appium怎么测试ios_使用Appium,Cucumber和Serenity测试iOS应用程序—质量秘诀
- 婴幼儿体重在线计算机,【婴儿体重计算器标准_婴儿体重计算器标准专题】- 天鹅到家...
- 简述igp和egp_igp egp