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

news2025/2/25 21:27:40

最近工作上遇到了要接入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;
    }

    @Override
    public 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);
        }
    }

    @Override
    public 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());
        }
    }

    @Override
    public 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,url
            int 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

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

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

相关文章

【Tensorflow 2.12 简单智能商城商品推荐系统搭建】

Tensorflow 2.12 简单智能商城商品推荐系统搭建 前言架构数据召回排序部署调用结尾 前言 基于 Tensorflow 2.12 搭建一个简单的智能商城商品推荐系统demo~ 主要包含6个部分&#xff0c;首先是简单介绍系统架构&#xff0c;接着是训练数据收集、处理&#xff0c;然后是召回模型、…

一个小的图文编辑软件 -- 采用winform开发

本人用winform开发了一款图文编辑软件&#xff0c;实现了图片、文字、图形混合排版; 可以对图元调整大小、设置角度、添加剪切区间等操作。本人以前也写过一款类似的软件《WinForm版图像编辑小程序》&#xff1b; 最近几年&#xff0c;本人一直从事图形处理方面的开发&#xff…

雷达开发的基本概念fft,cfar,以及Clutter, CFAR,AoA

CFAR Constant False-Alarm Rate的缩写。在雷达信号检测中&#xff0c;当外界干扰强度变化时&#xff0c;雷达能自动调整其灵敏度&#xff0c;使雷达的虚警概率保持不变。具有这种特性的接收机称为恒虚警接收机。雷达信号的检测总是在干扰背景下进行的&#xff0c;这些干扰包括…

SAP PO/PI 设置字段或静态参数到URL

文章目录 需求一、字段内容设置到URL中二、使用静态值三、测试总结 需求 通过PO/PI访问第三方接口并把字段或静态参数设置在URL中 一、字段内容设置到URL中 首先我们在MassageMapping中需要把字段内容发送到DynamicConfiguration中去&#xff0c;利用UDF UDF代码 这里面需要…

编译工具链 之一 基本概念、组成部分、编译过程、命名规则

编译工具链将程序源代码翻译成可以在计算机上运行的可执行程序。编译过程是由一系列的步骤组成的&#xff0c;每一个步骤都有一个对应的工具。这些工具紧密地工作在一起&#xff0c;前一个工具的输出是后一个工具的输入&#xff0c;像一根链条一样&#xff0c;我们称这一系列工…

【汇编】第一个汇编程序(学习笔记)

一、程序从编写到执行的过程 1、编写 Notepad / UltraEdit 汇编语言 2、编译、连接 MASM.EXE&#xff1a;编译产生目标文件 LINK.EXE&#xff1a;连接&#xff0c;产生可执行文件 连接作用&#xff1a;源程序分为多个子程序编译后&#xff0c;连接在一起。或程序调用其他…

【JavaEE】网络编程---UDP数据报套接字编程

一、UDP数据报套接字编程 1.1 DatagramSocket API DatagramSocket 是UDP Socket&#xff0c;用于发送和接收UDP数据报。 DatagramSocket 构造方法&#xff1a; DatagramSocket 方法&#xff1a; 1.2 DatagramPacket API DatagramPacket是UDP Socket发送和接收的数据报。…

SQL查询优化---单表使用索引及常见索引失效优化

如何避免索引失效 1、全值匹配 系统中经常出现的sql语句如下&#xff1a; EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age30 EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age30 and deptid4EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age30 and dept…

美团真题解析

文章目录 &#x1f31f; 美团真题解析&#x1f34a; 美团面试真题-美团招聘简介&#x1f34a; 美团面试真题-介绍一下MyBatis的缓存机制&#x1f389; 一级缓存&#x1f389; 二级缓存 &#x1f34a; 美团面试真题-谈谈jvm的内存模型&#x1f34a; 美团面试真题-谈谈你知道的垃…

手写 Promise(1)核心功能的实现

一&#xff1a;什么是 Promise Promise 是异步编程的一种解决方案&#xff0c;其实是一个构造函数&#xff0c;自己身上有all、reject、resolve这几个方法&#xff0c;原型上有then、catch等方法。 Promise对象有以下两个特点。 &#xff08;1&#xff09;对象的状态不受…

[SQL开发笔记]WHERE子句 : 用于提取满足指定条件的记录

SELECT DISTINCT语句用户返回列表的唯一值&#xff1a;这是一个很特定的条件&#xff0c;假设我需要考虑很多中限制条件进行查询呢&#xff1f;这时我们就可以使用WHERE子句进行条件的限定 一、功能描述&#xff1a; WHERE子句用于提取满足指定条件的记录&#xff1b; 二、WH…

nginx快速部署一个网站服务 + 多域名 + 多端口

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

C#,数值计算——分类与推理Phylo_slc的计算方法与源程序

1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Phylo_slc : Phylagglom { public override void premin(double[,] d, int[] nextp) { } public override double dminfn(double[…

OS 处理机调度

目录 处理机调度的层次 高级调度 作业 作业控制块 JCB 作业调度的主要任务 低级调度 中级调度 进程调度 进程调度时机 进程调度任务 进程调度机制 排队器 分派器 上下文切换器 进程调度方式 非抢占调度方式 抢占调度方式 调度算法 处理机调度算法的目标 处理…

UE5 虚幻引擎中UI、HUD和UMG的区别与联系

目录 0 引言1 UI 用户界面2 HUD 用户界面3 UMG4 总结 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;UE虚幻引擎专栏&#x1f4a5; 标题&#xff1a;UE5 虚幻引擎中UI、HUD和UMG的区别与联系❣️ 寄语&#xff1a;加油&#xff0c;一次专注一件事…

Java编写图片转base64

图片转成base64 url &#xff0c; 在我们的工作中也会经常用到&#xff0c;比如说导出 word,pdf 等功能&#xff0c;今天我们尝试写一下。 File file new File("");byte[] data null;InputStream in null;ByteArrayOutputStream out null;try{URL url new URL(&…

C++初阶 入门(2)

目录 一、缺省函数 1.1什么是缺省函数 1.2为什么要有缺省函数 1.3使用缺省函数 1.4测试代码 二、函数重载 2.1什么是函数重载 2.2为什么要有函数重载 2.3什么情况构成函数重载 2.4函数重载例子及代码 三、引用 3.1什么是引用 3.2如何引用 ​3.3常引用(可略过) 3…

【宝塔面板建站】本地连接云服务器的数据库 以阿里云服务器为例子(保姆级图文)

目录 实现效果实现过程1. 获取云服务的数据库root密码 2.尝试本地连接2.1 端口放行2.2 云服务器授权本地访问MySQL权限 实现代码总结 『宝塔面板建站』分享宝塔面板从安装到实战的宝塔面板本机免云服务器免域名搭建网站等内容。 欢迎关注 『宝塔面板建站』 系列&#xff0c;持续…

Plex Media Server for Mac: 打造您的专属媒体库

在数字媒体时代&#xff0c;我们越来越依赖各种媒体应用来丰富我们的生活。其中&#xff0c;Plex Media Server for Mac以其高效、稳定和多功能性&#xff0c;逐渐成为了Mac用户们的首选。今天&#xff0c;我们就来深入探讨这款个人媒体软件的优势和应用场景。 Plex Media Serv…

【Zero to One系列】微服务Hystrix的熔断器集成

前期回顾&#xff1a; 【Zero to One系列】springcloud微服务集成nacos&#xff0c;形成分布式系统 【Zero to One系列】SpringCloud Gateway结合Nacos完成微服务的网关路由 1、hystrix依赖包 首先引入hystrix相关的依赖包&#xff0c;版本方面自己和项目内相对应即可&#…