訊飛語音聽寫SDK快速接入(附空指針解決和修改對話框文字方法)

1空猜、賬號準備工作

首先要有一個訊飛的賬號啦末盔,為后面申請APPID、APPKey等東西做準備盆佣。順帶一提:訊飛對不同認證類型用戶開

放的SDK的使用次數(shù)是有不同的往堡,詳情如下圖械荷。

不同用戶的套餐區(qū)別

賬號申請完成后,需要去你自己的控制臺注冊你的應用虑灰,同時也可以看到你的應用對應的 APPID 等屬性吨瞎,開通的功能,調(diào)用量剩余次數(shù)等信息穆咐。

image

本文介紹的是Android SDK的接入颤诀,這是Android SDK的下載地址,可以根據(jù)項目的具體需求具體分析庸娱。

2着绊、SDK集成準備工作

如果參照官方文檔中或者官方DEMO的做法谐算,需要把對應架構(gòu)的文件拷貝到 Android工程的libs目錄下 熟尉。

而官方提供的DEMO中,它只拷貝了armeabi-v7a架構(gòu)洲脂。如下圖所示(我信了它的邪斤儿,在我第一次接入時,就因為參考了官方DEMO只導入了armeabi-v7a架構(gòu)恐锦,導致出了一大堆毛病??)

官方DEMO

為了避免這個坑往果,我的建議是:把提供的架構(gòu)都拷貝到工程里。(有特殊設備需求的除外)

image

然后在build.gradle文件中一铅,添加SDK的依賴

    implementation files('libs/Msc.jar')

如果將SDK導入到lib文件夾后陕贮,可能還會有無法識別的錯誤。

可以試下在build.gradle(app)中注釋掉以下的代碼(玄學操作~~),再繼續(xù)排查潘飘。

//        ndk {
//            //選擇要添加的對應cpu類型的.so庫肮之。
//            abiFilters 'armeabi-v7a', 'armeabi'
//        }

//    sourceSets {
//        main{
//            jniLibs.srcDirs = ['libs']
//        }
//    }

3、在 AndroidManifest.xml 文件 添加所需權(quán)限

靜態(tài)添加權(quán)限部分卜录,參考了官方文檔的說法戈擒。

<!--連接網(wǎng)絡權(quán)限,用于執(zhí)行云端語音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--獲取手機錄音機使用權(quán)限艰毒,聽寫筐高、識別、語義理解需要用到此權(quán)限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--讀取網(wǎng)絡信息狀態(tài) -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--獲取當前wifi狀態(tài) -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允許程序改變網(wǎng)絡連接狀態(tài) -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--讀取手機信息權(quán)限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--讀取聯(lián)系人權(quán)限丑瞧,上傳聯(lián)系人需要用到此權(quán)限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--外存儲寫權(quán)限柑土,構(gòu)建語法需要用到此權(quán)限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存儲讀權(quán)限,構(gòu)建語法需要用到此權(quán)限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置權(quán)限绊汹,用來記錄應用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手機定位信息稽屏,用來為語義等功能提供定位,提供更精準的服務-->
<!--定位信息是敏感信息灸促,可通過Setting.setLocationEnable(false)關(guān)閉定位請求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人臉識別诫欠,還要添加:攝相頭權(quán)限涵卵,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />

不過,靜態(tài)申請了權(quán)限荒叼,還不夠哦轿偎。對于現(xiàn)在的手機,很大部分都已經(jīng)是Android版本678910的了被廓,應用是需要動態(tài)申請權(quán)限的坏晦,得讓用戶確認同意了,APP才可以使用這些權(quán)限嫁乘。

動態(tài)申請權(quán)限的方法有很多昆婿,也有很多開源的項目,這里就不做介紹了蜓斧。

4仓蛆、SDK初始化

SDK初始化建議放在程序入口處(如Application、Activity的onCreate方法)挎春,非常簡單看疙,就一行語句。

初始化代碼如下:

//將“1234567”替換成您申請的APPID
SpeechUtility.createUtility(context, SpeechConstant.APPID +"=1234567");

注意:SpeechConstant.APPID +"=1234567" 采用的是拼接的方式直奋,所以不可以在“=”與appid之間添加任何空字符或者轉(zhuǎn)義符能庆。

5、調(diào)用語音聽寫功能

最重要的來了脚线,前面鋪墊這么久搁胆,就是為了能調(diào)用它的語音聽寫啊。

離線聽寫方式邮绿,需要購買且下載特定的離線識別SDK渠旁,故這里使用的是在線聽寫。

在線聽寫的SDK斯碌,提供了兩種識別方式一死,分別是帶語音對話框識別和無UI識別。

一.無UI識別

//初始化識別無UI識別對象
//使用SpeechRecognizer對象傻唾,可根據(jù)回調(diào)消息自定義界面--自己的語音識別UI
mIat = SpeechRecognizer.createRecognizer(IatDemo.this, mInitListener);

//設置語法ID和 SUBJECT 為空冠骄,以免因之前有語法調(diào)用而設置了此參數(shù)凛辣;或直接清空所有參數(shù)扁誓,具體可參考 DEMO 的示例。
mIat.setParameter( SpeechConstant.CLOUD_GRAMMAR, null );
mIat.setParameter( SpeechConstant.SUBJECT, null );
//設置返回結(jié)果格式足删,目前支持json,xml以及plain 三種格式失受,其中plain為純聽寫文本內(nèi)容
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
//此處engineType為“cloud”
mIat.setParameter( SpeechConstant.ENGINE_TYPE, engineType );
//設置語音輸入語言拂到,zh_cn為簡體中文
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
//設置結(jié)果返回語言
mIat.setParameter(SpeechConstant.ACCENT, "mandarin");
// 設置語音前端點:靜音超時時間兄旬,單位ms辖试,即用戶多長時間不說話則當做超時處理
//取值范圍{1000~10000}
mIat.setParameter(SpeechConstant.VAD_BOS, "4000");
//設置語音后端點:后端點靜音檢測時間劈狐,單位ms肥缔,即用戶停止說話多長時間內(nèi)即認為不再輸入汹来, 
//自動停止錄音,范圍{0~10000}
mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
//設置標點符號,設置為"0"返回結(jié)果無標點,設置為"1"返回結(jié)果有標點
mIat.setParameter(SpeechConstant.ASR_PTT,"1");
//開始識別坟岔,并設置監(jiān)聽器
mIat.startListening(mRecogListener);

二.帶語音對話框識別(SDK自帶)

// 初始化聽寫Dialog社付,如果只使用有UI聽寫功能,無需創(chuàng)建SpeechRecognizer
// 使用UI聽寫功能啼辣,請根據(jù)sdk文件目錄下的notice.txt,放置布局文件和圖片資源
mIatDialog = new RecognizerDialog(IatDemo.this, mInitListener);

//以下為dialog設置聽寫參數(shù)
        mIatDialog.setParameter(SpeechConstant.RESULT_TYPE, "json");
        //設置語音輸入語言鸥拧,zh_cn為簡體中文
        mIatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        //設置結(jié)果返回語言
        mIatDialog.setParameter(SpeechConstant.ACCENT, "mandarin");
        // 設置語音前端點:靜音超時時間麸锉,單位ms花沉,即用戶多長時間不說話則當做超時處理
        //取值范圍{1000~10000}
        mIatDialog.setParameter(SpeechConstant.VAD_BOS, "4500");
        //設置語音后端點:后端點靜音檢測時間碱屁,單位ms,即用戶停止說話多長時間內(nèi)即認為不再輸入蛾找,
        //自動停止錄音娩脾,范圍{0~10000}
        mIatDialog.setParameter(SpeechConstant.VAD_EOS, "1500");
        //開始識別并設置監(jiān)聽器
        mIatDialog.setListener(mRecognizerDialogListener);

//開始識別并設置語音UI監(jiān)聽器
mIatDialog.setListener(mRecognizerDialogListener);
//顯示聽寫對話框打毛,show方法實際是內(nèi)部調(diào)用無UI識別方式
mIatDialog.show();

重點來了,也是很多人很困擾的一步幻枉,官方文檔的說法是使用這個SDK自帶的語音識別對話框碰声,需要把對應的布局文件和圖片資源放入工程中熬甫。然而胰挑,很多人這樣做了之后, mIatDialog.show(); 調(diào)用了還是會出現(xiàn)空指針的異常瞻颂。。例如:??

java.lang.NullPointerException
      at com.iflytek.cloud.ui.a.a(Unknown Source)
      at com.iflytek.cloud.ui.RecognizerDialog.setParameter(Unknown Source)
      atcom.example.mediaplayer.activity.SearchActivity.setParam(SearchActivity.java:111)
      at com.example.mediaplayer.activity.SearchActivity.onClick(SearchActivity.java:86)
      at android.view.View.performClick(View.java:4438)
      at android.view.View$PerformClick.run(View.java:18422)
      at android.os.Handler.handleCallback(Handler.java:733)
      at android.os.Handler.dispatchMessage(Handler.java:95)
      at android.os.Looper.loop(Looper.java:136)
      at android.app.ActivityThread.main(ActivityThread.java:5045)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:515)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
      at dalvik.system.NativeStart.main(Native Method)

解決方法,如下:

首先,在asset文件內(nèi),放入所需的資源正歼。注意:asset文件夾的位置,是要在src/main/ 的下一級冗疮,然后在與

asset文件夾同級的地方創(chuàng)建 jniLibs 文件夾,把 libs/文件夾的對應SDK文件拷貝到 jniLibs 中檩帐,如圖:

image

同時檢查下术幔,SDK初始化的 APPId 有無出錯的可能。

獲取數(shù)據(jù)

解決了空指針的問題后湃密,接下來調(diào)用 show 方法诅挑,就可以在自定義的監(jiān)聽器里愉快地獲取到返回的聽寫數(shù)據(jù)了

 //創(chuàng)建語音識別UI對話框
 mIatDialog = new RecognizerDialog(getActivity(), searchViewModel.mInitListener);
 
 
 
    /**
     * 初始化聽寫事件監(jiān)聽器。
     */
    public InitListener mInitListener = new InitListener() {

        @Override
        public void onInit(int code) {
            if (code != ErrorCode.SUCCESS) {
                //Todo
            }
        }
    };
    /**
     * 聽寫UI監(jiān)聽器 訊飛
     */
    public RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {

        /**
         * 接收語音聽寫回調(diào)信息
         * @param recognizerResult 回調(diào)結(jié)果
         * @param b 是否翻譯
         */
        @Override
        public void onResult(com.iflytek.cloud.RecognizerResult recognizerResult, boolean b) {
        //返回的數(shù)據(jù)
        String data = recognizerResult.getResultString();
        }
        /**
         * 識別回調(diào)錯誤.
         */
        public void onError(SpeechError error) {
            if(error.getErrorCode() == 14002) {
               //Todo
            } else {
               //Todo
            }
        }

    };

修改SDK自帶UI對話框的文字或字體

下面以修改對話框底部的文字為例:

//通過tag找到對話框底部的TextView
TextView recorderDialogTextView = (TextView)  mIatDialog.getWindow().getDecorView().findViewWithTag("textlink");
//動態(tài)更換訊飛自帶對話框的底部文字泛源,必須在dialog的show執(zhí)行后更換拔妥,否則會空指針報錯
recorderDialogTextView.setText(R.string.recorder_dialog_textview_text);
默認文本修改后

返回的聽寫數(shù)據(jù)實例,用于創(chuàng)建實體類:

{
    "sn": 1,
    "ls": true,
    "bg": 0,
    "ed": 0,
    "ws": [
        {
            "bg": 0,
            "cw": [
                {
                    "w": "今天",
                    "sc": 0
                }
            ]
        },
        {
            "bg": 0,
            "cw": [
                {
                    "w": "的",
                    "sc": 0
                }
            ]
        },
        {
            "bg": 0,
            "cw": [
                {
                    "w": "天氣",
                    "sc": 0
                }
            ]
        },
        {
            "bg": 0,
            "cw": [
                {
                    "w": "怎么樣",
                    "sc": 0
                }
            ]
        },
        {
            "bg": 0,
            "cw": [
                {
                    "w": "达箍。",
                    "sc": 0
                }
            ]
        }
    ]
}

注意:若在SDK中開通了 動態(tài)修正的功能没龙,返回的數(shù)據(jù)會出現(xiàn)格式不一致的情況。官方的說法如下:

動態(tài)修正:
  • 未開啟動態(tài)修正:實時返回識別結(jié)果缎玫,每次返回的結(jié)果都是對之前結(jié)果的追加硬纤;
  • 開啟動態(tài)修正:實時返回識別結(jié)果,每次返回的結(jié)果有可能是對之前結(jié)果的的追加赃磨,也有可能是要替換之前某次返回的結(jié)果(即修正)筝家;
  • 開啟動態(tài)修正,相較于未開啟煞躬,返回結(jié)果的顆粒度更小肛鹏,視覺沖擊效果更佳;
  • 使用動態(tài)修正功能需到控制臺-流式聽寫-高級功能處點擊開通恩沛,并設置相應參數(shù)方可使用,參數(shù)設置方法:mIat.setParameter("dwa", "wpgs"); 缕减;
  • 動態(tài)修正功能僅 中文 支持雷客;
  • 未開啟與開啟返回的結(jié)果格式不同,詳見下方桥狡;

若開通了動態(tài)修正功能并設置了dwa=wpgs(僅中文支持)搅裙,會有如下字段返回:

參數(shù) 類型 描述
pgs string 開啟wpgs會有此字段 取值為 "apd"時表示該片結(jié)果是追加到前面的最終結(jié)果;取值為"rpl" 時表示替換前面的部分結(jié)果裹芝,替換范圍為rg字段
rg array 替換范圍部逮,開啟wpgs會有此字段 假設值為[2,5],則代表要替換的是第2次到第5次返回的結(jié)果

PS:一般項目中的語音聽寫需求嫂易,完全可以不使用動態(tài)修正功能兄朋,但若要使用同步顯示語音識別結(jié)果或者比較需要比較精準的結(jié)果,可以考慮使用此功能怜械。

總結(jié)

訊飛語音聽寫SDK颅和,坑點不少傅事,但是都不是很難,用于項目快速接入語音聽寫需求的還是挺不錯的峡扩。蹭越。??

如果要更多操作和功能,請參考訊飛語音聽寫SDK官方文檔 吧??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末教届,一起剝皮案震驚了整個濱河市响鹃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌案训,老刑警劉巖茴迁,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異萤衰,居然都是意外死亡堕义,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門脆栋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倦卖,“玉大人,你說我怎么就攤上這事椿争∨绿牛” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵秦踪,是天一觀的道長褐捻。 經(jīng)常有香客問我,道長椅邓,這世上最難降的妖魔是什么柠逞? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮景馁,結(jié)果婚禮上板壮,老公的妹妹穿的比我還像新娘。我一直安慰自己合住,他們只是感情好绰精,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著透葛,像睡著了一般笨使。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上僚害,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天硫椰,我揣著相機與錄音,去河邊找鬼。 笑死最爬,一個胖子當著我的面吹牛涉馁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播爱致,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼烤送,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了糠悯?” 一聲冷哼從身側(cè)響起帮坚,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎互艾,沒想到半個月后试和,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡纫普,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年阅悍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昨稼。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡节视,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出假栓,到底是詐尸還是另有隱情寻行,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布匾荆,位于F島的核電站拌蜘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏牙丽。R本人自食惡果不足惜简卧,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望剩岳。 院中可真熱鬧贞滨,春花似錦、人聲如沸拍棕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绰播。三九已至,卻和暖如春尚困,著一層夾襖步出監(jiān)牢的瞬間蠢箩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谬泌,地道東北人滔韵。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像掌实,于是被迫代替她去往敵國和親陪蜻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容