• Unity+Android+讯飞离线命令词识别(HLYH)


    1.下载SDK之前要先创建自己的应用。去讯飞官网注册个账号,然后创建完成之后打开控制台创建应用。我涂掉的这部分是我自己的appid,这个东西在后面会用到。

    1.下载离线版SDK。下载方法参考网上一些例子。这里就不多说,有很多文章。

    2.下载SDK如下图。

     

    4.直接打开SDK下sample中的demo,build出错“ERROR: Plugin with id 'com.android.application' not found.”

    官网解决方案(用了但是并没有解决)

    如果编译时出现“ERROR: Plugin with id 'com.android.application' not found.”错误,请在build.gradle文件中添加以下代码。

    buildscript {
        repositories {
            google()
            jcenter()
        }
        dependencies {
             //版本号请根据自己的gradle插件版本号自行更改
            classpath 'com.android.tools.build:gradle:3.4.0'
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }

    如在导入项目中还出现其他问题,可参考帖子:安卓demo常见错误排查

    打开file-->project structure ,可查看gradle version,

     

    解决方案(导入module方式):

    新建一个空的Android Studio项目,file--new--import  module导入下载SDK中sample下的demo

     (打开Android Studio,在菜单栏File--->new--->import module当前解压sdk路径,使用离线服务能力选择导入mscV5PlusDemo,导入成功之后sync编译下,编译无误可连接手机,开启手机USB开发调试模式,直接在Android Studio运行导入的mscV5PlusDemo,最后生成的apk可直接安装在对应的手机上。)

    (点击Tool-->SDK Manager可选择版本号)

     

     5主要代码如下:

    AsrDemo
    package com.iflytek.mscv5plusdemo;
    
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.Editor;
    import android.os.Bundle;
    import android.os.Environment;
    import android.text.TextUtils;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.Window;
    import android.widget.EditText;
    import android.widget.RadioGroup;
    import android.widget.RadioGroup.OnCheckedChangeListener;
    import android.widget.Toast;
    
    import com.iflytek.cloud.ErrorCode;
    import com.iflytek.cloud.GrammarListener;
    import com.iflytek.cloud.InitListener;
    import com.iflytek.cloud.LexiconListener;
    import com.iflytek.cloud.RecognizerListener;
    import com.iflytek.cloud.RecognizerResult;
    import com.iflytek.cloud.SpeechConstant;
    import com.iflytek.cloud.SpeechError;
    import com.iflytek.cloud.SpeechRecognizer;
    import com.iflytek.cloud.SpeechUtility;
    import com.iflytek.cloud.util.ContactManager;
    import com.iflytek.cloud.util.ContactManager.ContactListener;
    import com.iflytek.cloud.util.ResourceUtil;
    import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;
    import com.iflytek.speech.util.FucUtil;
    import com.iflytek.speech.util.JsonParser;
    import com.iflytek.speech.util.XmlParser;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class AsrDemo /*extends Activity implements OnClickListener*/{
        private final static String TAG = AsrDemo.class.getSimpleName();
    
        private Toast mToast;
        // 语音识别对象
        private SpeechRecognizer mAsr;
        // 缓存
        private SharedPreferences mSharedPreferences;
        // 本地语法文件
        private String mLocalGrammar = null;
        // 本地词典
        private String mLocalLexicon = null;
        // 云端语法文件
        private String mCloudGrammar = null;
        // 本地语法构建路径
        private String grmPath = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/msc/test";
       
    // 返回结果格式,支持:xml,json
        private String mResultType = "json";
    
        private  final String KEY_GRAMMAR_ABNF_ID = "grammar_abnf_id";
        private  final String GRAMMAR_TYPE_ABNF = "abnf";
        private  final String GRAMMAR_TYPE_BNF = "bnf";
    
        private String mEngineType = SpeechConstant.TYPE_LOCAL;
        @SuppressLint("ShowToast")
        public void onCreate(Bundle savedInstanceState)
        {
            //super.onCreate(savedInstanceState);
            //this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            //setContentView(R.layout.isrdemo);
            initLayout();
    
            // 初始化识别对象
            mAsr = SpeechRecognizer.createRecognizer(getActivity(), mInitListener);
            if(mAsr==null){
                Log.e(TAG,"masr is null");
            }
            // 初始化语法、命令词
            mLocalLexicon = "张海羊
    ";
            //mLocalLexicon = "张海羊
    刘婧
    王锋
    ";
            mLocalGrammar = FucUtil.readFile(getActivity(),"call.bnf", "utf-8");
            mCloudGrammar = FucUtil.readFile(getActivity(),"grammar_sample.abnf","utf-8");
    
            // 获取联系人,本地更新词典时使用
            //ContactManager mgr = ContactManager.createManager(AsrDemo.this, mContactListener);
            //mgr.asyncQueryAllContactsName();
            //mSharedPreferences = getSharedPreferences(getPackageName(),    MODE_PRIVATE);
    
            //mToast = Toast.makeText(this,"",Toast.LENGTH_SHORT);
        }
    
        /**
         * 初始化Layout。
         */
        private void initLayout(){
            //findViewById(R.id.isr_recognize).setOnClickListener(this);
    //
            //findViewById(R.id.isr_grammar).setOnClickListener(this);
            ////findViewById(R.id.isr_lexcion).setOnClickListener(this);
    //
            //findViewById(R.id.isr_stop).setOnClickListener(this);
            //findViewById(R.id.isr_cancel).setOnClickListener(this);
    
    
            //((EditText)findViewById(R.id.isr_text)).setText(mLocalGrammar);
            //findViewById(R.id.isr_lexcion).setEnabled(true);
            mEngineType =  SpeechConstant.TYPE_LOCAL;
            ////选择云端or本地
            //RadioGroup group = (RadioGroup)this.findViewById(R.id.radioGroup);
            //group.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            //    @Override
            //    public void onCheckedChanged(RadioGroup group, int checkedId) {
            //        if(checkedId == R.id.radioCloud)
            //        {
            //            ((EditText)findViewById(R.id.isr_text)).setText(mCloudGrammar);
            //            findViewById(R.id.isr_lexcion).setEnabled(false);
            //            mEngineType = SpeechConstant.TYPE_CLOUD;
            //        }else if(checkedId == R.id.radioLocal)
            //        {
            //            ((EditText)findViewById(R.id.isr_text)).setText(mLocalGrammar);
            //            findViewById(R.id.isr_lexcion).setEnabled(true);
            //            mEngineType =  SpeechConstant.TYPE_LOCAL;
            //        }
            //    }
            //});
        }
    
    
    
    
    
    
    
        String mContent;// 语法、词典临时变量
        int ret = 0;// 函数调用返回值
        //@Override
        //public void onClick(View view) {
        //    if( null == mAsr ){
        //        // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
        //        this.showTip( "创建对象失败,请确认 libmsc.so 放置正确,
     且有调用 createUtility 进行初始化" );
        //        return;
        //    }
        //
        //    if(null == mEngineType) {
        //        showTip("请先选择识别引擎类型");
        //        return;
        //    }
        //    switch(view.getId())
        //    {
        //        case R.id.isr_grammar:
        //            showTip("上传预设关键词/语法文件");
        //            // 本地-构建语法文件,生成语法id
        //            //if (mEngineType.equals(SpeechConstant.TYPE_LOCAL)) {
        //                //((EditText)findViewById(R.id.isr_text)).setText(mLocalGrammar);
        //            Buildsyntax();
        //            //}
        //            //// 在线-构建语法文件,生成语法id
        //            //else {
        //            //    ((EditText)findViewById(R.id.isr_text)).setText(mCloudGrammar);
        //            //    mContent = new String(mCloudGrammar);
        //            //    // 指定引擎类型
        //            //    mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
        //            //    // 设置文本编码格式
        //            //    mAsr.setParameter(SpeechConstant.TEXT_ENCODING,"utf-8");
        //            //    ret = mAsr.buildGrammar(GRAMMAR_TYPE_ABNF, mContent, grammarListener);
        //            //    if(ret != ErrorCode.SUCCESS)
        //            //        showTip("语法构建失败,错误码:" + ret+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
        //            //}
        //            break;
        //        // 本地-更新词典
        //        //case R.id.isr_lexcion:
        //        //    ((EditText)findViewById(R.id.isr_text)).setText(mLocalLexicon);
        //        //    mContent = new String(mLocalLexicon);
        //        //    mAsr.setParameter(SpeechConstant.PARAMS, null);
        //        //    // 设置引擎类型
        //        //    mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
        //        //    // 设置资源路径
        //        //    mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
        //        //    //使用8k音频的时候请解开注释
    //    //        //    mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
        //        //    // 设置语法构建路径
        //        //    mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
        //        //    // 设置语法名称
        //        //    mAsr.setParameter(SpeechConstant.GRAMMAR_LIST, "call");
        //        //    // 设置文本编码格式
        //        //    mAsr.setParameter(SpeechConstant.TEXT_ENCODING,"utf-8");
        //        //    ret = mAsr.updateLexicon("contact", mContent, lexiconListener);
        //        //    if(ret != ErrorCode.SUCCESS){
        //        //        showTip("更新词典失败,错误码:" + ret+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
        //        //    }
        //        //    break;
        //        // 开始识别
        //        case R.id.isr_recognize:
        //            //((EditText)findViewById(R.id.isr_text)).setText(null);// 清空显示内容
        //            StartRecognize();
        //            break;
        //        // 停止识别
        //        case R.id.isr_stop:
        //            mAsr.stopListening();
        //            showTip("停止识别");
        //            break;
        //        // 取消识别
        //        case R.id.isr_cancel:
        //            mAsr.cancel();
        //            showTip("取消识别");
        //            break;
        //    }
        //}
    
    
    
    
        /**
         * 初始化监听器。
         */
        private InitListener mInitListener = new InitListener() {
    
            @Override
            public void onInit(int code) {
                Log.d(TAG, "SpeechRecognizer init() code = " + code);
                if (code != ErrorCode.SUCCESS) {
                    showTip("初始化失败,错误码:"+code+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
                }
            }
        };
    
        /**
         * 更新词典监听器。
         */
        private LexiconListener lexiconListener = new LexiconListener() {
            @Override
            public void onLexiconUpdated(String lexiconId, SpeechError error) {
                if(error == null){
                    showTip("词典更新成功");
                }else{
                    showTip("词典更新失败,错误码:"+error.getErrorCode());
                }
            }
        };
    
        /**
         * 构建语法监听器。
         */
        private GrammarListener grammarListener = new GrammarListener() {
            @Override
            public void onBuildFinish(String grammarId, SpeechError error) {
                if(error == null){
                    if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
                        Editor editor = mSharedPreferences.edit();
                        if(!TextUtils.isEmpty(grammarId))
                            editor.putString(KEY_GRAMMAR_ABNF_ID, grammarId);
                        editor.commit();
                    }
                    showTip("语法构建成功:" + grammarId);
                }else{
                    showTip("语法构建失败,错误码:" + error.getErrorCode());
                }
            }
        };
        /**
         * 获取联系人监听器。
         */
        private ContactListener mContactListener = new ContactListener() {
            @Override
            public void onContactQueryFinish(String contactInfos, boolean changeFlag) {
                //获取联系人
                mLocalLexicon = contactInfos;
            }
        };
        /**
         * 识别监听器。
         */
        private RecognizerListener mRecognizerListener = new RecognizerListener() {
    
            @Override
            public void onVolumeChanged(int volume, byte[] data) {
                callUnity("Main Camera","FromAndroid", "当前正在说话,音量大小:" + volume);
                //showTip("当前正在说话,音量大小:" + volume);
                Log.d(TAG, "返回音频数据:"+data.length);
            }
    
            @Override
            public void onResult(final RecognizerResult result, boolean isLast) {
                if (null != result && !TextUtils.isEmpty(result.getResultString())) {
                    Log.d(TAG, "recognizer result:" + result.getResultString());
                    String text = "";
                    if (mResultType.equals("json")) {
                        text = JsonParser.parseGrammarResult(result.getResultString(), mEngineType);
                        callUnity("Main Camera","FromAndroid", text);
                    } else if (mResultType.equals("xml")) {
                        text = XmlParser.parseNluResult(result.getResultString());
                    }else{
                        text = result.getResultString();
                    }
                    // 显示
                    //((EditText) findViewById(R.id.isr_text)).setText(text);
                } else {
                    Log.d(TAG, "recognizer result : null");
                }
            }
    
            @Override
            public void onEndOfSpeech() {
                // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
                callUnity("Main Camera","FromAndroid", "结束说话");
                //showTip("结束说话");
            }
    
            @Override
            public void onBeginOfSpeech() {
                // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
                //showTip("开始说话");
                callUnity("Main Camera","FromAndroid", "开始说话");
                callUnity("Main Camera","FromAndroid", "开始说话22222");
            }
    
            @Override
            public void onError(SpeechError error) {
                showTip("onError Code:"    + error.getErrorCode());
    
                callUnity("Main Camera","FromAndroid", "onError Code:"    + error.getErrorCode());
                //2021.3.24测试安卓环境下路径
                //callUnity("Main Camera","FromAndroid", "onError Code:"    + Environment.getExternalStorageDirectory()
                    //    .getAbsolutePath() + "/msc/test"+"_________"+grmPath);
            }
    
            @Override
            public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
                // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
                // 若使用本地能力,会话id为null
                //    if (SpeechEvent.EVENT_SESSION_ID == eventType) {
                //        String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
                //        Log.d(TAG, "session id =" + sid);
                //    }
            }
    
        };
    
    
    
        private void showTip(final String str) {
            //runOnUiThread(new Runnable() {
            //    @Override
            //    public void run() {
            //        mToast.setText(str);
            //        mToast.show();
            //    }
            //});
        }
    
        /**
         * 参数设置
         * @return
         */
        public boolean setParam(){
            boolean result = false;
            //callUnity("Main Camera","FromAndroid", "第一行");
            // 清空参数
            mAsr.setParameter(SpeechConstant.PARAMS, null);
            //callUnity("Main Camera","FromAndroid", "第二行");
            // 设置识别引擎
            mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
            //callUnity("Main Camera","FromAndroid", "第三行");
            //if("cloud".equalsIgnoreCase(mEngineType))
            //{
            //    String grammarId = mSharedPreferences.getString(KEY_GRAMMAR_ABNF_ID, null);
            //    if(TextUtils.isEmpty(grammarId))
            //    {
            //        result =  false;
            //    }else {
            //        // 设置返回结果格式
            //        mAsr.setParameter(SpeechConstant.RESULT_TYPE, mResultType);
            //        // 设置云端识别使用的语法id
            //        mAsr.setParameter(SpeechConstant.CLOUD_GRAMMAR, grammarId);
            //        result =  true;
            //    }
            //}
            //else
            //{
            // 设置本地识别资源
            mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
            // 设置语法构建路径
            mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
            // 设置返回结果格式
            mAsr.setParameter(SpeechConstant.RESULT_TYPE, mResultType);
            // 设置本地识别使用语法id
            mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, "call");
            // 设置识别的门限值
            mAsr.setParameter(SpeechConstant.MIXED_THRESHOLD, "30");
            // 使用8k音频的时候请解开注释
    //            mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
            result = true;
            //}
    
            // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
            mAsr.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");
            mAsr.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/asr.wav");
            return result;
        }
    
        //获取识别资源路径
        private String getResourcePath(){
            StringBuffer tempBuffer = new StringBuffer();
            //识别通用资源
            tempBuffer.append(ResourceUtil.generateResourcePath(getActivity(), RESOURCE_TYPE.assets, "asr/common.jet"));
            return tempBuffer.toString();
        }
    
        //@Override
        //protected void onDestroy() {
        //    super.onDestroy();
        //    if( null != mAsr ){
        //        // 退出时释放连接
        //        mAsr.cancel();
        //        mAsr.destroy();
        //    }
        //}
    
        private Activity _unityActivity;
    
        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 boolean InitAsr()
        {
    
            mEngineType =  SpeechConstant.TYPE_LOCAL;
            StringBuffer param = new StringBuffer();
            //param.append("appid=5e4a3f32");
            param.append("appid=5d20577b");
    
            param.append(",");
            // 设置使用v5+
            param.append(SpeechConstant.ENGINE_MODE+"="+SpeechConstant.MODE_MSC);
            SpeechUtility.createUtility(getActivity(), param.toString());
            callUnity("Main Camera","FromAndroid", "构建通用组件成功");
            Context UnityContext=getActivity();
            if(UnityContext==null)
            {
                callUnity("Main Camera","FromAndroid", "UnityActivity为空");
                return  false;
            }
            mAsr = SpeechRecognizer.createRecognizer(UnityContext, mInitListener);
            if(mAsr==null){
                Log.e(TAG,"masr is null");
                callUnity("Main Camera","FromAndroid", "初始化识别引擎失败");
                return  false;
            }
            // 初始化语法、命令词
            mLocalLexicon = "张海羊
    ";
            mLocalGrammar = FucUtil.readFile(getActivity(),"call.bnf", "utf-8");
            mCloudGrammar = FucUtil.readFile(getActivity(),"grammar_sample.abnf","utf-8");
    
            mSharedPreferences = UnityContext.getSharedPreferences(UnityContext.getPackageName(),UnityContext.MODE_PRIVATE);
            callUnity("Main Camera","FromAndroid", "初始化识别引擎成功");
            return true;
        }
    
    
        public boolean Buildsyntax(){
    
            mContent = new String(mLocalGrammar);
            mAsr.setParameter(SpeechConstant.PARAMS, null);
            // 设置文本编码格式
            mAsr.setParameter(SpeechConstant.TEXT_ENCODING,"utf-8");
            // 设置引擎类型
            mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
            // 设置语法构建路径
            mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
            //2021.3.23
            // 设置本地识别使用语法id
            mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, "call");
            // 设置识别的门限值
            mAsr.setParameter(SpeechConstant.MIXED_THRESHOLD, "30");
            //
            //使用8k音频的时候请解开注释
    //                    mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
            // 设置资源路径
            mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
            ret = mAsr.buildGrammar(GRAMMAR_TYPE_BNF, mContent, grammarListener);
            if(ret != ErrorCode.SUCCESS){
                //showTip("语法构建失败,错误码:" + ret+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
                callUnity("Main Camera","FromAndroid", "语法构建失败,错误码:" + ret);
                return false;
            }
            callUnity("Main Camera","FromAndroid", "构建语法完成");
            return true;
        }
    
    
        public boolean StartRecognize(){
            // 设置参数
            if (!setParam()) {
                //showTip("请先构建语法。");
                callUnity("Main Camera","FromAndroid", "请先构建语法");
                return false;
            };
            //grmPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/msc/test";
            callUnity("Main Camera","FromAndroid", Environment.getExternalStorageDirectory()
                    .getAbsolutePath() + "/msc/test");
            ret = mAsr.startListening(mRecognizerListener);
            if (ret != ErrorCode.SUCCESS) {
                //showTip("识别失败,错误码: " + ret+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
                callUnity("Main Camera","FromAndroid", "识别失败,错误码: " + ret+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
                return false;
            }
            callUnity("Main Camera","FromAndroid", "请说话");
            //callUnity("Main Camera","FromAndroid", "请说话");
            return true;
        }
        //public  void Buildsyntax()
        //{
        //    mContent = new String(mLocalGrammar);
        //    mAsr.setParameter(SpeechConstant.PARAMS, null);
        //    // 设置文本编码格式
        //    mAsr.setParameter(SpeechConstant.TEXT_ENCODING,"utf-8");
        //    // 设置引擎类型
        //    mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
        //    // 设置语法构建路径
        //    mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
        //    //使用8k音频的时候请解开注释
    //    //                mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
        //    // 设置资源路径
        //    mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
        //    ret = mAsr.buildGrammar(GRAMMAR_TYPE_BNF, mContent, grammarListener);
        //    if(ret != ErrorCode.SUCCESS){
        //        showTip("语法构建失败,错误码:" + ret+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
        //    }
        //}
    
        //public  void  StartRecognize()
        //{
        //    // 设置参数
        //    if (!setParam()) {
        //        showTip("请先构建语法。");
        //        return;
        //    };
    //
        //    ret = mAsr.startListening(mRecognizerListener);
    //
        //    if (ret != ErrorCode.SUCCESS) {
        //        showTip("识别失败,错误码: " + ret+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
        //    }
        //}
    //
    
    
        /**
         * Toast显示unity发送过来的内容
         * @param content           消息的内容
         * @return                  调用是否成功
         */
        public boolean showToast(String content){
            Toast.makeText(getActivity(),content,Toast.LENGTH_SHORT).show();
            //这里是主动调用Unity中的方法,该方法之后unity部分会讲到
            callUnity("Main Camera","FromAndroid", "hello unity i'm android");
            return true;
        }
    
        /**
         * 调用Unity的方法
         * @param gameObjectName    调用的GameObject的名称
         * @param functionName      方法名
         * @param args              参数
         * @return                  调用是否成功
         */
        boolean callUnity(String gameObjectName, String functionName, String args){
            try {
                Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
                Method method =classtype.getMethod("UnitySendMessage", String.class,String.class,String.class);
                method.invoke(classtype,gameObjectName,functionName,args);
                return true;
            } catch (ClassNotFoundException e) {
    
            } catch (NoSuchMethodException e) {
    
            } catch (IllegalAccessException e) {
    
            } catch (InvocationTargetException e) {
    
            }
            return false;
        }
    
    }
    SpeechApp
    package com.iflytek.mscv5plusdemo;
    
    import android.app.Application;
    
    import com.iflytek.cloud.SpeechConstant;
    import com.iflytek.cloud.SpeechUtility;
    
    public class SpeechApp extends Application{
    
        @Override
        public void onCreate() {
            // 应用程序入口处调用,避免手机内存过小,杀死后台进程后通过历史intent进入Activity造成SpeechUtility对象为null
            // 注意:此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请增加参数:SpeechConstant.FORCE_LOGIN+"=true"
            // 参数间使用“,”分隔。
            // 设置你申请的应用appid
    
            // 注意: appid 必须和下载的SDK保持一致,否则会出现10407错误
    
            StringBuffer param = new StringBuffer();
            param.append("appid="+"5d20577b");
            //param.append("appid="+getString(R.string.app_id));
    
            param.append(",");
            // 设置使用v5+
            param.append(SpeechConstant.ENGINE_MODE+"="+SpeechConstant.MODE_MSC);
            SpeechUtility.createUtility(SpeechApp.this, param.toString());
            super.onCreate();
        }
    }

    build gradle(module mscv5plusdemo)

    apply plugin: 'com.android.library'
    //apply plugin: 'com.android.application'
    android {
        compileSdkVersion 29
    
        buildToolsVersion "29.0.1"
        defaultConfig {
            minSdkVersion 15
            targetSdkVersion 29
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
          //  testInstrumentationRunner "android.support.mscv5plusdemo.runner.AndroidJUnitRunner"
    
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
    
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }
    
        allprojects {
            repositories {
    
                // Msc.jar线上maven地址
                jcenter()
                mavenCentral()
            }
        }
    }
    
    
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    
        implementation 'com.android.support:appcompat-v7:28.0.0'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
        implementation files('libs/Msc.jar')
    
    }
    

     build之后,将arr包导入unity打包 报错23108(弄了好久才解决)

     原因就是创建文件夹失败,以下test文件根本找不到,没有创建成功

     

    解决方案如下

        /*
        private String grmPath = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/msc/test";
                仅仅这句创建文件夹会报错,错误码23108,解决方案如下:
        但是,如果要建多层目录的文件夹的话,可不能一蹴而就。像下面这样写代码的话,执行代码后,在Android设备的外存里是不会创建文件夹“myApp/sub”的:
    String appHome = Environment.getExternalStorageDirectory().getAbsolutePath()+"/myApp";
    createDir(appHome)
    如果要建多层目录的文件夹,只能是一步一步的建,如下所示:
    
    String appHome = Environment.getExternalStorageDirectory().getAbsolutePath()+"/myApp";
    String subPath = appHome+"/sub";
    createDir(appHome);
    createDir(subPath);
    ————————————————
        */

    unity脚本:
    using UnityEngine;
    using UnityEngine.UI;
    
    public class SpeechOffline : MonoBehaviour
    {
    
        /// <summary>
        /// 场景上的文本框用来显示android发送过来的内容
        /// </summary>
        public Text text;
    
        /// <summary>
        /// android原生代码对象
        /// </summary>
        AndroidJavaObject _ajc;
    
        void Start()
        {
            //通过该API来实例化导入的arr中对应的类
            _ajc = new AndroidJavaObject("com.iflytek.mscv5plusdemo.AsrDemo");
            Debug.Log("test log");
        }
    
        void Update()
        {
    
        }
    
        /// <summary>
        /// 场景上按点击时触发该方法
        /// </summary>
        public void OnBtnClick()
        {
            //通过API来调用原生代码的方法
            bool success = _ajc.Call<bool>("InitAsr");
            if (true == success)
            {
                //请求成功
            }
        }
    
        public void OnBtnClick2()
        {
            //通过API来调用原生代码的方法
            bool success = _ajc.Call<bool>("Buildsyntax");
            if (true == success)
            {
                //请求成功
            }
        }
    
        public void OnBtnClick3()
        {
            //通过API来调用原生代码的方法
            bool success = _ajc.Call<bool>("StartRecognize");
            if (true == success)
            {
                //请求成功
            }
        }
    
        /// <summary>
        /// 原生层通过该方法传回信息
        /// </summary>
        /// <param name="content"></param>
        public void FromAndroid(string content)
        {
            text.text = content;
        }
    }

     ps(如果还是失败请将手机或者AR眼镜的对应用的存储权限和录音权限打开)

     (demo位置;TW/讯飞+unity+语音转文字/unity+Android+讯飞离线命令词语音识别)

    讲项目整合到AMglass眼镜中,安装成功后,初始化,构建语法、点击开始识别,报错23002(弄了好久才解决)

     由于之前在测试项目中,是成功的,现在是将demo中的内容导入AR眼镜项目,出了问题,各种测试都不能解决问题,于是,对比两个项目打包设置,发现在buil setting中的一个选项是问题所在,眼镜项目build system选项是internal,将该选项改为与demo一样的gradle就解决问题啦。

    原设置:

     改后:

  • 相关阅读:
    蓝桥杯基础练习 杨辉三角形
    蓝桥杯基础练习 回文数 特殊的数字
    普及图论三题 P1807 P1113 P 4017
    P3916 图的遍历
    [转载][总结]图论入门:建图,DFS,BFS,拓扑排序
    如何转载博客园的文章
    P1892 [BOI2003]团伙
    P1621 集合
    [模板]线性筛素数(欧拉筛)
    P5076 普通二叉树(简化版)
  • 原文地址:https://www.cnblogs.com/WalkingSnail/p/14542464.html
Copyright © 2020-2023  润新知