1. 程式人生 > >Android 科大訊飛語音識別 金額數字

Android 科大訊飛語音識別 金額數字

最近要在應用裡面使用語音識別功能,老闆選擇了科大訊飛的技術,小可也就開始看文件啦;

這裡只嵌入了語音識別,其他的語法什麼的沒有研究,有需要的各位看文件唄;

需要的資料 :只識別數字,若不過濾則把LSpeechManager中的onResult方法中的LDataFormat過濾去掉即可

1,首先要在科大訊飛開放平臺註冊開發者,並註冊應用,然後下載SDK;

2,語音識別需要的檔案:

      (1)Msc.jar

      (2)libmsc.so

3,需要的許可權 :

    <!-- 網路許可權 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 獲取手機錄音機使用許可權,聽寫、識別、語義理解需要用到此許可權 -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <!-- 網路狀態的監控許可權 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <!-- 手機狀態的監聽許可權 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 
4,需要自己的Application,並在其中初始化語音識別
public class Lapp extends Application {
	@Override
	public void onCreate() {
		// 應用程式入口處呼叫,避免手機記憶體過小,殺死後臺程序,造成SpeechUtility物件為null
		// 設定你申請的應用appid
		SpeechUtility.createUtility(Lapp.this, "appid=5486584a");
		super.onCreate();
	}
}

5,語音識別  (使用該類可以直接呼叫start()方法進行語音聽寫識別)
/**
 * 語音識別管理類
 * 
 * @author li'mingqi
 * 
 */
public class LSpeechManager {
	private Context mContext;
	// 語音聽寫
	private SpeechRecognizer mIat;
	// handler
	private Handler mHandler;
	// 識別結果
	private LSpeechResultListener resultListener;
	// 識別成功
	public static final int SPEECH_SUCCESS = 0;
	// 識別失敗
	public static final int SPEECH_FAIL = -1;
	// 開始識別
	public static final int SPEECH_START = 1;
	// 識別出錯
	public static final int SPEECH_ERROR = 2;

	/**
     * 
     */
	@SuppressLint("HandlerLeak")
	public LSpeechManager(Context context) {
		this.mContext = context;
		// 語音聽寫部分
		// 建立SpeechRecognizer物件
		mIat = SpeechRecognizer.createRecognizer(this.mContext, null);
		// 設定聽寫引數
		// 應用領域 --語音識別
		mIat.setParameter(SpeechConstant.DOMAIN, "iat");
		// 語言--中文
		mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
		// mandarin 普通話 cantonese廣東話
		mIat.setParameter(SpeechConstant.ACCENT, "mandarin");
		// 客戶端引擎選擇模式 --雲端msc
		mIat.setParameter(SpeechConstant.ENGINE_MODE, "msc");
		// 客戶端引擎型別 --雲端msc
		mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
		// 資料解碼方式 --utf-8
		mIat.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
		// 初始化聽寫Dialog,如果只使用有UI聽寫功能,無需建立SpeechRecognizer
		mHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				int what = msg.what;
				switch (what) {
				case SPEECH_SUCCESS:// 識別成功
					String result = (String) msg.obj;
					if (null != resultListener) {
						resultListener.onSuccess(result);
					}
					break;

				case SPEECH_FAIL:// 識別失敗
					Toast.makeText(mContext, "請將金額數字按普通話講出", Toast.LENGTH_SHORT)
							.show();
					break;

				case SPEECH_START://開始識別
					if (null != resultListener) {
						resultListener.onStart();
					}
					break;
				case SPEECH_ERROR://識別出錯
					if (null != resultListener) {
						String error = (String) msg.obj;
						resultListener.onError(error);
					}
					break;
				}
			}
		};
	}

	public void start() {
		final StringBuilder sb = new StringBuilder();
		// 開始聽寫
		mIat.startListening(new RecognizerListener() {

			@Override
			public void onVolumeChanged(int arg0) {
				// 音量值變化
			}

			@Override
			public void onResult(RecognizerResult msg, boolean arg1) {
				// 一般情況下會通過onResults介面多次返回結果,完整的識別內容是多次結果的累加;
				// 關於解析Json的程式碼可參見MscDemo中JsonParser類;
				// isLast等於true時會話結束。
				/***
				 * 結果--{"sn":1,"ls":false,"bg":0,"ed":0,"ws":[{"bg":0,"cw":[
				 * {"w":"兩百","sc":0.00}]}]}
				 * 結果--{"sn":2,"ls":true,"bg":0,"ed":0,"ws"
				 * :[{"bg":0,"cw":[{"w":"。","sc":0.00}]}]}
				 */
				try {
					JSONObject mRsult = new JSONObject(msg.getResultString());
					if (!mRsult.getBoolean("ls")) {
						JSONArray data = mRsult.getJSONArray("ws");
						for (int i = 0; i < data.length(); i++) {
							JSONObject w = data.getJSONObject(i);
							JSONArray array = w.getJSONArray("cw");
							for (int k = 0; k < array.length(); k++) {
								JSONObject cwdata = array.getJSONObject(k);
								sb.append(cwdata.getString("w"));
							}
						}
					} else {
						mIat.stopListening();
						String money = LDataFormat.format(sb.toString());
						if ("".equals(money) || null == money
								|| "0".equals(money)) {
							Message msgs = mHandler.obtainMessage();
							msgs.what = SPEECH_FAIL;
							mHandler.sendMessage(msgs);
						} else {
							Message msgs = mHandler.obtainMessage();
							msgs.what = SPEECH_SUCCESS;
							msgs.obj = money;
							mHandler.sendMessage(msgs);
						}
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}

			@Override
			public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
				// 擴充套件類回撥
			}

			@Override
			public void onError(SpeechError error) {
				// 回話發生錯誤時回撥的函式
				String merror = error.getPlainDescription(true);// 獲取錯誤碼描述
				Message msg=mHandler.obtainMessage();
				msg.what=SPEECH_ERROR;
				msg.obj=merror;
				mHandler.sendMessage(msg);
			}

			@Override
			public void onEndOfSpeech() {
				// 結束錄音
			}

			@Override
			public void onBeginOfSpeech() {
				// 開始錄音
				Message msg=mHandler.obtainMessage();
				msg.what=SPEECH_START;
				mHandler.sendMessage(msg);
			}
		});
	}

	/**識別回撥
         * @param resultListener
	 *            the resultListener to set
	 */
	public void setResultListener(LSpeechResultListener resultListener) {
		this.resultListener = resultListener;
	}

	public interface LSpeechResultListener {

		public void onStart();//開始識別

		public void onError(String error);//識別出現錯誤  ---錯誤的內容

		public void onSuccess(String result);//識別成功   ---識別結果
	}
}

6,貼上過濾文字和其他無關的內容的LDateFormat類  (很大一部分是別人寫的,謝謝那位大神!)

/**
 * 資料格式化
 * <ol>
 * 該類主要解決語音輸入時攜帶漢字或者漢字數字混合的字串情況
 * <li>該類會將除{'分','毛','塊','十','百','千','萬','億','一','二','三'...}以外所有的漢字移除並替換格式補位.
 * 即'十'放在十位,'百'放在百位...
 * <li>例如:你好,280元----->280;兩百八十元------>280
 * <ol>
 * 
 * @author li'mingqi
 * @version 1.0
 */
public class LDataFormat {
	// 全域性陣列,儲存單位量級
	public static String[] strCHup = { "億", "萬", "千", "百", "十", "元" };

	/***
	 * 格式化資料
	 * 
	 * @param source
	 *            語音輸入的資料
	 * @return 返回格式化後的數字字串
	 * 
	 *         li'mingqi 2014-12-11
	 * 
	 **/
	public static String format(String source) {
		// 1,去除不相干的文字資訊
		char[] pt = source.toCharArray();
		for (int i = 0; i < pt.length; i++) {
			char k = pt[i];
			if (k == '一' || k == '二' || k == '兩' || k == '三' || k == '四'
					|| k == '五' || k == '六' || k == '七' || k == '八' || k == '九'
					|| k == '十' || k == '百' || k == '千' || k == '萬' || k == '億'
					|| k == '0' || k == '1' || k == '2' || k == '3' || k == '4'
					|| k == '5' || k == '6' || k == '7' || k == '8' || k == '9') {

			} else {
				source = source.replace(k + "", "");
			}
		}
		// 去除空格間隙
		source.trim();
		// 2,漢字'十','百','千'的轉換
		long money = 0;
		// 如果不是數字也就是 一千萬這樣的漢字 ---則需要轉換 如 一百五十萬----1500000
		if (source.contains("一") || source.contains("二")
				|| source.contains("兩") || source.contains("三")
				|| source.contains("四") || source.contains("五")
				|| source.contains("六") || source.contains("七")
				|| source.contains("八") || source.contains("九")
				|| source.contains("十") || source.contains("百")
				|| source.contains("千") || source.contains("萬")
				|| source.contains("億")) {
			money = excuteCharge(source);
		}
		// 資料的來源直接就是阿拉伯數字 如200元---此時元已經去掉,即數字200
		else {
			if (!"".equals(source)) {
				money = Integer.parseInt(source);
			}
		}
		// 3,返回最終格式化結果

		return money + "";
	}

	/***
	 * 通過兩次遞迴呼叫實現分割.
	 * 
	 * @param str
	 * @return li'mingqi 2014-12-11
	 */
	public static long excuteCharge(String str) {
		// 儲存量級單位
		long midNumber = 0;
		// 儲存是否可以找到最高量級
		int bre = -1;
		// 找到後根據索引實行字串分割
		int split = 0;
		// 通過迴圈查詢最高量級
		for (int i = 0; i < strCHup.length; i++) {
			bre = str.indexOf(strCHup[i]);
			if (bre != -1) {
				split = i;
				switch (i) {
				case 0:
					midNumber = 100000000;
					break;
				case 1:
					midNumber = 10000;
					break;
				case 2:
					midNumber = 1000;
					break;
				case 3:
					midNumber = 100;
					break;
				case 4:
					midNumber = 10;
					break;
				case 5:
					midNumber = 1;
					break;
				}
				// 只需要找到最高量級,找到即刻跳出迴圈.
				break;
			}

		}
		// 如果沒有找到量級數.說明該數很小,直接呼叫add()返回該值.
		if (bre == -1) {
			return add(str);
		}
		// 否則要根據量級進行字串侵害和返回侵害前部分的值
		else {
			// 如果大型整數,如:十萬 等.因為後面不需要再分割
			if (str.length() == bre + 1) {
				// 對於單個量級的值,如:十、百、千、萬等。不需要裁減字串。直接返回量級即可
				if (str.length() == 1) {
					return midNumber;
				} else {
					return add(str.substring(0, str.length() - 1)) * midNumber;
				}
			}
			// 對於只有兩位數的.如:十九.直接呼叫add()返回值即可.不能在此處遞迴.
			else if (str.length() == bre + 2) {
				return add(str);
			}
			// 其他情況則取值和分割.然後再遞迴呼叫.
			else {
				String[] strPart = str.split(strCHup[split]);
				return (add(strPart[0]) * midNumber) + excuteCharge(strPart[1]);
			}
		}

	}

	public static long add(String str) {
		// 儲存strCHup裡具體漢字的數字值
		long mid = 0;
		// 儲存strNumup裡具體漢字的數字值
		int number = 0;
		// 儲存傳入字串的最高級別單位在strCHup數組裡的索引.
		int num = -1;
		for (int i = 0; i < strCHup.length; i++) {
			// 取得量級在字串中的索引.
			num = str.indexOf(strCHup[i]);
			// 定義char型變數,儲存每個漢字.便於後面比較
			char ch = ' ';
			// //////////////////////////////////////////////////////////////
			if (num != -1) {

				switch (i) {
				case 0:
					mid = 100000000;
					break;
				case 1:
					mid = 10000;
					break;
				case 2:
					mid = 1000;
					break;
				case 3:
					mid = 100;
					break;
				case 4:
					mid = 10;
					break;
				case 5:
					mid = 1;
					break;
				}

				// 如果以"十"開關的,直接定義number的值.因為在上面能夠找到它的量級.
				if ((str.toCharArray())[0] == '十') {
					number = 1;
				}
				// 否則,取得量級前的數字進行比較,再確定number的值
				else {
					if (0 != num) {
						ch = (str.toCharArray())[num - 1];
					}
				}

				// ////////////////////////////////////////////////////
			}
			// 迴圈結束
			// ////////////////////////////////////////////////////////////////
			// 如果整個字串就一個字,那麼就應該取該值進行比較.而不是再取量級前的數字.
			if (str.length() == 1) {

				ch = (str.toCharArray())[0];
			}
			// 防止幾萬零幾這樣的數.
			else if ((str.length() == 2) && ((str.toCharArray())[0] == '零')) {
				ch = (str.toCharArray())[1];
			}
			switch (ch) {
			case '零':
				number = 0;
				break;
			case '一':
				number = 1;
				break;
			case '二':
				number = 2;
				break;
			case '兩':
				number = 2;
				break;
			case '三':
				number = 3;
				break;
			case '四':
				number = 4;
				break;
			case '五':
				number = 5;
				break;
			case '六':
				number = 6;
				break;
			case '七':
				number = 7;
				break;
			case '八':
				number = 8;
				break;
			case '九':
				number = 9;
				break;
			}
			// ///////////////////////////////////////////////////////////////

			if (num != -1) {
				break;
			}

		}
		if (num == -1) {
			return number;
		}

		String strLeft = str.substring(num + 1);
		return (number * mid) + add(strLeft);
	}
}
最後在Activity中的使用方法:
public class MainActivity extends Activity {
	/**語音識別管理**/
	LSpeechManager manager;
	/**識別內容輸入框**/
	EditText text;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		text = (EditText) findViewById(R.id.editText1);
		manager = new LSpeechManager(this);
		manager.setResultListener(new LSpeechResultListener() {

			@Override
			public void onSuccess(String result) {
				// 識別結束
				text.setText(result);
			}

			@Override
			public void onError(String error) {
				// 識別出現異常
			}

			@Override
			public void onStart() {
				// 識別開始
			}
		});
	}

	public void onClick(View v) {
		int id = v.getId();
		switch (id) {
		case R.id.button1:// 開始識別
			manager.start();
			break;
		}
	}
附上demo:http://download.csdn.net/detail/li352558693/8253035

相關推薦

Android 科大語音識別 金額數字

最近要在應用裡面使用語音識別功能,老闆選擇了科大訊飛的技術,小可也就開始看文件啦; 這裡只嵌入了語音識別,其他的語法什麼的沒有研究,有需要的各位看文件唄; 需要的資料 :只識別數字,若不過濾則把LSpeechManager中的onResult方法中的LDataFormat過

Android 科大語音識別 金額數字

最近要在應用裡面使用語音識別功能,老闆選擇了科大訊飛的技術,小可也就開始看文件啦; 這裡只嵌入了語音識別,其他的語法什麼的沒有研究,有需要的各位看文件唄; 需要的資料 :只識別數字,若不過濾則把LSpeechManager中的onResult方法中的LDataFormat過濾去掉即可 1,首先要在科

unity接科大語音識別Windows平臺(補充前面的文章,添加了錄音功能)

其他操作就不在一一贅述了,直說一下新增的負責錄音的那段程式碼 1、首先利用Microphone類開始錄製和結束錄製音訊 2、利用AudioSource類播放錄製的音訊 3、然後用自己寫的方法Float2Byte將錄製的音訊轉成byte資料,供訊飛語音識別方法呼叫 詳細

Android科大語音按佇列播報

在Android開發中,語音播報經常使用,但是,在使用過程中會發現,如果語音來源過於塊,頻率過高,在前一條沒有播放完的情況下會執行第二條播放,本篇文章用來解決這個問題。 一、科大訊飛語音整合: 1、在科大訊飛的開發者平臺(科大訊飛開放平臺)註冊。我這裡使用的

科大語音識別時字串中特殊字元的處理

比如口算遊戲: 訊飛會返回:請回答[n2]78+11=? 此時我們要去掉[n2] 可做如下操作 String results = "[n2]78+11=?"; results = results.replaceAll("\\[" + "n2" + "\\]", "");

科大語音識別使用過程中踩過的坑

眨眼之間又是好久沒有寫部落格了,佩服那些寫了很多部落格的大神,堅持和耐心值得我學習 這次寫的是一個知名的語音識別sdk,就是科大訊飛的語音識別,其實也沒有多複雜,但是由於我是用swift語言,期間出了很多差錯 ,搞了好久,在這裡就慢慢記錄下來吧。 使用步驟: (有很多步驟

Android 科大語音整合,文字轉語音

前言: 記錄一下科大訊飛的文字轉語音功能的sdk的整合過程,希望能夠幫助到大家。 1. 登入官網,應用註冊。 訊飛開放平臺,進行簡單的開發者註冊。進入個人中心,註冊應用。 註冊完成後,我們可以看到自己的appid。選擇自己要開通的功能,然

科大語音無限制錄音、識別功能的實現:Android studio(一)

            最近想要做一款語音聽寫APP,在網上搜索關於如何使用科大訊飛語音的Demo少之又少,又或者是隻是單純的按照文件來實現簡單的語音聽寫,遠遠不能滿足需求,看了幾天的文件和自己搜尋的一些資料,還有這幾天中遇到的一些問題,覺得有必要做一個筆記,能給初學者一些

Android 科大 線上和離線語音聽寫

效果圖: 參考資料 專案裡要用語音聽寫,想到了科大訊飛,參考上面的資料完成了最簡單的線上有UI的語音識別,後面想要改成離線也可以使用。參考下面的文章 下載好語記和離線資源之後,想要改成有UI的RecognizerDialog離線語音聽寫,但是沒

Android開發之通過藍芽耳機實現語音識別的功能

近階段在開發一款app,實現通過藍芽耳機進行訊飛語音識別,獲取識別結果之後再通過語音合成從藍芽耳機播報出識別結果。上網也查了很多資料,大多是說通過一下兩行程式碼:      mAudioManager.setBluetoothScoOn(true);           

2018 Android 文字轉語音(中文) TextToSpeech+科大語音引擎3.0

最近專案中需要用到文字轉語音。 本來是想使用朗讀女生成的聲音檔案放到專案資源中進行播放。 但是產品要求改成動態的。於是就用了Google為我們封裝好的類TTS,即[TextToSpeech]:大家可以看下詳細文件。 程式碼其實不多,但是寫完之後測試就有問題

android專案接入科大語音評測功能過程

前言 最近專案需要接入語音評測功能,公司有做過這方面的同事推薦了科大訊飛語音評測,於是根據官網的開發指南接入了sdk,可以成功評測使用者的口語能力,並給出合適的分數,但是期間遇到了很多小問題,於是寫在這篇文章記錄一下開發及填坑的過程。 正文 1.接入sdk: 如何接入

【記錄】科大語音控制元件的使用——Android Studio

一、將libs資料夾移至Android Studio的Project的根目錄下 將科大訊飛提供的SDK中的libs資料夾直接拖拽至Android Studio的Project的根目錄下 二、匯入xxx.jar檔案 其實.jar檔案已經存在於

Android開發之聲網即時通訊與語音識別相結合

聲網是一家提供語音、視訊即時通訊服務的公司,他的服務大多基於WebRTC開源專案並進行一些優化和修改。而訊飛語音識別應該不用多說了,老羅在釋出會上介紹得已經夠詳細了。 那麼下面進入今天的主題,就是讓聲網和訊飛識別同時使用,之前可能有朋友沒遇到過這樣的需求,那先說一下讓兩者同

Android整合語音、百度語音、阿里語音識別

一、引言 demo下載地址:https://fir.im/jy28 demo原始碼檢視:https://github.com/

Unity接入語音識別___Android版

Unity版本4.6+Eclipse 1,首先我們先去訊飛開放平臺註冊一個開發者賬號(註冊地址:http://www.xfyun.cn),註冊完成後進入控制檯建立一個新的應用。​ 2,提交成功後我們需要選擇我們需要開通我們需要的服務,​​​點選開

unity接入Android語音

使用工具;Unity+Eclipse(Android) 1.在訊飛語音註冊開發者賬號  ip: http://www.xfyun.cn  然後進入控制檯建立一個新的應用。​   2.點入進去建立新應用,提交成功後我們需要選擇我們需要開通我們需

科大語音雲使用經歷

科大訊飛的語音識別是屬於一流的行列,那不多想當然選擇科大訊飛了。 在百度上輸:訊飛語音 就能找到,輸科大訊飛會直接出現官網,那裡面沒有。(ps我第一次就是這樣) 下載後會有三個檔案選擇。 一個是語音+  帶有語音+APP的。一個是含語音互動介面,一個是不含語音互

ionic載入cordova科大語音輸入法外掛相關問題

1:申請相關appid,見官網,新增語音聽寫服務,下載sdk 2:下載cordova外掛,見https://github.com/Edc-zhang/cordova-plugin-IFlyspeech 3:將sdk的libs資料夾,替換cordova外掛的src/android/libs  將cordo

ubuntu下,在QT中利用科大語音庫實現語音合成TTS

首先要去科大訊飛語音庫註冊,下載linux下的線上合成TTS的SDK,然後在QT下建立一個基於控制檯的工程,其實建立關於UI的也可以,問題不大,這裡以控制檯工程進行說明。將sample中TTS部分的t