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

Unity 通过jar包形式接入讯飞星火SDK

最近工作上遇到了要接入gpt相关内容的需求,简单实现了一个安卓端接入讯飞星火的UnitySDK。
或者也可以接入WebSocket接口的。本文只讲安卓实现
我使用的Unity版本为2021.3.27f1c2
Android版本为4.2.2

1.下载SDK

登陆讯飞开放平台下载如图所示SDK
在这里插入图片描述

2.新建安卓工程

新建安卓工程,在工程下创建libs文件夹
在这里插入图片描述
下载的SDK解压后的aar文件至安卓工程的libs文件夹下
打开工程的build.gradle
复制以下代码
在这里插入图片描述
上面红框部分是引用aar,下面是打jar包的逻辑

3.根据原来的demo工程修改代码

package com.rayneo.sparklib;
import android.app.Activity;
import com.iflytek.sparkchain.core.LLM;
import com.iflytek.sparkchain.core.LLMCallbacks;
import com.iflytek.sparkchain.core.LLMConfig;
import com.iflytek.sparkchain.core.SparkChain;
import com.iflytek.sparkchain.core.SparkChainConfig;public class SparkTool {private static final String TAG = "SparkLLM";private Activity _unityActivity;private String domain ="general";private String url = "wss://spark-api.xf-yun.com/v1.1/chat";public int initSDK(String appid,String apiKey,String apiSecret,int logLevel,String domain,String url) {// 初始化SDK,Appid等信息在清单中配置SparkChainConfig sparkChainConfig = SparkChainConfig.builder();sparkChainConfig.appID(appid).apiKey(apiKey).apiSecret(apiSecret)//应用申请的appid三元组.logLevel(logLevel);int ret = SparkChain.getInst().init(getActivity(),sparkChainConfig);this.domain = domain;this.url = url;return ret;}public void unInitSDK() {SparkChain.getInst().unInit();}Activity getActivity(){if(null == _unityActivity) {try {Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);_unityActivity = activity;} catch (ClassNotFoundException e) {} catch (IllegalAccessException e) {} catch (NoSuchFieldException e) {}}return _unityActivity;}public int startChat(ISparkLLMProxy unityProxy,String msg) {LLMConfig llmConfig = LLMConfig.builder();llmConfig.domain(domain).url(url);LLM llm = new LLM(llmConfig);LLMCallbacks llmCallbacks = new SparkLLMCallbacks(unityProxy);llm.registerLLMCallbacks(llmCallbacks);String myContext = "myContext";int ret = llm.arun(msg,myContext);return ret;}}

这几个接口分别是初始化,释放,获取Unity的Activity,开始gpt。

package com.rayneo.sparklib;public interface ISparkLLMProxy {void onLLMResult(int status, String Content);void onLLMEvent(int eventID, String eventMsg);void onLLMError(int errorCode, String var2);}
package com.rayneo.sparklib;import android.util.Log;import com.iflytek.sparkchain.core.LLMCallbacks;
import com.iflytek.sparkchain.core.LLMError;
import com.iflytek.sparkchain.core.LLMEvent;
import com.iflytek.sparkchain.core.LLMResult;public class SparkLLMCallbacks implements LLMCallbacks {private static final String TAG = "SparkLLMCallbacks";private ISparkLLMProxy unityProxy;public SparkLLMCallbacks(ISparkLLMProxy unityProxy) {this.unityProxy = unityProxy;}@Overridepublic void onLLMResult(LLMResult llmResult, Object usrContext) {Log.d(TAG, "onLLMResult\n");String content = llmResult.getContent();Log.e(TAG, "onLLMResult:" + content);int status = llmResult.getStatus();if (unityProxy != null) {unityProxy.onLLMResult(status, content);}}@Overridepublic void onLLMEvent(LLMEvent event, Object usrContext) {Log.d(TAG, "onLLMEvent\n");Log.w(TAG, "onLLMEvent:" + " " + event.getEventID() + " " + event.getEventMsg());if (unityProxy != null) {unityProxy.onLLMEvent(event.getEventID(), event.getEventMsg());}}@Overridepublic void onLLMError(LLMError error, Object usrContext) {Log.d(TAG, "onLLMError\n");Log.e(TAG, "errCode:" + error.getErrCode() + "errDesc:" + error.getErrMsg());if (unityProxy != null) {unityProxy.onLLMError(error.getErrCode(), error.getErrMsg());}}
}

实现回调接口,让Unity可以注册
在这里插入图片描述
点击此处导出jar包
在这里插入图片描述

4.导入Unity工程

拷贝jar包和aar包至Unity工程此目录下
在这里插入图片描述

Androidmanifest增加
在这里插入图片描述
权限

using System;
using UnityEngine;
using UnityEngine.UI;
//using FfalconXR;public class IFlyLLMHandler : MonoBehaviour
{public InputField input;public Button button;public Text text;private AndroidJavaObject sparkToolInstance;private void Start(){Loom.Initialize();sparkToolInstance = new AndroidJavaObject("com.rayneo.sparklib.SparkTool");InitializeSDK();button.onClick.AddListener(() =>{text.text = "";StartChat(input.text);});}public void InitializeSDK(){if (sparkToolInstance != null){//输入开放平台的apikey等数据,appid,apiKey,apiSecret,logLevel,domain,urlint ret = sparkToolInstance.Call<int>("initSDK", "9e803172", "e4045501df3916cad0c4137d43db8b3b", "ZWFiZGYwMjllNTkyYTFmNjE1YTNiMWRk", 0, "general", "");Debug.Log("initializeSDK error code is" + ret);}else{Debug.LogError("SparkTool instance is null. Make sure the Android plugin is properly imported.");}}public void StartChat(string msg){if (sparkToolInstance != null){int ret = sparkToolInstance.Call<int>("startChat", new SparkLLMProxy(onLLMResult, onLLMEvent, onLLMError), msg);Debug.Log("startChat error code is" + ret);}else{Debug.LogError("SparkTool instance is null. Make sure the Android plugin is properly imported.");}}private void onLLMError(int errorCode, string error){Debug.Log("onLLMError errorCode " + errorCode + " error message " + error);}private void onLLMEvent(int eventID, string eventMsg){Debug.Log("onLLMError eventID " + eventID + " eventMsg " + eventMsg);}private void onLLMResult(int status, string content){Loom.QueueOnMainThread((p) =>{text.text += content;}, null);Debug.Log("onLLMResult status " + status + " content " + content);}public void UninitializeSDK(){if (sparkToolInstance != null){sparkToolInstance.Call("unInitSDK");}else{Debug.LogError("SparkTool instance is null. Make sure the Android plugin is properly imported.");}}
}
public class SparkLLMProxy : AndroidJavaProxy
{private Action<int, string> onLLMResultCallback;private Action<int, string> onLLMEventCallback;private Action<int, string> onLLMErrorCallback;public SparkLLMProxy(Action<int, string> onLLMResult, Action<int, string> onLLMEvent, Action<int, string> onLLMError) : base("com.rayneo.sparklib.ISparkLLMProxy"){onLLMResultCallback = onLLMResult;onLLMEventCallback = onLLMEvent;onLLMErrorCallback = onLLMError;}public void onLLMResult(int status, string content){if (onLLMResultCallback != null){onLLMResultCallback(status, content);}}public void onLLMEvent(int eventID, string eventMsg){if (onLLMEventCallback != null){onLLMEventCallback(eventID, eventMsg);}}public void onLLMError(int errorCode, string error){if (onLLMErrorCallback != null){onLLMErrorCallback(errorCode, error);}}}

接入安卓接口
打包运行至手机上
在这里插入图片描述
左边输入栏输入文本,点击按钮发送。收到返回即代表成功。

工程仓库地址为:https://github.com/oneSitDown/spark-unity

相关文章:

Unity 通过jar包形式接入讯飞星火SDK

最近工作上遇到了要接入gpt相关内容的需求&#xff0c;简单实现了一个安卓端接入讯飞星火的UnitySDK。 或者也可以接入WebSocket接口的。本文只讲安卓实现 我使用的Unity版本为2021.3.27f1c2 Android版本为4.2.2 1.下载SDK 登陆讯飞开放平台下载如图所示SDK 2.新建安卓工程…...

python轻量规则引擎rule-engine入门与应用实践

rule-engine是一种轻量级、可选类型的表达式语言&#xff0c;具有用于匹配任意 Python 对象的自定义语法&#xff0c;使用python语言开发。 规则引擎表达式用自己的语言编写&#xff0c;在 Python 中定义为字符串。其语法与 Python 最相似&#xff0c;但也受到 Ruby 的一些启发…...

栓Q八股文: C++ 14/17 新特性

C 14 翻译&#xff1a; 【翻译】C14的新特性简介-腾讯云开发者社区-腾讯云 C 17翻译&#xff1a;【翻译】C17的新特性简介-腾讯云开发者社区-腾讯云 原理&#xff1a;C Lambda 原理和编译器实现_clamda实现原理-CSDN博客...

虚拟世界游戏定制开发:创造独一无二的虚拟体验

在游戏开发领域&#xff0c;虚拟世界游戏定制开发是一项引人注目的任务&#xff0c;旨在满足客户独特的需求和愿景&#xff0c;创造一个完全个性化的虚拟世界游戏。这种类型的游戏开发需要专业的技能、深刻的游戏开发知识和密切的与客户合作&#xff0c;以确保游戏满足客户的期…...

Tomcat及jdk安装下载及环境配置(超超超详解)

我是看了两篇博客安装配置好的 jdk 最详细jdk安装以及配置环境&#xff08;保姆级教程&#xff09;_安装jdk需要配置环境变量吗-CSDN博客 tomcat Tomcat的下载安装与配置及常见问题处理【Win11】 - 鞠雨童 - 博客园 (cnblogs.com) 本篇文章是我解决了很多朋友的tomcat配置问题总…...

专业安卓实时投屏软件:极限投屏(QtScrcpy作者开发)使用说明

基本介绍 极限投屏是一款批量投屏管理安卓设备的软件&#xff0c;是QtScrcpy作者基于QtScrcpyCore开发&#xff0c;主要功能有&#xff1a; 设备投屏&控制&#xff1a;单个控制、批量控制分组管理wifi投屏adb shell快捷指令文件传输、apk安装 更多功能还在持续更新。 极…...

C++:二叉搜索树的原理和模拟实现

文章目录 二叉搜索树二叉搜索树的基本实现原理 二叉搜索树的实现非递归版本的实现递归版本的实现 二叉搜索树 二叉搜索树也叫做二叉排序树&#xff0c;可以是空树&#xff0c;也可以是满足一些要求的二叉树 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点…...

学习视觉CV Transformer (2)--Transformer原理及代码分析

下面结合代码和原理进行深入分析Transformer原理。 2 Transformer深入分析 对于CV初学者来说&#xff0c;其实只需要理解Q K V 的含义和注意力机制的三个计算步骤&#xff1a; Q 和所有 K 计算相似性&#xff1b;对相似性采用 Softmax 转化为概率分布&#xff1b;将概率分布…...

【AI视野·今日CV 计算机视觉论文速览 第271期】Thu, 19 Oct 2023

AI视野今日CS.CV 计算机视觉论文速览 Thu, 19 Oct 2023 Totally 63 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Learning from Rich Semantics and Coarse Locations for Long-tailed Object Detection Authors Lingchen Meng, Xiyang D…...

GoLong的学习之路(四)语法之循环语句

书接上回&#xff0c;上回说到运算符&#xff0c;这次我们说一个编程语言中最重要的一点&#xff1a;流程控制&#xff0c;及循环语句 文章目录 循环语句if else(分支结构)if条件判断特殊写法 for(循环结构)for range(键值循环) switch casegoto(跳转到指定标签)break(跳出循环…...

【Lua语法】字符串

Lua语言中的字符串是不可变值。不能像在C语言中那样直接改变某个字符串中的某个字符&#xff0c;但是可以通过创建一个新字符串的方式来达到修改的目的 print(add2(1 , 2 ,15,3))a "no one"b string.gsub(a , "no" , "on1111")print(a) print…...

程序员节的由来

早在2006年的时候 我就发现了 1024KB1MB 然后恰好又是2的10次方 那时候我就把这一天定义为程序员节了 不过当时并没有太多的知名度。 所以严格意义来讲 距历史记载&#xff0c;程序员应该是由我&#xff08;田尚滨/cagy&#xff09;发明的。 As early as 2006 I found …...

订水商城H5实战教程-03用户协议

目录 1 创建页面2 为文本组件增加事件3 检查用户协议是否勾选最终效果 我们上一篇介绍了打开首页时弹出登录窗口的功能&#xff0c;本篇我们实现一下用户协议。 1 创建页面 功能是点击用户协议的时候打开具体的协议内容&#xff0c;需要先创建一个页面。打开自定义应用&#x…...

淘宝app商品详情源数据API接口(解决滑块问题)可高并发采集

通过API接口采集淘宝商品列表和app商品详情遇到滑块验证码的解决方法&#xff08;带SKU和商品描述&#xff0c;支持高并发&#xff09;&#xff0c;主要是解决了高频情况下的阿里系滑块和必须要N多小号才能解决的反扒问题&#xff0c;以后都可以使用本方法&#xff1a; 大家都…...

xcode15一直显示正在连接iOS17真机问题解决

前言 更新xcode15之后&#xff0c;出现了各种报错问题&#xff0c;可谓是一路打怪啊&#xff0c;解决一个报错问题又来一个。没想到到了最后还能出现一个一直显示正在连接iOS17真机的问题 一直显示正在连接iOS17真机的问题 问题截图如下&#xff1a; 解决方法 1. 打开De…...

stm32通过AT指令与esp8622通信

stm32通过AT指令与esp8622通信 文章目录 stm32通过AT指令与esp8622通信1.tcp通信2.mqtt通信 1.tcp通信 ATCWMODE1 设置为STA模式ATCWJAP_DEF"langtaotech","langtaotechXXX"ATCIPSTA? 查询ipATCIPMUX0 设置单连接ATCIPSTART"TCP","19…...

Flutter 类似onResume 监听,解决入场动画卡顿

在Flutter 实际开发过程中&#xff0c;页面数据往往是异步加载&#xff0c;接口请求回来后&#xff0c;数据刷新显示到界面上。 由于Flutter性能原因&#xff0c;也可能因为获取数据量比较大&#xff0c;在新页面路由进场动画执行过程中&#xff0c;接口请求结果回来了&#x…...

1024勋章

&#x1f338;关于重阳节的一些发疯日常&#xff08;昨天的聊天记录&#xff0c;今天发系列&#xff09;&#x1f605; &#x1f338;没错&#xff0c;发出来单纯觉得好玩儿&#x1f609;(为了1024勋章&#x1f60f;)芜湖&#xff01;...

C++栈、队列、优先级队列模拟+仿函数

目录 一、栈的模拟和deque容器 1.deque 1.1deque结构 1.2deque优缺点 2.stack模拟 二、队列的模拟 三、priority_queue优先级队列 1.优先级队列模拟 2.添加仿函数 一、栈的模拟和deque容器 在之前&#xff0c;我们学过了C语言版本的栈&#xff0c;可以看这篇文章 栈和…...

ES挂载不上怎么处理?

全文搜索 EelasticSearch安装 Docker安装 docker run -d --name es7 -e ES_JAVA_POTS"-Xms256m -Xmx256m" -e "discovery.typesingle-node" -v /home/206/es7/data/:/usr/share/elasticsearch/data -p 9200:9200 -p 9300:9300 elasticsearch:7.14.0 …...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...