안드로이드 카카오 음성 API - andeuloideu kakao eumseong API

October 10, 2019 13 min to read

안드로이드 카카오 음성 API - andeuloideu kakao eumseong API

★ 이 글은 2019년 한양대학교 컴퓨터동아리 HUHS에서 제가 진행한 안드로이드 멘토링 수업 내용을 정리한 것입니다. 스터디를 진행하면서 설명이 부족했던 부분을 정리하고, 그와 동시에 당시 스터디에 참여하지 못했던 분들을 위해 정리한 것입니다. 당시 스터디가 좀 길었던 관계로, 일부 내용을 자르고 짧게 편집한 부분이 있습니다.

★ 이 스터디에서 활용한 발표 자료를 첨부하겠습니다. 발표 자료에 있는 내용은 따로 블로그 글에 담지 않았으니, 꼭 발표 자료도 같이 봐주시면 감사하겠습니다.
발표 자료 다운받기

새 프로젝트 생성하고 설정하기

  ‘Start a new Android Studio project’를 선택합니다.   그대로 ‘Next’를 누릅니다.   Name(앱 이름)은 ‘voiceapp’으로, Language(프로그래밍 언어)는 ‘Java’로 바꾼 뒤 Finish를 누릅니다. 기본 언어가 Kotlin으로 되어 있기 때문에 Java로 바꿔줘야 합니다!   프로젝트가 빌드될 때까지 잠시 기다립니다. 아래쪽 Sync에서 모든 로딩이 끝나야 합니다. 생각보다 오래 걸릴 수도 있으니 느긋하게 기다리시면 됩니다.   빌드가 끝나면, 아래처럼 MainActivity.java가 표시됩니다.

  우선, Manifest를 설정해 줍시다. Manifest는 권한을 포함한 앱에 대한 필수 정보들을 담고 있는 파일입니다. 다음과 같은 사항들을 Manifest에서 설정할 수 있습니다.

  • 앱이 요구하는 권한 (인터넷, 블루투스, 마이크, 외부 저장소, 카메라 등등)
  • 앱의 테마 및 전체적인 디자인
  • 앱에서 사용되는 라이브러리에 관한 정보
  • 기타 앱 실행 시 필요한 요소들

  왼쪽 메뉴에서 ‘manifests’ 폴더를 더블클릭해 Manifest 파일을 엽니다.

  그리고, 3번째 줄인 'package="com.candykick.voiceapp">'와 그 아래의 '<application' 사이에 아래 코드를 입력합니다.

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

  소스코드 맨 위부터 설명드리면 다음과 같습니다.

  • <uses-permission ~~~ .INTERNET”/> : 인터넷 권한. 이게 있어야 앱에서 인터넷을 연결할 수 있습니다.
  • <uses-permission ~~~ .ACCESS_NETWORK_STATE”/> : 네트워크 연결 상태를 얻는 권한. 보통 인터넷 권한과 같이 쓰입니다.
  • <uses-permission ~~~ .BLUETOOTH”/> : 블루투스 권한. 카카오 음성합성 API에서 기본으로 요구한다고 하는데, 이유는 잘 모르겠습니다. 이거 없으면 작동을 안 하더라고요.
  • <uses-permission ~~~ .RECORD_AUDIO”/> : 마이크 권한. 카카오 음성인식 API에서 쓰는 건데, 음성합성 API에서도 마이크를 쓰지 않아도 동일하게 요구합니다. 역시 이 권한이 없으면 작동을 하지 않습니다.

  권한을 추가했으면, 카카오 개발자 홈페이지에 접속해서 내 앱을 등록하고 관련 정보들을 입력해야 합니다.
우선 카카오 개발자 페이지에 접속해서 로그인합니다. 로그인하면 아래와 같은 화면이 나올 겁니다.   여기서 왼쪽 위의 ‘앱 만들기’를 클릭합니다. 그리고 앱 이름을 적당히 입력하고 회사명은 자기 닉네임을 적어넣은 뒤 확인을 누릅니다. 저는 앱 이름은 voiceapp으로, 회사명은 제 닉네임은 candykick으로 입력하겠습니다.   앱 아이콘을 등록해달라는 메세지가 나올 텐데요, ‘계속 진행’을 누릅니다.   그러면 애플리케이션이 생성되었다는 창이 나올 겁니다. 여기서 왼쪽 ‘설정’의 ‘일반’을 클릭합니다.   플랫폼 추가를 누릅니다.   플랫폼 추가에서 Android를 선택합니다. 이후, 패키지명을 입력하라고 나올 겁니다. 패키지명은 어디에 있을까요?
아까 켜 둔 Manifest 파일에서 3번째 줄을 보면 'package="com.candykick.voiceapp"' 부분이 보일 겁니다. 아마 여러분들은 ‘package=’ 뒤의 부분이 다를 텐데요, 이 ‘package=’뒤의 부분이 패키지 이름입니다. 여기서는 com.candykick.voiceapp이 되겠죠. 여러분 프로젝트의 Manifest에서 패키지명을 알맞게 찾아서 입력합니다. 그러면 마켓 URL이 자동으로 추가될 겁니다. 모든 정보가 입력되었으면 추가 버튼을 누릅니다.   그리고 해야 할 일이 하나 남았습니다. 키 해시를 입력하는 과정입니다.
안드로이드 스튜디오에서는 앱을 빌드할 때 개발자나 회사를 가리키는 특정한 파일로 앱에 서명을 합니다. 이러한 서명을 통해 누가 앱을 만들었고, 이 앱에 대한 책임이 누구한테 있는지를 표시합니다. 카카오 API를 포함한 상당수의 API와 라이브러리들 또한 개발자들이 앱을 등록할 때 이러한 서명을 같이 제출하도록 요구하는데요, 그 서명의 역할을 하는 게 키 해시라고 볼 수 있습니다.
키 해시를 얻는 과정은 초보자에겐 조금 복잡할 수 있습니다. 일단, 안드로이드 스튜디오 좌측의 메뉴에서 MainActivity를 더블클릭해서 엽니다.   여기서 맨 아래의 ‘}’ 바로 위에 아래의 소스코드를 그대로 입력합니다.

private void getAppKeyHash() { try { PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES); for (Signature signature : info.signatures) { MessageDigest md; md = MessageDigest.getInstance("SHA"); md.update(signature.toByteArray()); String something = new String(Base64.encode(md.digest(), 0)); Log.e("Hash key", something); } } catch (Exception e) { // TODO Auto-generated catch block Log.e("name not found", e.toString()); } }

  그리고 setContentView(R.layout.activity_main); 바로 아래에 아래의 소스코드를 입력합니다.

  전부 붙여넣으면 아래와 같이 됩니다. 어디에 각 코드를 넣어야 할지 헷갈리신다면, 아래 사진을 참고해서 붙여넣으시면 됩니다.   붙여넣기했을 때 아래와 같이 나온다면, ‘OK’를 눌러서 전부 붙여넣기합니다.   이 상태에서 본인의 핸드폰을 연결하거나 에뮬레이터를 실행한 후, 실행한 기기를 선택하고 재생 버튼을 눌러서 앱을 실행합니다.   아랫쪽에 로딩바가 나올 텐데요, 이 상태에서 조금 기다리면 앱이 실행됩니다. ‘Hello World!’하고 화면이 인사를 하죠.   여기서, 핸드폰이 아닌 노트북(혹은 컴퓨터)로 돌아옵니다. 안드로이드 스튜디오의 아랫쪽에 보시면 Logcat이란 버튼이 있을 텐데요, 이 버튼을 누릅니다.   그러면 무슨 텍스트가 잔뜩 적힌 창이 나올 겁니다. Logcat은 안드로이드 앱이 실행될 때 발생하는 여러 동작들과 오류들을 기록해놓은 공간으로, 앱이 실행되고 터치나 화면 전환 등의 이벤트가 발생될 때마다 실시간으로 그 상태를 반영해서 새 메세지를 보여주는 곳입니다.   여기서 검색창에 ‘Hash’라고 검색합니다. 그럼 빨간 글씨로 무언가 나올 겁니다. E/Hash key: **************************** 이렇게 나올 텐데요, 여기서 E/Hash key: 뒤의 글씨를 복사합니다.   카카오 개발자 페이지로 돌아가서, 왼쪽 메뉴의 ‘설정’의 ‘일반’을 다시 클릭합니다. 그리고 가운데 플랫폼 밑에 Android를 누르면 아까 입력한 패키지명과 마켓 URL, 그리고 키 해시를 입력하는 곳이 나올 겁니다. ‘키 해시’에 아까 복사한 빨간 글자를 붙여넣기합니다. 그리고 저장을 누릅니다.   마지막으로, 카카오 음성 API를 켜야 합니다. 켜 주지 않으면 작동을 하지 않죠. 왼쪽 메뉴의 ‘설정’에서 ‘음성’을 클릭합니다.   음성이 OFF되어 있죠? 스위치를 클릭해서 ON으로 바꾸고, 사용 목적을 입력한 뒤 저장을 누릅니다. 사용 목적은 ‘음성 인식 및 합성 기반의 앱 개발’로 적어주시면 됩니다.   이 설정이 끝나면, 다시 ‘설정’의 ‘일반’으로 이동합니다.   맨 위에 ‘앱 키’ 밑의 ‘네이티브 앱 키’가 보이시죠? 이걸 복사합니다.   복사한 키를 Manifest의 application 태그 안에 복사합니다. 위치가 헷갈리신다면 사진을 참고해주세요!

<meta-data android:name="com.kakao.sdk.AppKey" android:value="복사한 네이티브 앱 키" />

  여기까지 해서, 모든 설정이 끝났습니다! 이젠 직접 앱을 만들러 가 봅시다!

음성인식/합성 API 등록하기

  카카오 음성인식/합성 API를 사용하려면, 각 API를 내 프로젝트에 추가해야 합니다. API 및 라이브러리는 gradle 파일에서 추가할 수 있습니다.
안드로이드 스튜디오로 돌아와서, 왼쪽 메뉴의 ‘Gradle Scripts’를 누르고 ‘build.gradle (Project: voiceapp)’을 클릭합니다.   여기서 아래의 두 줄을 allprojects의 repositories 안에 있는 jcenter() 밑에 추가합니다. 정확한 위치는 소스코드 아래의 사진을 참고해주세요.

mavenCentral() maven { url 'http://devrepo.kakao.com:8088/nexus/content/groups/public/' }

  그 다음, 왼쪽 메뉴의 ‘Gradle Scripts’를 누르고 ‘build.gradle (Module: app)’을 클릭합니다.   그리고 아래의 dependencies 안쪽의 맨 아랫쪽에 아래의 한 줄을 추가합니다. 정확한 위치는 소스코드 아래의 사진을 참고해주세요.

implementation 'com.kakao.sdk:newtone:6.0.1'

  추가가 되었으면 위쪽의 ‘Gradle files have changed since ~~~~’라고 적힌 부분이 있을 겁니다. 이 텍스트 끝의 ‘Sync Now’를 클릭합니다.   프로젝트가 다시 빌드될 겁니다. 모든 빌드가 끝날 때까지 기다립니다.   이렇게 해서 카카오 음성인식/합성 API를 내 프로젝트에 추가했습니다. 이제 소스코드를 짜 봅시다!

레이아웃 구성하기

※ HUHS에서 진행한 수업에서는 안드로이드 기초를 같이 알려주다 보니, 버튼 입력이나 가장 기초적인 텍스트뷰 사용법, 레이아웃 배치 등을 짧게나마 소개하고 넘어갔었습니다. 다만 여기서까지 해당 내용을 소개하면 글이 너무 길어지고, 중구난방이 될 우려가 있어서 해당 내용을 잘랐습니다. 이 글에서는 카카오 음성합성 API 사용법에만 초점을 맞추도록 하겠습니다.

  안드로이드 스튜디오 왼쪽 메뉴의 res 폴더를 누르고 layout 폴더에 들어간 뒤 activity_main.xml을 더블클릭해서 엽니다.   입력창 하나, 버튼 하나로 이루어진 화면을 구성해 보겠습니다. 입력창에서 텍스트를 입력하고 버튼을 누르면 입력한 대로 읽게 할 것입니다.
입력창은 EditText, 버튼은 Button이란 이름을 쓰고 있습니다. 우선 버튼을 화면 가운데 아랫부분에 추가해 보겠습니다.
가운데 View들이 모여 있는 공간에서 Button을 선택합니다.   Button을 선택하고 흰색 화면의 아랫쪽 가운데로 드래그합니다.   일단 버튼 하나가 추가되었습니다. 이 버튼의 텍스트를 바꿔보겠습니다. 버튼이 선택된 상태에서 오른쪽 중간에 보시면 Common Attributes가 있을 겁니다. 이 아래에 text란 속성이 있는데요, 이 속성이 버튼에 적힌 텍스트입니다. 이 부분을 ‘읽기’로 고칩니다.   그리고 버튼의 위치도 한 번 잡아보겠습니다. 버튼이 선택된 상태에서 오른쪽 위에 보시면 네모가 그려져 있고, 사방에 + 버튼이 달려 있는 게 있습니다. 이 부분에서 버튼의 위치 밑 크기를 지정합니다. 우리는 버튼을 아랫쪽 가운데에 둘 예정이죠. 네모칸 왼쪽, 오른쪽, 아랫쪽의 + 버튼을 각각 클릭합니다.   그리고 바로 아래의 layout_width를 누르고 wrap_content를 match_constraint로 바꿉니다. 그러면 자동으로 0dp라는 글자가 들어갈 겁니다.   마지막으로, 좌우 간격이 다르게 설정되어 있는지 확인합니다. 저의 경우 좌우 양쪽을 100으로 설정했습니다.

  비슷한 방식으로, 입력창인 EditText를 추가해 보겠습니다. 가운데의 View가 모여 있는 공간에서 ‘Text’ -> ‘Plain Text’를 차례대로 클릭합니다.
그 후, Plain Text를 화면 위쪽 가운데로 드래그합니다.   버튼과 비슷하게 오른쪽의 네모칸이 있는 부분에서 네모칸 왼쪽, 오른쪽, 위쪽의 + 버튼을 각각 클릭합니다. 이번엔 위쪽을 기준으로 정렬할 것이므로 아래가 아닌 위를 누르시면 됩니다.
그리고 아까처럼 바로 아래의 layout_width를 누르고 wrap_content를 match_constraint로 바꿉니다. 그러면 자동으로 0dp라는 글자가 들어갈 겁니다.
만약 좌우 간격이 다르다면 좌우 간격을 똑같이 맞춥니다. 저는 왼쪽 102, 오른쪽 96으로 간격이 다르기 때문에 양쪽 다 96으로 바꿨습니다.   마지막으로, 가운데의 ‘Hello World!’라 적힌 글자를 클릭해서 지워줍니다.

자바 소스코드 짜기

  이제 자바 소스코드를 짜 봅시다.
오른쪽의 메뉴에서 java 폴더를 누르고, java 폴더를 누르면 나오는 목록 중 맨 위의 패키지명으로 된 폴더를 누른 뒤, MainActivity를 더블클릭해서 MainActivity.java 파일을 엽니다.   전체 소스코드를 먼저 올리고, 세부사항을 따로따로 설명하겠습니다. 전체 소스코드는 아래와 같습니다.

  우선, 카카오 음성합성 API는 TextToSpeechClient라는 객체를 통해서 실행됩니다. 이 객체에 해 줘야 할 일은 다음과 같습니다.

  • 초기화
  • 객체 설정
  • 오류 처리
  • 텍스트를 넣고 실행
  • 앱 종료 시 처리(정확히는 현재 화면, Activity 종료 시 처리)

  일단 TextToSpeechClient를 선언합니다. 이름은 ttsClient로 했습니다.

private TextToSpeechClient ttsClient;

  이후, onCreate 안에서 ttsClient를 초기화했습니다.

//음성인식 초기화 SpeechRecognizerManager.getInstance().initializeLibrary(this); TextToSpeechManager.getInstance().initializeLibrary(this);

  그리고 아까 레이아웃에서 선언한 Button과 EditText를 자바 파일과 연결시킵니다. Button과 EditText를 딱히 바꾸거나 여러 번 생성하지 않았다면, Button의 id값은 button이고 EditText의 id값은 editText일 겁니다.

Button button = findViewById(R.id.button); final EditText editText = findViewById(R.id.editText);

  이후 버튼을 클릭할 때 동작을 서술합니다. 버튼에 onClick 리스너를 붙여 주면 버튼이 클릭될 때 일을 시킬 수 있습니다. 버튼에 리스너를 붙이는 코드는 원래 다음과 같습니다.

button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //버튼이 클릭되었을 때 작업 } });

  여기서는 버튼이 클릭될 때 EditText에서 입력된 텍스트를 가져와서 그대로 말을 시켜야 하죠.
우선은 ttsClient를 초기화했으니 읽는 방식이나 속도, 목소리 등을 설정해줘야 합니다. 아래의 소스코드로 이 방식을 설정합니다.

TextToSpeechClient.Builder builder = new TextToSpeechClient.Builder(); builder.setSpeechMode(TextToSpeechClient.NEWTONE_TALK_1); builder.setSpeechSpeed(2.5); builder.setSpeechVoice(TextToSpeechClient.VOICE_MAN_READ_CALM); builder.setListener(ttsListener);

  위의 소스코드에서 2번째 줄부터 각각 읽는 방식, 읽는 속도, 목소리, 오류 처리를 지정하는 부분입니다. 이 부분에 대한 설명은 맨 위에 첨부한 PDF에 있으니 참고 바랍니다. 발표 자료 다운받기

  설정이 끝났으면, 이 설정을 ttsClient에 적용합니다.

ttsClient = builder.build();

  그리고 EditText에서 텍스트를 가져와서(editText.getText().toString()) ttsClient를 통해 텍스트를 읽습니다.

ttsClient.play(editText.getText().toString());

  위의 버튼 onClick 리스너부터 텍스트를 읽는 부분까지 전부 합치면 아래의 코드가 되는 것이죠.

button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { TextToSpeechClient.Builder builder = new TextToSpeechClient.Builder(); builder.setSpeechMode(TextToSpeechClient.NEWTONE_TALK_1); builder.setSpeechSpeed(2.5); builder.setSpeechVoice(TextToSpeechClient.VOICE_MAN_READ_CALM); builder.setListener(ttsListener); ttsClient = builder.build(); ttsClient.play(editText.getText().toString()); } });

  그렇다면, ttsListener는 어디에 있을까요? 바로 아래의 코드에 있습니다. 이 부분은 ttsClient가 오류가 났을 때, 즉 카카오 음성합성 API에서 오류가 발생했을 때 어떤 동작을 할 것인지를 기술하는 부분입니다. 여기서는 해당 부분을 텅 비워서 오류가 발생하면 아무것도 하지 않도록 처리했습니다만, 실제로는 토스트 메세지를 넣어서 오류가 발생했다고 알려 주는 경우가 대부분입니다.

private TextToSpeechListener ttsListener = new TextToSpeechListener() { @Override public void onFinished() { } @Override public void onError(int code, String message) { } };

  마지막으로, 앱이 종료될 때, 정확히는 현재 화면인 MainActivity가 종료될 때 ttsClient를 꺼 주는 작업을 해야 합니다. 이 작업은 아래 소스코드에서 담당합니다.

@Override public void onDestroy() { super.onDestroy(); TextToSpeechManager.getInstance().finalizeLibrary(); SpeechRecognizerManager.getInstance().finalizeLibrary(); }

  이대로 친 뒤 실행해볼까요? 실행하면 아래 화면처럼 나옵니다.   텍스트를 넣고 읽기 버튼을 누르면 입력한 그대로 읽어줍니다!

  이번 강의에서는 카카오 음성합성 API를 활용한 기본적인 앱을 만들어봤습니다. 다음 시간엔 카카오 음성인식 API로 네이버 검색을 하는 앱을 만들어 보겠습니다.