问题
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
回答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.
回答2:
You got RecognitionService busy
because of this code
@Override
public void onEndOfSpeech() {
mSpeechRecognizer.startListening(intent);
}
You should call mSpeechRecognizer.startListening(intent)
in onResults
来源:https://stackoverflow.com/questions/28828928/activity-has-leaked-serviceconnection-android-speech-speechrecognizerconnection