Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Speech Recognition Insufficient Permission (Error Code 9)

I am trying to implement speech recognition without the standard dialog (it is working fine with the dialog).

I am getting error code 9 as soon as I try to start listening.

My device is an LG G Stylo (running Android 6.0).

Manifest:

<manifest package="example.com.myapplication"
      xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<application
 .....

(also tried adding INTERNET permission even though that shouldn't be necessary since offline recognition should be working)

build.gradle:

compileSdkVersion 23
buildToolsVersion "23.0.2"

defaultConfig {
    applicationId "example.com.appname"
    minSdkVersion 19
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}

Speech recognition code:

private SpeechRecognizer speechRecognizer;

protected void onCreate(Bundle savedInstanceState) {
  speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
  speechRecognizer.setRecognitionListener(new speech_listener());
  Intent intent = new intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
  intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
     RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
  intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
       getApplication().getPackageName());
  intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
  intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.ENGLISH);
  speechRecognizer.startListening(intent);

Listener (inner) class:

class speech_listener implements RecognitionListener
{
  public void onReadyForSpeech(Bundle params){}
  public void onBeginningOfSpeech(){}
  public void onRmsChanged(float rmsdB){}
  public void onBufferReceived(byte[] buffer){}
  public void onEndOfSpeech(){}
  public void onError(int error){
    Log.d("Speech", "error: " + error);
  }
  public void onResults(Bundle results)
  {
    ArrayList data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
    String answer = (String)data.get(0);
    processAnswer(answer);
  }
  public void onPartialResults(Bundle partialResults){}
  public void onEvent(int eventType, Bundle params){}
}

Any insight would be appreciated.

like image 291
Mark Fraser Avatar asked Feb 07 '16 00:02

Mark Fraser


3 Answers

In my case, error message is "9/Insufficient permissions"

Solved by giving Microphone permission to Google app

enter image description here

Reference : https://github.com/react-native-voice/voice/issues/253#issuecomment-812726040

like image 151
Thanhal Avatar answered Sep 30 '22 09:09

Thanhal


although the answer is out there, you have to put it together from many pieces. What has worked for me (I was getting the same error):

  • add the permission into you manifest: <uses-permission android:name="android.permission.RECORD_AUDIO" />
  • from my logcat, I got a strong feeling the following permission is also necessary: <uses-permission android:name="android.permission.BLUETOOTH" /> try to add it if everything else fails
  • in newer versions of android, you also have to request your permission from the user during runtime. It is crucial to do this at the right spot, you cannot run the request for permission just from anywhere in your code, it has to be run from the UI Thread. For me the following worked:

    void doPermAudio()
    {
        int MY_PERMISSIONS_RECORD_AUDIO = 1;
        MainActivity thisActivity = this;
    
       if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.RECORD_AUDIO)
            != PackageManager.PERMISSION_GRANTED) {
    
               ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.RECORD_AUDIO},
                    MY_PERMISSIONS_RECORD_AUDIO);
            }
        }
    }
    
    // in main activity's onCreate
    protected void onCreate(Bundle savedInstanceState) {
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    doPermAudio();
                }
            }
         });
    }
    
  • also, what has been mentioned elsewhere, you may get the error 9 for declaring a wrong package name when starting the listening intent, as it seems many people have copied their function from a sample from the web, where the package name is explicitly written out:

    void listen()
    {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                String pkg = getApplication().getPackageName();
                intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, pkg);
    
                sr.startListening(intent);
    
            }
        });
    }
    
like image 27
mxl Avatar answered Sep 30 '22 09:09

mxl


On Android 6 this permission is one of dangerous ones which means you need to ask user to confirm it (actually acquire it). Check this and this for more details.

like image 32
Sam Avatar answered Sep 30 '22 09:09

Sam