我正在尝试运行一项服务,该服务在启动后使用语音识别器录制音频5秒。然而,每当我启动服务时,它都会调用语音识别器类中的onError
方法,一旦我停止服务,它就会给我错误:
服务已泄漏ServiceConnectionandroid.speech.SpeechRecognizer$Connection@2e1ecaf最初绑定到此
我尝试了所有的方法,到处寻找,但似乎找不到解决方案。请帮忙。
这是我的服务代码,它是使用mainActivity
中的按钮启动和停止的。
MicrophoneService.java
package com.example.daisymicrophone;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import static com.example.daisymicrophone.App.CHANNEL_ID;
public class MicrophoneService extends Service {
protected static SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
Context c;
public static final String TAG = "MicrophoneService";
@Override
public void onCreate() {
super.onCreate();
c = getApplicationContext();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Daisy App")
.setContentText("Daisy is listening to you")
.setSmallIcon(R.drawable.ic_mic)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
Toast.makeText(this,"start Service.", Toast.LENGTH_SHORT).show();
//if condition is met then do this
SpeechRecognitionListener h = new SpeechRecognitionListener();
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(h);
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
Log.d("avail", " " + mSpeechRecognizer.isRecognitionAvailable(this));
if (mSpeechRecognizer.isRecognitionAvailable(this))
Log.d("created", "onBeginingOfSpeech");
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mSpeechRecognizer.stopListening();
}
}, 5 * 1000);
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
class SpeechRecognitionListener implements RecognitionListener {
@Override
public void onReadyForSpeech(Bundle bundle) {
Log.d("onReady", "service");
}
@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) {
Log.d("ERROR","ERROR");
}
@Override
public void onResults(Bundle resultsBundle) {
Log.d("Results", "onResults: " + resultsBundle.toString());
}
@Override
public void onPartialResults(Bundle bundle) {
}
@Override
public void onEvent(int i, Bundle bundle) {
}
}
}
错误日志
2020-05-09 00:13:00.199 19488-19488/com.example.daisymicrophone D/MicrophoneService: startMicService:
2020-05-09 00:13:00.202 19488-19488/com.example.daisymicrophone V/ActivityThread: SVC-Creating service CreateServiceData{token=android.os.BinderProxy@331f924 className=com.example.daisymicrophone.MicrophoneService packageName=com.example.daisymicrophone intent=null}
2020-05-09 00:13:00.211 19488-19488/com.example.daisymicrophone D/ActivityThread: SVC-Calling onStartCommand: com.example.daisymicrophone.MicrophoneService@c083c8d, flags=0, startId=1
2020-05-09 00:13:00.238 19488-19488/com.example.daisymicrophone D/avail: true
2020-05-09 00:13:00.243 19488-19488/com.example.daisymicrophone D/created: onBeginingOfSpeech
2020-05-09 00:13:00.402 19488-19488/com.example.daisymicrophone D/onReady: service
2020-05-09 00:13:00.547 19488-19488/com.example.daisymicrophone D/ERROR: ERROR
2020-05-09 00:13:02.982 19488-19488/com.example.daisymicrophone D/MicrophoneService: stopMicService:
2020-05-09 00:13:02.984 19488-19488/com.example.daisymicrophone V/ActivityThread: SVC-Destroying service com.example.daisymicrophone.MicrophoneService@c083c8d
2020-05-09 00:13:02.993 19488-19488/com.example.daisymicrophone E/ActivityThread: Service com.example.daisymicrophone.MicrophoneService has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@2e1ecaf that was originally bound here
android.app.ServiceConnectionLeaked: Service com.example.daisymicrophone.MicrophoneService has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@2e1ecaf that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1376)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:1271)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1465)
at android.app.ContextImpl.bindService(ContextImpl.java:1437)
at android.content.ContextWrapper.bindService(ContextWrapper.java:636)
at android.speech.SpeechRecognizer.startListening(SpeechRecognizer.java:287)
at com.example.daisymicrophone.MicrophoneService.onStartCommand(MicrophoneService.java:66)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3394)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1632)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6259)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
您应该在停止服务时销毁语音识别器。
@Override
public void onDestroy() {
mSpeechRecognizer.destroy();
super.onDestroy();
}