Unity accesses iFlytek Spark SDK through jar package

Recently, I encountered the need to access gpt-related content at work, and simply implemented an Android terminal to access the UnitySDK of iFlytek Spark.
Or you can also access the WebSocket interface. This article only talks about Android implementation
The Unity version I am using is 2021.3.27f1c2
Android version is 4.2.2

1. Download SDK

Log in to the iFlytek open platform and download the SDK as shown in the picture.

2. Create a new Android project

Create a new Android project and create a libs folder under the project

Download the decompressed aar file of the SDK to the libs folder of the Android project
Open the project’s build.gradle
Copy the following code

The red box above refers to aar, and the following is the logic of creating a jar package.

3. Modify the code based on the original demo project

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) {
        // Initialize SDK, Appid and other information are configured in the manifest
        SparkChainConfig sparkChainConfig = SparkChainConfig.builder();
        sparkChainConfig.appID(appid)
                .apiKey(apiKey)
                .apiSecret(apiSecret)//The appid triplet applied by the application
                .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;
    }

}

These interfaces are initialization, release, obtaining Unity’s Activity, and starting 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\\
");
        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\\
");
        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\\
");
        Log.e(TAG, "errCode:" + error.getErrCode() + "errDesc:" + error.getErrMsg());
        if (unityProxy != null) {
            unityProxy.onLLMError(error.getErrCode(), error.getErrMsg());
        }
    }
}

Implement the callback interface so that Unity can register

Click here to export the jar package

4. Import Unity project

Copy the jar package and aar package to this directory of the Unity project

Androidmanifestincrease

Permissions

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)
        {
            //Enter the apikey and other data of the open platform, 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);
        }
    }

}

Access Android interface
Package and run on mobile phone

Enter text in the left input field and click the button to send. Receiving a return indicates success.

The project warehouse address is: https://github.com/oneSitDown/spark-unity