当前位置: 首页 > news >正文

Unity 编写自己的aar库,接收Android广播(broadcastReceiver)并传递到Unity

编写本文是因为找了很多文章,都比较片段,不容易理解,对于Android新手来说理解起来不友好。我这里写了一个针对比较小白的文章,希望有所帮助。

Android端

首先还是先来写Android端,我们新建一个Android空项目,并添加一个Module,具体可以参考这篇《Unity 编写自己的aar库,并通过AndroidJavaProxy调用访问和返回》,我们给Module命名AndroidJFramework,还是一个Library类型。

添加Unity Jar

因为要给Unity传送消息,要使用到UnityPlayer类,所以我们需要把Unity的Lib复制到安卓里,我这里使用的2022.3.17,路径是\Unitys\2022.3.17f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

在这里插入图片描述

我们回到Android,建立了Libs目录并把这个jar复制到安卓的项目里,重命名为calsses_unity.jar
如下图:
在这里插入图片描述


添加了新库,要在build.gradle中添加引用

implementation files('src\\Libs\\classes_unity.jar')

或者还可以在这个jar上点击右键,进行添加
如下图:
在这里插入图片描述




这样gradle文件中会自动添加,如下图:
在这里插入图片描述


最后改完gradle文件,记得sync一下,在菜单的File->Sync Project with Gradle Files

在这里插入图片描述

前期工作做完了,然后我们开始编写Android脚本。

编写Android脚本

我们这里编写两个类

package com.lg.AndroidJFramework;public interface UnityBroadcasterInterface {void onReceive(String action,String msg);}

这个UnityBroadcasterInterface是一个interface,因为Unity只能访问interface。

package com.lg.AndroidJFramework;import android.content.Context;import com.unity3d.player.UnityPlayer;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;public class UnityBroadcaster
{public UnityBroadcasterInterface mInterface;//广播处理并回调Unity中OnReceive()方法private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();Log.d("test", "UnityBroadcastHelper: action: " + action);Bundle bundle = intent.getExtras();if (bundle == null) {bundle = new Bundle();}int n = bundle.size();int i = 0;String parm = "";for (String key : bundle.keySet()) {Object value = bundle.get(key);String omsg = String.format("{ \"%s\" : \"%s\" , \"%s\" : \"%s\" }","id",key,"value",value.toString());parm += omsg;i++;if(i < n)parm += ",";}parm = "{\"data\":["+parm+"]}";mInterface.onReceive(action,parm);}};//构造函数public UnityBroadcaster(UnityBroadcasterInterface callback){mInterface = callback;Context context = UnityPlayer.currentActivity;if (context == null) {Log.e("test","找不到Unity");return;}IntentFilter ifs = new IntentFilter();ifs.addAction("com.lg.updateandroid");context.registerReceiver(broadcastReceiver, ifs);}}

这个UnityBroadcaster类是负责接收广播,并把广播通过mInterface.onReceive(action,parm)传递给Unity。
IntentFilter是广播的过滤,改成你的自定义名称。接收到的广播消息,我拼接成了json格式数据传递给Unity。

最后我们就可以进行编译了。

编译

在这里插入图片描述
我们点击Make Module,运行完成后我们来到build目录就可以找到aar文件。我的是在
E:\AndroidProjects\AndroidJFrameWork\AndroidJFramework\build\outputs\aar
在这里插入图片描述
我们把这个文件复制到Unity项目Plugins\Android目录下。
如下图位置:
在这里插入图片描述


这里我们要进行一个操作,用Winrar把aar文件打开,把Libs里的unity.jar删除掉
在这里插入图片描述
如果没有删除我们在打包的时候可能会出现如下报错:
Duplicate class bitter.jnibridge.JNIBridge found in modules AndroidJFramework-debug-runtime

在这里插入图片描述
提示我们有重复的类JNIBridge .

到这里Android部分就完成了,看起来一大堆操作,其实还是挺简单的。

Unity端

主脚本

Unity里我们也是添加两个脚本。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class UnityBroadcaster : AndroidJavaProxy
{[Serializable]public class RecData{public string id;public string value;}[Serializable]public class RecDataList{ public RecData[] data;}AndroidJavaObject javaObject;public UnityBroadcaster() : base("com.lg.AndroidJFramework.UnityBroadcasterInterface"){javaObject = new AndroidJavaObject("com.lg.AndroidJFramework.UnityBroadcaster", this);}public void onReceive(string action,string msg){RecDataList list = new RecDataList();Debug.Log("Unity onReceive :" + action + msg);list = JsonUtility.FromJson<RecDataList>(msg);for (int i = 0; i < list.data.Length; i++){RecData data = list.data[i];Debug.Log(data.id + " : " + data.value);}}
}

我们建立主脚本UnityBroadcaster ,继承自AndroidJavaProxy。构造函数我们这里的base后面就是包名+interface的名称,例如我的是com.lg.AndroidJFramework.UnityBroadcasterInterface。

javaObject是实例化这个Java对象,需要用包名+类名,例如我的是com.lg.AndroidJFramework.UnityBroadcaster

这两个名称绝对不能错误,请自定修改。

实例化脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static UnityBroadcaster;public class BroadcasterLoad : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){new UnityBroadcaster();}}

AndroidJavaProxy脚本没办法挂在对象上,所以我们建立一个脚本,直接new,挂在主场景对象上。
然后直接进行Unity打包就可以了。

测试

我是从另外一个app上发送的广播,不在本例arr安卓端,你可以自行建立一个带窗体按钮的app,点击按钮发送广播就可以了。

Intent intent=new Intent();
intent.setAction("com.lg.updateandroid");//广播的名字,过滤使用
intent.putExtra("msg1", "haha1");//指定广播内容
intent.putExtra("msg2", "hehe1");//指定广播内容
mContext.sendBroadcast(intent); //发送广播

发送广播后我们可以看到输出的内容:
在这里插入图片描述

参考

https://www.programmersought.com/article/51956081045/
https://vuopaja.com/tutorials/android-java-proxy

相关文章:

Unity 编写自己的aar库,接收Android广播(broadcastReceiver)并传递到Unity

编写本文是因为找了很多文章&#xff0c;都比较片段&#xff0c;不容易理解&#xff0c;对于Android新手来说理解起来不友好。我这里写了一个针对比较小白的文章&#xff0c;希望有所帮助。 Android端 首先还是先来写Android端&#xff0c;我们新建一个Android空项目&#xf…...

Mysql cast函数、cast用法、字符串转数字、字符串转日期、数据类型转换

文章目录 一、语法二、示例2.1、复杂示例 三、cast与convert的区别 CAST 函数是 SQL 中的一种类型转换函数&#xff0c;它用于将一个数据类型转换为另一个数据类型&#xff0c;这篇文章主要介绍了Mysql中Cast()函数的用法,需要的朋友可以参考下。 Mysql提供了两种将值转换成指…...

微信小程序开发之组件复用机制

新建复用文件&#xff0c;另外需要注册 behavior 例如&#xff1a; 在behavior.js文件中写入方法&#xff0c;并向外暴露出去 写法一&#xff1a; module.exportsBehavior({data: {num: 1},lifetimes: {created() {console.log(1);}} })写法二&#xff1a; const behavior …...

数据结构--线性表

数据结构分类 集合 线性结构(一对一) 树形结构(一对多) 图结构(多对多) 数据结构三要素 1、逻辑结构 2、数据的运算 3、存储结构&#xff08;物理结构&#xff09; 线性表分类 1、顺序表 2、链表 3、栈 4、队列 5、串 线性表--顺序表 顺序表的特点 顺序表的删除和插入…...

深入探针:PHP与DTrace的动态追踪艺术

标题&#xff1a;深入探针&#xff1a;PHP与DTrace的动态追踪艺术 在高性能的PHP应用开发中&#xff0c;深入理解代码的执行流程和性能瓶颈是至关重要的。DTrace&#xff0c;作为一种强大的动态追踪工具&#xff0c;为开发者提供了对PHP脚本运行时行为的深入洞察。本文将详细介…...

黑龙江日报报道第5届中国计算机应用技术大赛,赛氪提供赛事支持

2024年7月17日&#xff0c;黑龙江日报、极光新闻对在哈尔滨市举办的第5届中国计算机应用技术大赛全国总决赛进行了深入报道。此次大赛由中国计算机学会主办&#xff0c;中国计算机学会计算机应用专业委员会与赛氪网共同承办&#xff0c;吸引了来自全国各地的顶尖技术团队和选手…...

【计算机网络】LVS四层负载均衡器

https://mobian.blog.csdn.net/article/details/141093263 https://blog.csdn.net/weixin_42175752/article/details/139966198 《高并发的哲学原理》 &#xff08;基本来自本书&#xff09; 《亿级流量系统架构设计与实战》 LVS 章文嵩博士创造 LVS(IPVS&#xff09; 章⽂嵩发…...

Java 守护线程练习 (2024.8.12)

DaemonExercise package DaemonExercise20240812;public class DaemonExercise {public static void main(String[] args) {// 守护线程// 当普通线程执行完毕之后&#xff0c;守护线程没有继续执行的必要&#xff0c;所以说会逐步关闭&#xff08;并非瞬间关闭&#xff09;//…...

C#小桌面程序调试出错,如何解决??

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…...

Seatunnel Mysql数据同步到Mysql

环境 mysql-connector-java-8.0.28.jar、connector-cdc-mysql 配置 env {# You can set SeaTunnel environment configuration hereexecution.parallelism 2job.mode "STREAMING"# 10秒检查一次&#xff0c;可以适当加大这个值checkpoint.interval 10000#execu…...

Java Web —— 第五天(请求响应1)

postman Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件 作用:常用于进行接口测试 简单参数 原始方式 在原始的web程序中&#xff0c;获取请求参数&#xff0c;需要通过HttpServletRequest 对象手动获 http://localhost:8080/simpleParam?nameTom&a…...

【LLMOps】手摸手教你把 Dify 接入微信生态

作者&#xff1a;韩方圆 "Dify on WeChat"开源项目作者 概述 微信作为最热门即时通信软件&#xff0c;拥有巨大的流量。 微信友好的聊天窗口是天然的AI应用LUI(Language User Interface)/CUI(Conversation User Interface)。 微信不仅有个人微信&#xff0c;同时提供…...

Ftrans文件摆渡方案:重塑文件传输与管控的科技先锋

一、哪些行业会用到文件摆渡相关方案 文件摆渡相关的产品和方案通常用于需要在不同的网络、安全域、网段之间传输数据的场景&#xff0c;主要是一些有核心数据需要保护的行业&#xff0c;做了网络隔离和划分。以下是一些应用比较普遍的行业&#xff1a; 金融行业&#xff1a;…...

LaTeX中的除号表示方法详解

/除号 LaTeX中的除号表示方法详解1. 使用斜杠 / 表示除号优点缺点 2. 使用 \frac{} 表示分数形式的除法优点缺点 3. 使用 \div 表示标准除号优点缺点 4. 使用 \over 表示分数形式的除法优点缺点 5. 使用 \dfrac{} 和 \tfrac{} 表示大型和小型分数优点缺点 总结 LaTeX中的除号表…...

DID、DID文档、VC、VP分别是什么 有什么关系

DID&#xff08;去中心化身份&#xff09; 定义&#xff1a;DID 是一种去中心化的唯一标识符&#xff0c;用于表示个体、组织或设备的身份。DID 不依赖于中央管理机构&#xff0c;而是由去中心化网络&#xff08;如区块链&#xff09;生成和管理。 用途&#xff1a;DID 允许用…...

网络安全应急响应

前言\n在网络安全领域&#xff0c;有一句广为人知的话&#xff1a;“没有绝对的安全”。这意味着任何系统都有可能被攻破。安全攻击的发生并不可怕&#xff0c;可怕的是从头到尾都毫无察觉。当系统遭遇攻击时&#xff0c;企业的安全人员需要立即进行应急响应&#xff0c;以将影…...

Qt数据和视图分离——中MCV和MVVM

智能指针 一、背景知识二、命令式编程 vs 声明式编程2.1 命令式编程&#xff08;Imperative Programming&#xff09;2.2 声明式编程&#xff08;Declarative Programming&#xff09; 三、 MVC(Model-View-Controller)3.1 模型&#xff08;Model&#xff09;3.2 视图&#xff…...

重定义变量类型:如#define FLOAT float和typedef float FLOAT的区别

在 C 或 C 中&#xff0c; #define 和 typedef 都可以用来为类型或值创建别名&#xff0c;但它们之间存在一些关键的区别&#xff1a; 预处理指令 ( #define ): #define 是预处理器指令&#xff0c;用于定义宏。 当编译器处理源代码时&#xff0c;预处理器会先运行&#…...

Qt 使用阿里矢量图标库

前言 阿里矢量图标库非常好用&#xff0c;里面有各种丰富的图标&#xff0c;完全免费&#xff0c;还支持自定义图标&#xff0c;还可以将图标打包到一个项目中&#xff0c;使用起来非常方便。 第一步&#xff1a; 打开阿里矢量图标库 第二步&#xff1a; 搜索图标&#x…...

仓颉语言运行时轻量化实践

杨勇勇 华为语言虚拟机实验室架构师&#xff0c;目前负责仓颉语言静态后端的开发工作 仓颉语言运行时轻量化实践 仓颉Native后端&#xff08;CJNative&#xff09;是仓颉语言的高性能、轻量化实现。这里的“轻量化”意指仓颉程序运行过程中占用系统资源&#xff08;内存、CPU等…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

02.运算符

目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&&#xff1a;逻辑与 ||&#xff1a;逻辑或 &#xff01;&#xff1a;逻辑非 短路求值 位运算符 按位与&&#xff1a; 按位或 | 按位取反~ …...