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主要代碼如下:
Android Studio
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"; /* 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); ———————————————— */ //2021.3.25更改后如下 private String str = Environment.getExternalStorageDirectory() .getAbsolutePath() + "/msc"; private String grmPath = str+ "/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 = "開始\n"; //mLocalLexicon = "張海羊\n劉婧\n王鋒\n"; 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 放置正確,\n 且有調用 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=c8d477a3"); param.append(","); // 設置使用v5+ //param.append(SpeechConstant.ENGINE_MODE+"="+SpeechConstant.MODE_MSC); //2021.3.31 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 = "開始\n"; 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); ———————————————— */
關鍵詞修改call.bnf
位置
更改:(注意不能定義太多slot,否則會識別不全)
#BNF+IAT 1.0 UTF-8; !grammar call; !slot <keyOperation>; !slot <keyNormal>; !slot <keyRPV>; !start <mainAction>; <mainAction>:<keyOperation>|<keyNormal>|<keyRPV>; <keyOperation>:放大|縮小|旋轉; <keyNormal>:主泵爆炸圖|主泵還原|蒸汽發生器爆炸圖|蒸汽發生器還原|燃料組件爆炸圖|燃料組件還原; <keyRPV>:壓力容器爆炸圖|壓力容器還原|堆內構件爆炸圖|堆內構件還原|體化堆頂結構爆炸圖|體化堆頂結構還原|支承爆炸圖|支承還原|組件吊裝|組件還原;
導出arr准備給unity使用
代碼寫好了我們選中module然后選擇「Build」「Rebuild Project」

接着將這個arr文件找到,就是我們要導入到unity的文件了。
導出的arr文件位置
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; } }
三個方法分別調用了安卓的初始化,構建語法,開始識別三個功能
_ajc = new AndroidJavaObject(“com.iflytek.mscv5plusdemo.AsrDemo”);
尤其要注意的是這行,不能獲取錯了類名,否則會報錯沒辦法運行
將打出來的aar包放在Asset/plugin/Android下,之后將該腳本懸掛至Camera上然后在場景中創建三個button來分別調用這個方法。
ps(如果還是失敗請將手機或者AR眼鏡的對應用的存儲權限和錄音權限打開)
(demo位置;TW/訊飛+unity+語音轉文字/unity+Android+訊飛離線命令詞語音識別)
講項目整合到AMglass眼鏡中,安裝成功后,初始化,構建語法、點擊開始識別,報錯23002(弄了好久才解決)
由於之前在測試項目中,是成功的,現在是將demo中的內容導入AR眼鏡項目,出了問題,各種測試都不能解決問題,於是,對比兩個項目打包設置,發現在buil setting中的一個選項是問題所在,眼鏡項目build system選項是internal,將該選項改為與demo一樣的gradle就解決問題啦。
原設置:
改后: