Unity与Android交互通信系列(6)

  本节主要讲述广播订阅。

  使用AndroidJavaProxy代理接口,我们可以很方便的实现对Android端事件的订阅,灵活的进行Android端与Unity端的代码交互。通过AndroidJavaProxy代理,我们也可以在安卓端使用 BroadcastReceiver 接收广播,然后利用自定义的方法传递给C#端,但这种方式不太通用,我们希望能直接在C#端注册Android广播,下面演示一个通用的广播接收器。

  其原理依然是利用AndroidJavaProxy接口进行桥接,但通过Unity端注入action(Android端广播动作名称)参数,即由C#端控制需要注册的广播,Android端接收到广播之后,进行相应的数据处理(方便将这些数据传递到C#端),然后调用接口方法,触发C#端广播处理方法。首先我们看一下调用逻辑,代码如下:

//代码6-1
//C#端代码
using System.Collections.Generic;
using UnityEngine;
public class BroadcastExample : MonoBehaviour, UnityBroadcastHelper.IBroadcastListener
{UnityBroadcastHelper helper;void Start(){helper = UnityBroadcastHelper.Register( new string[] { "some_action_name" }, this);}public void OnReceive(string action, Dictionary<string, string> dictionary){//广播处理逻辑}void OnDisable(){helper.Stop();}
}

  通过代码13-17可以看到广播注册界面非常简洁,脚本实现了UnityBroadcastHelper.IBroadcastListener 接口,在Start()方法中初始化一个UnityBroadcastHelper 对象,然后通过OnReceive()方法等待Android端回调并进行相应处理即可,使用完后,通过OnDisable()方法停止广播监听。

  C#端UnityBroadcastHelper类代码如下:

//代码6-2
//C#端代码
using System.Collections.Generic;
using UnityEngine;
public class UnityBroadcastHelper
{//Java端对象private readonly AndroidJavaObject javaObject;//构建函数,生成唯一Java端对象实例private UnityBroadcastHelper(string[] actions, IBroadcastListener listener){ListenerAdapter adapter = new ListenerAdapter(listener, this);javaObject = new AndroidJavaObject("com.example.davidwang.UnityBroadcastHelper", actions, adapter);}//注册广播public static UnityBroadcastHelper Register(string[] actions, IBroadcastListener listener){return new UnityBroadcastHelper(actions, listener);}//取消广播订阅public void Stop(){javaObject.Call("stop");}//广播订阅者接口public interface IBroadcastListener{void OnReceive(string action, Dictionary<string, string> dictionary);}//AndroidJavaProxy实现桥接,处理数据并触发订阅方法private class ListenerAdapter : AndroidJavaProxy{readonly IBroadcastListener listener;readonly UnityBroadcastHelper helper;public ListenerAdapter(IBroadcastListener listener, UnityBroadcastHelper helper) : base("com.example.davidwang.UnityBroadcastHelper$BroadcastListener"){this.listener = listener;this.helper = helper;}void onReceive(string action){AndroidJavaObject javaObject = helper.javaObject;if (!javaObject.Call<bool>("hasKeyValue")){return;}string[] keys = javaObject.Call<string[]>("getKeys");string[] values = javaObject.Call<string[]>("getValues");javaObject.Call("pop");Dictionary<string, string> dictionary = new Dictionary<string, string>();int n = keys.Length;for (int i = 0; i < n; i++){dictionary[keys[i]] = values[i];}listener.OnReceive(action, dictionary);}}
}

  UnityBroadcastHelper类是接口的辅助类,其内部定义了IBroadcastListener接口及桥接类ListenerAdapter,并定义了注册与取消注册方法,从而简化调用端的使用。

  Java端代码如下:

//代码6-3
//Java端代码
package com.example.davidwang;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import java.util.LinkedList;
import java.util.Queue;
//引入UnityPlayer类
import com.unity3d.player.UnityPlayer;public class UnityBroadcastHelper {private static final String TAG = "UnityBroadcastHelper";//接口定义public interface BroadcastListener {void onReceive(String action);}private final BroadcastListener listener;private Queue<String[]> keysQueue = new LinkedList<>();private Queue<String[]> valuesQueue = new LinkedList<>();//构造函数,注入Unity端广播订阅者并注册广播public UnityBroadcastHelper(String[] actions, BroadcastListener listener) {this.listener = listener;IntentFilter intentFilter = new IntentFilter();for (String action : actions) {intentFilter.addAction(action);}Context context = UnityPlayer.currentActivity;if (context == null) {return;}context.registerReceiver(broadcastReceiver, intentFilter);}public boolean hasKeyValue() {return !keysQueue.isEmpty();}//返回健public String[] getKeys() {return keysQueue.peek();}//返回值public String[] getValues() {return valuesQueue.peek();}public void pop() {keysQueue.poll();valuesQueue.poll();}//取消广播注册public void stop() {Context context = UnityPlayer.currentActivity;if (context == null) {return;}context.unregisterReceiver(broadcastReceiver);}//广播处理并回调Unity中OnReceive()方法private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();MyLog.d(TAG, "UnityBroadcastHelper: action: " + action);Bundle bundle = intent.getExtras();if (bundle == null) {bundle = new Bundle();}int n = bundle.size();String[] keys = new String[n];String[] values = new String[n];int i = 0;for (String key : bundle.keySet()) {keys[i] = key;Object value = bundle.get(key);values[i] = value != null ? value.toString() : null;i++;}keysQueue.offer(keys);valuesQueue.offer(values);listener.onReceive(action);}};
}

  UnityBroadcastHelper类中的BroadcastListener接口即为需要桥接的接口,在该类的构造函数中传入了C#端定义的action及桥接实例对象并进行了广播注册操作,在stop()方法中取消了广播注册,UnityBroadcastHelper通过持有BroadcastReceiver,将广播注册到Context上下文中。为在两端进行数据传递,将Extra的Bundle数据映射为C#中的Dictionary,传递给 OnReceive()方法,方便C#代码使用。为演示简单,这里将所有类型的数据都映射成string类型,实际使用时可根据需要进行处理,如通过AndroidJavaObject进行复杂类型数据传递。

  通过使用该通用类,不仅可以注册自定义广播,也可以注册系统广播(可能需要权限申请),还可以一次性注册多个广播,界面简洁,使用简单。


提示

         本示例也需要引入UnityPlayer类,该类位于Unity提供的Classes.jar包,引入Jar包流程和处理与上节一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/31303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

物联网APP设计艺术:技巧与未来科技的融合

从早期的智能家居&#xff0c;到今天的服装制造、医疗保健、物流运输、汽车工业...越来越多的行业开始使用物联网。物联网技术跨度大&#xff0c;适用范围广&#xff0c;设计师在面对物联网产品的UI设计项目时往往会感到受阻。这是什么原因呢&#xff1f;物联网应用程序界面设计…

基于国产飞腾2000制作的paddleocr hubserving服务docker镜像文件

paddleocr hubserving国产化飞腾、鲲鹏armv8 api服务镜像制作 一、编译paddle paddle官网说明在处理器飞腾2000和鲲鹏需要自行编译&#xff08;FT2000/Kunpeng 920 2426SK&#xff09; 如果自己编译可以参考官网飞腾/鲲鹏下从源码编译-使用文档-PaddlePaddle深度学习平台 二…

干货满满!亚信安慧亮相PostgreSQL峰会,分享AntDB数据库国产化运维之路

6月15日&#xff0c;PostgreSQL数据库技术峰会广州站圆满落幕。峰会上&#xff0c;亚信安慧数据库智能运维产品负责人李志龙带来了《AntDB数据库运维之路》的主题演讲。如何用好数据是企业数智化转型的重点&#xff0c;更智能的数据管理&#xff0c;在促进数据要素流转&#xf…

哪些医疗器械需要注意网络安全问题?医疗器械网络安全测试方法有哪些?

随着医疗设备的网络化程度不断提高&#xff0c;网络安全问题变得越来越突出。以下是一些需要特别注意网络安全的医疗器械类别&#xff1a;1. 医学影像类设备&#xff1a;包括CT、DR、医用X射线系统、超声诊断仪、磁共振设备、肿瘤治疗机、医用胶片及处理系统、医用3D打印设备等…

WindTerm软件的本地模式和远程模式

WindTerm作为一个多功能的远程终端控制软件&#xff0c;支持本地模式和远程模式两种键盘输入处理方式&#xff0c;这两种模式的主要区别在于键盘输入的处理逻辑和目标&#xff1a; 本地模式&#xff08;Local Mode&#xff09; 在本地模式下&#xff0c;WindTerm不对键盘输入…

怎么使用Consul当配置中心和动态刷新配置

一、背景 由于Eureka官方已经正式宣布&#xff0c;自2.0起不再维护该项目&#xff0c;如果需要使用2.x&#xff0c;自行承担风险。 项目之前使用的Eureka&#xff0c;现在不维护了则需要寻找替代方案。现在Spring Cloud官方推荐Spring Cloud Consul替换Eureka作为注册中心&…

IDEA 学习之 热加载问题(Hot Swap)

目录 1. IDEA 自带热加载1.1. 热加载快捷键1.2. 热加载范围 1. IDEA 自带热加载 1.1. 热加载快捷键 系统快捷键WINCtrl F9MACOPTIOIN F9 1.2. 热加载范围 资源类型是否影响影响范围Java部分方法签名内

常见的spark mllib分类算法详解

构建一个中文博客&#xff1a;常见的分类算法详解 在机器学习和数据科学领域&#xff0c;分类算法是解决分类问题的重要工具。本文将介绍几种常见的分类算法&#xff0c;包括线性支持向量机&#xff08;LinearSVC&#xff09;、逻辑回归&#xff08;Logistic Regression&#…

VUE面试题汇总(九)

之间联系&#xff08;Model 和 ViewModel 的双向数据绑定&#xff09; 解析&#xff1a; MVVM 是 Model-View-ViewModel 的缩写。MVVM 是一种设计思想。Model 层代表数据模型&#xff0c;也可以在 Model 中定义数据修改和操作的业务逻辑&#xff1b;View 代表 UI 组件&#xf…

推荐5个AI辅助生成论文、降低查重率的网站【2024最新】

一、引言 对于忙碌的学生来说&#xff0c;毕业论文通常是一项艰巨的任务。幸运的是&#xff0c;随着人工智能技术的发展&#xff0c;现在有一些工具可以帮助学生轻松完成论文。本文将介绍五个免费的AI工具&#xff0c;它们能够一键帮助你生成毕业论文&#xff0c;让你的学术生…

实验一:Ubuntu系统中的USB设备绑定实验

实验一&#xff1a;Ubuntu系统中的USB设备绑定实验 一、实验目的二、实验原理三、实验环境四、实验步骤任务 1&#xff1a;绑定不同USB设备任务 2&#xff1a;绑定多个相同设ID的串口设备 五、注意事项六、拓展练习 一、实验目的 学习Ubuntu中USB设备命名方法&#xff1b;掌握…

微信小程序app.json

信小程序中的 app.json 是一个重要的配置文件&#xff0c;用于定义小程序的全局配置。它包含了小程序的各种基本信息和页面路径等配置项&#xff0c;具体可以分为以下几个主要部分&#xff1a; 全局配置 在 app.json 中&#xff0c;可以设置小程序的全局属性&#xff0c;如&a…

从零开始精通Onvif之网络配置

&#x1f4a1; 如果想阅读最新的文章&#xff0c;或者有技术问题需要交流和沟通&#xff0c;可搜索并关注微信公众号“希望睿智”。 概述 网络配置是Onvif规范中的重要组成部分&#xff0c;允许用户通过网络远程配置和管理设备的网络设置&#xff0c;比如&#xff1a;DHCP、IP地…

从单体到微服务:Java架构演进之路

从单体到微服务&#xff1a;Java架构演进之路 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 随着互联网行业的不断发展&#xff0c;软件架构也在不断演进&am…

ADI Trinamic tmc2209专为3D打印和激光雕刻打造的高性能解决方案

TMC2209-LA是专为3D打印机和激光雕刻机设计的一款高性能、超静音的两相步进电机驱动器IC。该芯片结合了Trinamic公司的先进技术&#xff0c;为设备提供了稳定、可靠且低噪音的动力驱动解决方案 TMC2209-LA与许多传统驱动器以及TMC2208-LA引脚兼容。TRINAMICS先进的StealthChop2…

springboot基于Web的社区医院管理服务系统 LW+ PPT+源码+讲解

3系统需求分析 3.1系统功能 通过前面的功能分析可以将社区医院管理服务系统的功能分为管理员、用户和医生三个部分&#xff0c;系统的主要功能包括首页、个人中心、用户管理、医生管理、预约医生管理、就诊信息管理、诊疗方案管理、病历信息管理、健康档案管理、费用信息管理…

数据结构_二叉树

目录 一、树型结构 二、二叉树 2.1 概念 2.2 特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储 2.5 遍历二叉树 2.6 操作二叉树 总结 一、树型结构 树是一种非线性的数据结构&#xff0c;它是由 n(n>0) 个有限结点组成一个具有层次关系的集合&#xff0c;一棵 n 个…

OAuth2与OpenID Connect在Java中的实现

引言 在现代的Web应用和微服务架构中&#xff0c;安全性是至关重要的。OAuth2和OpenID Connect&#xff08;OIDC&#xff09;是两种流行的授权和身份验证协议&#xff0c;它们允许用户安全地授权第三方应用访问他们的资源&#xff0c;同时不必分享他们的凭据。本文将详细介绍如…

中央空调水系统安装

冷热水管&#xff1a; 空调冷热水管道的材质应由业主或使用方明确&#xff1a; 1、普通焊接钢管&#xff1b; 2、无缝钢管&#xff1b; 3、镀锌钢管&#xff1b; 4、PP-R管&#xff1b; 5、紫铜管&#xff1b; 6、水管内外表面应光洁、无疵孔、裂缝、结疤、层裂或气泡。…

流媒体开发工程师的面试题

流媒体开发工程师的面试题通常涵盖了广泛的技术领域,包括但不限于音视频处理、编解码技术、网络传输、流媒体协议以及系统设计和架构等。以下是一些可能的面试题示例: 基础知识题: 请解释流媒体的基本原理和关键技术。描述一下常见的音视频编码格式,如H.264、H.265、AAC等,…