마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 스튜디오 음성인식 질문있습니다.

0 추천

안녕하세요 최근에 안드로이드 스튜디오에 빠져 공부를 하고 있습니다

다름이 아니라 

 

MainActivity에 이렇게 넣고

매니피스트에도 인터넷과 레코드오디오 펄미션을 추가하였음에도 불구하고 

디버깅 후 어플 실행해서 버튼을 누르면 오디오 에러 라는창만 뜹니다.. 

어떻게하면 해결을 할수 있을가요 ?

디바이스는 픽셀2 api 29 / 안드로이드 10 입니다.

package com.example.test;

import android.Manifest;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import java.util.ArrayList;


public class MainActivity extends AppCompatActivity {
    TextView textView;
    Button button;
    Intent intent;
    SpeechRecognizer mRecognizer;
    final int PERMISSION = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 안드로이드 6.0버전 이상인지 체크해서 퍼미션 체크
        if(Build.VERSION.SDK_INT >= 23){
            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.INTERNET,
                    Manifest.permission.RECORD_AUDIO},PERMISSION);
        }

        textView = findViewById(R.id.textView);
        button = findViewById(R.id.button);

        // RecognizerIntent 생성
        intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,getPackageName()); // 여분의 키
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,"ko-KR"); // 언어 설정

        // 버튼 클릭 시 객체에 Context와 listener를 할당
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mRecognizer = SpeechRecognizer.createSpeechRecognizer(MainActivity.this); // 새 SpeechRecognizer 를 만드는 팩토리 메서드
                mRecognizer.setRecognitionListener(listener); // 리스너 설정
                mRecognizer.startListening(intent); // 듣기 시작
            }
        });
    }

    private RecognitionListener listener = new RecognitionListener() {
        @Override
        public void onReadyForSpeech(Bundle params) {
            // 말하기 시작할 준비가되면 호출
            Toast.makeText(getApplicationContext(),"음성인식 시작",Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onBeginningOfSpeech() {
            // 말하기 시작했을 때 호출
        }

        @Override
        public void onRmsChanged(float rmsdB) {
            // 입력받는 소리의 크기를 알려줌
        }

        @Override
        public void onBufferReceived(byte[] buffer) {
            // 말을 시작하고 인식이 된 단어를 buffer에 담음
        }

        @Override
        public void onEndOfSpeech() {
            // 말하기를 중지하면 호출
        }

        @Override
        public void onError(int error) {
            // 네트워크 또는 인식 오류가 발생했을 때 호출
            String message;

            switch (error) {
                case SpeechRecognizer.ERROR_AUDIO:
                    message = "오디오 에러";
                    break;
                case SpeechRecognizer.ERROR_CLIENT:
                    message = "클라이언트 에러";
                    break;
                case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
                    message = "퍼미션 없음";
                    break;
                case SpeechRecognizer.ERROR_NETWORK:
                    message = "네트워크 에러";
                    break;
                case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
                    message = "네트웍 타임아웃";
                    break;
                case SpeechRecognizer.ERROR_NO_MATCH:
                    message = "찾을 수 없음";
                    break;
                case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
                    message = "RECOGNIZER 가 바쁨";
                    break;
                case SpeechRecognizer.ERROR_SERVER:
                    message = "서버가 이상함";
                    break;
                case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
                    message = "말하는 시간초과";
                    break;
                default:
                    message = "알 수 없는 오류임";
                    break;
            }

            Toast.makeText(getApplicationContext(), "에러 발생 : " + message,Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onResults(Bundle results) {
            // 인식 결과가 준비되면 호출
            // 말을 하면 ArrayList에 단어를 넣고 textView에 단어를 이어줌
            ArrayList<String> matches =
                    results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

            for(int i = 0; i < matches.size() ; i++){
                textView.setText(matches.get(i));
            }
        }

        @Override
        public void onPartialResults(Bundle partialResults) {
            // 부분 인식 결과를 사용할 수 있을 때 호출
        }

        @Override
        public void onEvent(int eventType, Bundle params) {
            // 향후 이벤트를 추가하기 위해 예약
        }
    };
}

 

gimbap2 (170 포인트) 님이 3월 13일 질문

1개의 답변

0 추천
 
채택된 답변

권한처리 코드가 완료되지 않았네요. Internet 퍼미션은 AndroidManifest.xml 에 명시만 하면 되고 런타임 퍼미션은 아닙니다. 그리고 퍼미션은 먼저 권한 유무를 확인한 후, 없으면 요청을 하셔야 하고 onPermissionResult 콜백을 통해 요청결과를 처리해 주어야 합니다. (onPermissionResult 콜백은 launcher API로 대체되어 deprecated 되었을 겁니다.)

public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
     
    private TextView textView;
    private Button button;
    private SpeechRecognizer mRecognizer;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        textView = findViewById(R.id.textView);
        button = findViewById(R.id.button);
 
        // 버튼 클릭 시 객체에 Context와 listener를 할당
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                processPermissonOrStartSpeechRecognizer();
            }
        });
    }

    private void processPermissonOrStartSpeechRecognizer()  {
        boolean runtimPermssionRequired = Build.VERSION.SDK_INT >= 23;
        boolean permissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; 

        if (runtimPermssionRequired && !permissionGranted) {
            requestAudioRecordPermission();
            return;
        }

        startSpeechRecognizer();
    }

    private void requestAudioRecordPermission() {
          ActivityCompat.requestPermissions(this, {Manifest.permission.RECORD_AUDIO}, REQUEST_RECORD_AUDIO_PERMISSION);      
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode != REQUEST_RECORD_AUDIO_PERMISSION) return;

        boolean recordAudioPermissonAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
        if (recordAudioPermissonAccepted) {
            startSpeechRecognizer();
        }
    }

    private void startSpeechRecognizer() {
        mRecognizer = SpeechRecognizer.createSpeechRecognizer(MainActivity.this); 
        mRecognizer.setRecognitionListener(listener); // 리스너 설정
        
        // RecognizerIntent 생성
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getPackageName()); 
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "ko-KR"); 
     
        // 듣기 시작
        mRecognizer.startListening(intent); 
    }

    ...

}

 

spark (202,300 포인트) 님이 3월 13일 답변
gimbap2님이 3월 14일 채택됨
안녕하세요 . 이걸본후 따라해서 디버깅하였음에도불구하고 작동을 안하네요 ㅠㅠ뭐가문제인지 모르겠습니다... 계속 오디오에러만 뜨면서 아무작동도 안합니다
AndroidManifest.xml에도 해당 권한 설정을 하셨죠?
문제가 있으면 logcat에서 메세지를 확인하시고 의심가는 곳에 브레이크 포인트를 걸어서 디버깅을 해보세요.
답변 감사합니다 원인을 찾아서 해결하긴했는데 에뮬로 실행하면 오류가 계속뜨고 집에 남는 태블릿으로 실행해보니 정상작동합니다 .
  com....android.googlequicksearchbox  E  onError
                                                                                                    com.google.android.apps.gsa.shared.speech.a.m: errorCode: 65561, engine: 2

loacat 에서는 이런오류가 발생하네요ㅠㅠ
애뮬레이터는 실제 디바이스가 아니라 오디오 같은 하드웨어가 실제 디바이스랑 다르게 동작해요.
...