안드로이드에서 음성인식 기능을 구현하기 위해서는 구글의 Speech-To-Text(이하 STT)기능을 사용하면 됩니다. SST기능을 사용하는 방법은 2가지가 있습니다. 구글에서 지원하는 UI를 사용하거나, 나만의 커스텀 UI를 만드는 방법이 있습니다. 이 두가지 방법을 사용하는 예제는 인터넷에서 충분히 구할 수 있으나 이 두가지 방법은 제 맘에 드는 방법이 아니었습니다.

 저는 현재 음성녹음 시작과 함께 음성인식(STT)이 가능한 앱을 개발해야 했는데, 저 두가지 방법은 액티비티 전환이 필요하기 때문에 액티비티 전환 없이 음성인식을 하도록 만들어 보았습니다. 음성녹음의 경우 어렵지 않게 예제를 보고 구현할 수 있기 때문에 음성녹음 시작시 액티비티 전환 없이 음성인식을 하는 기능만 구현하면 되겠거니 생각해서 만들어 보았습니다.


액티비티(Activity)전환 없이 음성인식(구글 STT) 사용하기

 일단 프로젝트를 하나 생성한다. 그리고 가장 처음에 퍼미션부터 등록하도록 하겠다. 이 부분은 자칫하면 깜빡하고 넘어가기 쉽기 때문에(글쓴이 같은 경우..) 가장 먼저 등록을 해놓고 시작하겠다.

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

 소리를 입력받기 위해 RECORD_AUDIO 권한이 필요하고, 음성인식을 하기위해 인터넷에 접속해야 하기 떄문에 INTERNET 권한이 필요하다.

 음성 인식 시작을 위한 버튼하나정도는 필요할 것이다. 버튼 하나와 결과를 출력할 텍스트뷰를 만들어준다.

 그리고 액티비티가 최초 생성될 때 onCreate시 음성인식을 위한 준비를 한다.

 MainActivity.java

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		i = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
		i.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getPackageName());
		i.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "ko-KR");
	}

i는 전역변수로 설정해주었다. (Intent i)
마지막 줄인 EXTRA_LANGUAGE는 인식할 언어를 설정해주는 코드이다. 글쓴이는 한글을 인식하였다. 영어를 인식하기 위해서는 "ko-KR" 대신 "en-US"를 써주면 된다.

("ko-KR"로 설정해도 abc라고 발음했을 경우 "에이비씨" 보다 "abc"로 나오는 경우가 많은것 같다.)

다음은 버튼 클릭시 작동하는 코드이다.

MainActivity.java

			mRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
			mRecognizer.setRecognitionListener(listener);
			mRecognizer.startListening(i);

mRecognizer역시 전역변수로 설정 해 주었다. (SpeechRecognizer mRecognizer)
위의 두줄은 onCreate에 넣어줘도 상관은 없을것 같다. 마지막 줄은 음성인식 리스너를 불러오기 때문에 버튼 클릭시 실행하도록 한다.

다음은 리스너를 작성하자. 몇줄만 넣으면 자동완성으로 리스너 안의 메소드가 작성된다.

MainActivity.java

private RecognitionListener listener = new RecognitionListener() {
		
		@Override
		public void onRmsChanged(float rmsdB) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onResults(Bundle results) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onReadyForSpeech(Bundle params) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onPartialResults(Bundle partialResults) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onEvent(int eventType, Bundle params) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onError(int error) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onEndOfSpeech() {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onBufferReceived(byte[] buffer) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onBeginningOfSpeech() {
			// TODO Auto-generated method stub
			
		}
	};

각 메소드의 이름만 보면 언제 동작할 것인지 이해할것이라 생각하고 음성인식 결과를 텍스트로 출력하는 부분만 작성하겠다. 

참고로 onRmsChanged 메소드는 입력받는 소리의 크기를 나타내주는데, 소리 크기값인 rmsDb는 디폴트 값이 -2 또는 -2.12 인거 같다. 한번 음성입력을 받고 일정 시간동안 입력이 없으면(rmsDb값이 -2 또는 -2.12일 때) 자동으로 종료되는듯 하다.

음성인식 결과는 onResult 메소드에서 얻을 수 있다.

MainActivity.java

@Override
public void onResults(Bundle results) {
	String key = "";
	key = SpeechRecognizer.RESULTS_RECOGNITION;
	ArrayList<String> mResult = results.getStringArrayList(key);
	String[] rs = new String[mResult.size()];
	mResult.toArray(rs);
	tv.setText(""+rs[0]);		
}

tv는 텍스트뷰이다. tv역시 전역변수로 설정하였다.(TextView tv)
results라는 결과값을 mResult라는 ArrayList에 저장한다. 
rs라는 String배열을 만들어 mResult의 크기만큼 배열을 초기화 하고 그 rs라는 배열에 mResult값을 넣는다.
for루프를 돌려서 인식한 결과값을 모두 볼 수도 있고, rs[0]으로 첫번째 나온 값만 받을수 있다.

액티비티 전환없이 음성인식을해서 결과를 받아왔다. 음성인식 시작코드만 음성녹음 시작시에 실행하도록 하면 음성녹음과 동시에 음성인식을 할 수 있을것 같다. 추가적으로 입맛에 맞게 코드 수정도 자유롭게 할 수 있을것 같다.



제가 설명이 부족한 부분이 있을텐데 댓글로 질문해주시면 감사하겠습니다.


+ Recent posts