当前位置: 首页 > 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 …...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

32位寻址与64位寻址

32位寻址与64位寻址 32位寻址是什么&#xff1f; 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元&#xff08;地址&#xff09;&#xff0c;其核心含义与能力如下&#xff1a; 1. 核心定义 地址位宽&#xff1a;CPU或内存控制器用32位…...

网页端 js 读取发票里的二维码信息(图片和PDF格式)

起因 为了实现在报销流程中&#xff0c;发票不能重用的限制&#xff0c;发票上传后&#xff0c;希望能读出发票号&#xff0c;并记录发票号已用&#xff0c;下次不再可用于报销。 基于上面的需求&#xff0c;研究了OCR 的方式和读PDF的方式&#xff0c;实际是可行的&#xff…...