Activity has leaked ServiceConnection android.speech.SpeechRecognizer$Connection
Asked Answered
A

2

1

I'm trying to make a function in google glass that allows me to navigate between the cards without having to say the hotword "ok glass".

I tried creating a SpeechRecognizer that will constantly listen if something is being said or not and if the correct "command" is being mentioned the app will act accordingly.

However the onError method tells me

Error occured: RecognitionService busy.

and it's throwing a error that says

Activity com.example.sw_stage.topfinder.MainActivity has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@41d79530 that was originally bound here
android.app.ServiceConnectionLeaked: Activity com.example.sw_stage.topfinder.MainActivity has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@41d79530 that was originally bound here
        at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:970)
        at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:864)
        at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1575)
        at android.app.ContextImpl.bindService(ContextImpl.java:1558)
        at android.content.ContextWrapper.bindService(ContextWrapper.java:517)
        at android.speech.SpeechRecognizer.startListening(SpeechRecognizer.java:287)
        at com.example.sw_stage.topfinder.SpeechDetector.<init>(SpeechDetector.java:35)
        at com.example.sw_stage.topfinder.MainActivity.onCreate(MainActivity.java:58)
        at android.app.Activity.performCreate(Activity.java:5235)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1089)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2188)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2273)
        at android.app.ActivityThread.access$800(ActivityThread.java:138)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1236)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:149)
        at android.app.ActivityThread.main(ActivityThread.java:5045)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
        at dalvik.system.NativeStart.main(Native Method)

I'm currently using this project to test some of the functions I want to have in my final application. Currently I'm using

  • Head Gestures to navigate
  • A combination of a live card and immersion
  • A class to use shell commands in order to simulate touch gestures

Here is the class I wrote for the SpeechRecognizer

package com.example.sw_stage.topfinder;

import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;

import java.util.ArrayList;


public class SpeechDetector {
AudioManager mAudioManager;
SpeechRecognizer mSpeechRecognizer;
Intent intent;
issueKey mIssueKey = new issueKey();

public SpeechDetector(Context context)
{
    Log.i("speechdetector", "calling speech detector");
    mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

    mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(context);
    mSpeechRecognizer.setRecognitionListener(new listener(context));

    intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    Log.i("package name", context.getPackageName());
    intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.getPackageName());
    mSpeechRecognizer.startListening(intent);
    Log.i("111111","11111111"+"in");
}

class listener implements RecognitionListener
{
    Context context1;
    public listener(Context context)
    {
        context1 = context;
    }

    @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() {
        mSpeechRecognizer.startListening(intent);
    }

    @Override
    public void onError(int i) {
        //3 Audio recording error.
        //5 Other client side errors.
        //6 - No speech input
        //7 -No recognition result matched.
        //8 RecognitionService busy.
        //9 - vInsufficient permissions


        if(i == 1 || i == 2 || i == 3 || i == 4 || i == 5 || i == 6 || i == 7 || i == 8 || i == 9)
        {
            Log.wtf("Error occured", "Error " + i);
            mSpeechRecognizer.startListening(intent);
        }
    }

    @Override
    public void onResults(Bundle bundle) {
        ArrayList data = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        String result = "enter";
        String reslt = "";
        for (int i = 0; i < data.size(); i++)
        {
            reslt = reslt + " " + data.get(i);
        }
        switch(result)
        {
            case "next":  mIssueKey.issueKey(22);
                break;
            case "previous": mIssueKey.issueKey(21);
                break;
            case "enter": mIssueKey.issueKey(23);
                break;
            case "leave": mIssueKey.issueKey(4);
        }

    }

    @Override
    public void onPartialResults(Bundle bundle) {

    }

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

    }
}

}

I'm calling this class in my MainActivity onCreate() method.

private SpeechDetector mSpeechDetector;

@Override
protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);

    mIssueKey = new issueKey();
    mSpeechDetector = new SpeechDetector(getApplicationContext());

I changed

new SpeechDetector(MainActivity.this);

to

new SpeechDetector(getApplicationContext());

and I'm not getting the leaked error anymore

HOWEVER

Apparently the leaked error and the RecognitionService busy aren't related. So I'm still stuck with the fact that my speechrecognition doesn't work because it throws a RecognitionService busy error

EDIT I just noticed it writes an additional log

    03-03 13:11:13.252  20018-20018/? A/Error occured﹕ RecognitionService busy
    03-03 13:11:13.260      825-825/? I/RecognitionService﹕ concurrent startListening received - ignoring this call
Ambie answered 3/3, 2015 at 10:4 Comment(3)
In your MainActivity, have you by any chance declared your SpeechDetector class instance as static ??Eyeleen
@ZygoteInit No not declared as a static. I just updated my code with the declare and call of the SpeechDetector classAmbie
Do you require the service to be run all the time or just with the activity life, if it does only works till the activity life, stop and un-register while on pause or stop methods.Fylfot
A
1

It looks like the RecognitionService is already in use at the point that you call startListening(). I believe this is because you already called startListening() in your constructor and then call it again in onEndOfSpeech().

Make sure you make the necessary cancel() calls before calling startListening() again.

Airsick answered 3/3, 2015 at 22:11 Comment(1)
I added the .cancel() in the necesarry pieces of code. And now things have changed. I'm no longer getting 'RecognitionService busy'. I'm now either getting 'No speech input' or 'Other client side errors'Ambie
B
0

You got RecognitionService busy because of this code

@Override
public void onEndOfSpeech() {
    mSpeechRecognizer.startListening(intent);
}

You should call mSpeechRecognizer.startListening(intent) in onResults

Bluestocking answered 3/3, 2015 at 11:58 Comment(1)
tried this, however now it throws the error a x amount of times when MainActivity is started and then nothing. But it isn't like it's going in to the "OnResults()" method eitherAmbie

© 2022 - 2024 — McMap. All rights reserved.