Android игнорирует разрешение RECORD_AUDIO и реализацию Speech API

Я пытаюсь заставить Speech Recognition работать на моем приложении для Android 2.3.3, но чего-то фундаментального не хватает.

Во-первых, наверху моего AndroidManifest.xml файл у меня есть:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myuser.myapp">
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"

        ... remainder omitted for brevity

Как я полагаю, это должно побудить Android спросить конечного пользователя, желают ли они предоставить разрешение моему приложению на микрофон при запуске (если нет, пожалуйста, исправьте меня!)...

Далее у меня есть Activity который содержит всю потребность в возможностях распознавания речи моего приложения. По сути, я хочу, чтобы приложение обнаруживало всякий раз, когда кто-то говорит вслух "Go":

public class SpeechActivity extends AppCompatActivity implements RecognitionListener {
    private SpeechRecognizer speechRecognizer;

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

        int check = ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO);
        if(check != PackageManager.PERMISSION_GRANTED) {
            throw new RuntimeException("Ya can't do that now, ya here.");
        }

        speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
        speechRecognizer.setRecognitionListener(this);

        Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        speechIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "voice.recognition.test");
        speechIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
        speechRecognizer.startListening(speechIntent);
        Log.i("SpeechActivity", "Speech Recognizer is listening");
    }

    @Override
    public void onReadyForSpeech(Bundle bundle) {

    }

    @Override
    public void onBeginningOfSpeech() {

    }

    @Override
    public void onRmsChanged(float v) {

    }

    @Override
    public void onBufferReceived(byte[] bytes) {

    }

    @Override
    public void onEndOfSpeech() {

    }

    @Override
    public void onError(int i) {

    }

    @Override
    public void onResults(Bundle bundle) {
        Log.i("SpeechActivity", "Speech was detected...");
        String spoken = "";
        ArrayList<String> data = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        for (int i = 0; i < data.size(); i++) {
            spoken += data.get(i);
        }

        Log.i(this.getClass().getName(), String.format("The word \"%s\" was detected.", spoken));
        if(spoken.equalsIgnoreCase("go")) {
            doSomething();
        }
    }

    @Override
    public void onPartialResults(Bundle bundle) {

    }

    @Override
    public void onEvent(int i, Bundle bundle) {

    }
}

Я запускаю приложение на своем Samsung Galaxy S7 Edge, подключив телефон к ноутбуку (через USB), нажав кнопку " Запуск" (приложение) в Android Studio и выбрав свой телефон в качестве подключенного устройства.

Когда приложение запускается на моем телефоне, первое, что я замечаю, это то, что оно не побуждает меня принять / отклонить разрешение приложения на использование микрофона. Это ранний предупреждающий знак для меня, что что-то не так.

Но потом, когда я перейду к SpeechActivity/activity_speech.xml экран, я получаю:

Когда это работает, я получаю:

FATAL EXCEPTION: main
Process: com.example.myuser.myapp, PID: 9585
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myuser.myapp/com.example.myuser.myapp.SpeechActivity}: java.lang.RuntimeException: Ya can't do that now, ya here.
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2947)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3008)
   at android.app.ActivityThread.-wrap14(ActivityThread.java)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6688)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
Caused by: java.lang.RuntimeException: Ya can't do that now, ya here.
   at com.example.myuser.myapp.SpeechActivity.onCreate(SpeechActivity.java:43)
   at android.app.Activity.performCreate(Activity.java:6912)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2900)

Возможно ли мне загрузить и установить плагин или APK для работы распознавания речи? Почему мое приложение не запрашивает разрешение на использование микрофона моего телефона? Как распознаватель речи запускается / слушает, но, похоже, вообще не воспринимает речь?

1 ответ

Решение

Согласно документации, это опасное разрешение. Вы должны запросить его у пользователя.

RECORD_AUDIO: позволяет приложению записывать звук.

Уровень защиты: опасный

Постоянное значение: "android.permission.RECORD_AUDIO"

Просто вы можете проверить, есть ли у вашего приложения это разрешение, используя

int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
    Manifest.permission.RECORD_AUDIO);

if (permissionCheck == PERMISSION_GRANTED) {
    // you have the permission, proceed to record audio

    speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
    speechRecognizer.setRecognitionListener(this);

    Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    speechIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "voice.recognition.test");
    speechIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
    speechRecognizer.startListening(speechIntent);
    Log.i("SpeechActivity", "Speech Recognizer is listening");

} 
else {

    // you don't have permission, try requesting for it

    ActivityCompat.requestPermissions(thisActivity,
            new String[]{Manifest.permission.RECORD_AUDIO},
            MY_PERMISSION_REQUEST_RECORD_AUDIO);
}

Не спешите, прочтите Руководство по запрашиванию разрешений в Руководствах по Android.

Другие вопросы по тегам