본 포스팅에서 네이버 음성인식API를 이용하는데에 필요한 코드는
MainActivity.java, NaverTalkActivity.java, NaverRecognizer.java, AudioWriterPCM.java, activity_main.xml, activity_talk.xml 입니다.
(포스팅에서 다루는 저의 경우이니, 사용하시는 분에 따라서 변경될 수 있겠습니다.)
///////////////////////////////////////////////////////////////////////////////////////////////////
지난 포스팅에 이어 이제 NaverTalkActivity 를 만들어줄 차례입니다. 군데군데 수정만 해주시면 될것입니다.
이전에 다운받았던 SDK로 이동하여,
naverspeech-sdk-android-master\naverspeech-sdk-android-master\sample\NaverspeechClient-android-studio\app\src\main\java\com\naver\naverspeech\client 로 이동하면 아래와 같이 3가지 소스가 있습니다.
( MainActivity의 내용을 조금 수정하여 NaverTalkActivity를 만들어 줄 것입니다. 이 부분은 아래에서! )
우선, utils의 내용은 같으므로, 본인의 안드로이드 스튜디오에서 utils 패키지를 만들어 준 후, AudioWriterPCM.java 를 그대로 옮겨줍니다. 패키지 이름에 계속 신경써줍시다.
그리고, NaverRecognizer.java 또한 같으므로, 그대로 본인의 프로젝트로 옮겨줍니다.
지난 포스팅에서 저는 naverTalk라는 패키지를 하나 만들어서 그 안에 넣어주었으므로 그렇게 따라하시면 됩니다.
(만약, MainActivity와 같은 패키지에 하셔도 상관없지만, 이전 포스팅에서 Manifest에서 activity의 경로는 수정해주셔야 됩니다.)
naverTalk라는 패키지에 이제 NaverTalkActivity.java 를 생성해줍시다.
/////////////////////////////////////////////////////////////////////////////////
[NaverTalkActivity.java]
import java.lang.ref.WeakReference;
import com.naver.naverspeech.client.utils.AudioWriterPCM;
import com.naver.speech.clientapi.SpeechConfig;
//다른 import 또한 추가해주시면 됩니다.
public class MainActivity extends Activity {
private static final String CLIENT_ID = "Your Client ID"; // "내 애플리케이션"에서 Client ID를 확인해서 이곳에 적어주세요.
private static final SpeechConfig SPEECH_CONFIG = SpeechConfig.OPENAPI_KR; // or SpeechConfig.OPENAPI_EN
private RecognitionHandler handler;
private NaverRecognizer naverRecognizer;
private TextView txtResult;
private Button btnStart;
private String mResult;
private AudioWriterPCM writer;
private boolean isRunning;
// Handle speech recognition Messages.
private void handleMessage(Message msg) {
switch (msg.what) {
case R.id.clientReady:
// Now an user can speak.
txtResult.setText("Connected");
writer = new AudioWriterPCM(
Environment.getExternalStorageDirectory().getAbsolutePath() + "/NaverSpeechTest");
writer.open("Test");
break;
case R.id.audioRecording:
writer.write((short[]) msg.obj);
break;
case R.id.partialResult:
// Extract obj property typed with String.
mResult = (String) (msg.obj);
txtResult.setText(mResult);
break;
case R.id.finalResult:
// Extract obj property typed with String array.
// The first element is recognition result for speech.
String[] results = (String[]) msg.obj;
mResult = results[0];
txtResult.setText(mResult);
break;
case R.id.recognitionError:
if (writer != null) {
writer.close();
}
mResult = "Error code : " + msg.obj.toString();
txtResult.setText(mResult);
btnStart.setText(R.string.str_start);
btnStart.setEnabled(true);
isRunning = false;
break;
case R.id.clientInactive:
if (writer != null) {
writer.close();
}
btnStart.setText(R.string.str_start);
btnStart.setEnabled(true);
isRunning = false;
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_talk);
txtResult = (TextView) findViewById(R.id.txt_result);
btnStart = (Button) findViewById(R.id.btn_start);
handler = new RecognitionHandler(this);
naverRecognizer = new NaverRecognizer(this, handler, CLIENT_ID, SPEECH_CONFIG);
btnStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!isRunning) {
// Start button is pushed when SpeechRecognizer's state is inactive.
// Run SpeechRecongizer by calling recognize().
mResult = "";
txtResult.setText("Connecting...");
btnStart.setText(R.string.str_listening);
isRunning = true;
naverRecognizer.recognize();
} else {
// This flow is occurred by pushing start button again
// when SpeechRecognizer is running.
// Because it means that a user wants to cancel speech
// recognition commonly, so call stop().
btnStart.setEnabled(false);
naverRecognizer.getSpeechRecognizer().stop();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
// initialize() must be called on resume time.
naverRecognizer.getSpeechRecognizer().initialize();
mResult = "";
txtResult.setText("");
btnStart.setText(R.string.str_start);
btnStart.setEnabled(true);
}
@Override
protected void onPause() {
super.onPause();
// release() must be called on pause time.
naverRecognizer.getSpeechRecognizer().stopImmediately();
naverRecognizer.getSpeechRecognizer().release();
isRunning = false;
}
// Declare handler for handling SpeechRecognizer thread's Messages.
static class RecognitionHandler extends Handler {
private final WeakReference<MainActivity> mActivity;
RecognitionHandler(MainActivity activity) {
mActivity = new WeakReference<MainActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = mActivity.get();
if (activity != null) {
activity.handleMessage(msg);
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////
위에서, NaverTalkActivity.java를 만들어주었다면. 이제 onCreate에서 해당 레이아웃을 꾸며주어 버튼을 클릭했을 때에, 음성인식을 받도록 기능을 구현하게 합니다.
activity_talk.xml의 소스는 간단합니다. 클릭할 버튼 하나와, 음성인식한 텍스트를 보여줄 TextView 하나만 있으면 됩니다.
[activity_talk.xml]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.naver.recognition.client.MainActivity" >
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@string/str_start" />
<TextView
android:id="@+id/txt_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn_start"
android:layout_centerHorizontal="true"
android:singleLine="false" />
</LinearLayout>
/////////////////////////////////////////////////////////////////////////////////
그리고, 이제 본 애플리케이션의 MainActivity와 activity_main.xml 을 꾸며봅시다!
MainActivity에서 임의의 버튼을 클릭했을 때, NaverTalkActivity로 넘어가도록 할 것입니다.
[activity_main.xml]
기본으로 생성되어져 있는 레이아웃 안에 button만 하나 추가해줍시다.
<Button
android:id="@+id/btn_voice"
android:drawableLeft="@android:drawable/ic_btn_speak_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textSize="10dp"
android:text="음성 제어">
</Button>
/////////////////////////////////////////////////////////////////////////////////
[MainActivity.java]
public class MainActivity extends Activity {
private Button voiceBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
voiceBtn = (Button)findViewById(R.id.btn_voice);
voiceBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, NaverTalkActivity.class);
startActivity(intent);
}
});
}
}
이와 같이 MainActivity.java 를 구성하게 되면 마무리 되어집니다.
간단하게 보이고자 레이아웃을 매우 간단하게 꾸몄으니, 차후 레이아웃 디자인은 각자 예쁘게 꾸미시면 되겠습니다.
사실 네이버 음성인식API에 대한 부분은 워낙 코드도 간단하고 쉬운데다 가이드도 이해하기 쉽게 되어있어서 그대로 따라하셔도 초보자라도 30분~1시간이면 바로 테스트해볼 수 있으실 겁니다.