服务泄露了最初绑定在这里的 ServiceConnection android.speech.SpeechRecognizer$Connection@2e1ecaf

Service has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@2e1ecaf that was originally bound here

我正在尝试 运行 一项服务,该服务一旦开始使用语音识别器录制音频 5 秒。但是,每当我启动服务时,它都会调用语音识别器 class 中的 onError 方法,一旦我停止服务,它就会给我错误:

Service has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@2e1ecaf that was originally bound here

我已经尝试了所有方法并到处寻找但似乎找不到解决方案。请帮忙。

这是我的服务代码,它是使用 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();
}