Android的语音识别连续服务 [英] Android Speech Recognition Continuous Service

查看:150
本文介绍了Android的语音识别连续服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立在安卓4.2上运行的连续语音识别服务。使用此链接的答案(<一href="http://stackoverflow.com/questions/14940657/android-speech-recognition-as-a-service-on-android-4-1-4-2">Android语音识别是在Android 4.1及放大器的服务; 4.2 ),我创建了一个从一个活动运行的服务。我的问题是,在方法的handleMessage访问 mTarget.mAudioManager mTarget.mSpeechRecognizerIntent 的时候,我得到空例外。 (从它创建和mTarget对象)的目标是不为空,但它里面的所有对象。

我在做什么错在这里?

相关活动code(静态方法从活动叫,a​​ctivityContext是这种方法是从所谓的活动):

 公共静态无效的init(上下文的背景下)
{
   voiceCommandService =新VoiceCommandService();
   activityContext =背景;
}

公共静态无效startContinuousListening()
{
    意向书的服务=新的意图(activityContext,VoiceCommandService.class);
    activityContext.startService(服务);

    消息味精=新的Message();
    msg.what = VoiceCommandService.MSG_RECOGNIZER_START_LISTENING;

    尝试
    {
      voiceCommandService.mServerMessenger.send(MSG);
    }
    赶上(RemoteException的E)
   {
    e.printStackTrace();
   }

}
 

服务code:

 公共类VoiceCommandService扩展服务
{
保护AudioManager mAudioManager;
保护SpeechRecognizer mSpeechRecognizer;
受保护的意图mSpeechRecognizerIntent;
受保护的最后使者mServerMessenger =新信使(新IncomingHandler(本));

保护布尔mIsListening;
保护挥发性布尔mIsCountDownOn;

静态最终诠释MSG_RECOGNIZER_START_LISTENING = 1;
静态最终诠释MSG_RECOGNIZER_CANCEL = 2;

@覆盖
公共无效的onCreate()
{
    super.onCreate();
    mAudioManager =(AudioManager)getSystemService(Context.AUDIO_SERVICE);
    mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(本);
    mSpeechRecognizer.setRecognitionListener(新SpeechRecognitionListener());
    mSpeechRecognizerIntent =新的意图(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                                     RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
                                     this.getPackageName());
}

受保护的静态类IncomingHandler扩展了Handler
{
    私人的WeakReference&LT; VoiceCommandService&GT; mtarget;

    IncomingHandler(VoiceCommandService目标)
    {
        mtarget =新的WeakReference&LT; VoiceCommandService&GT;(目标);
    }


    @覆盖
    公共无效的handleMessage(信息MSG)
    {
        最后VoiceCommandService目标= mtarget.get();

        开关(msg.what)
        {
            案例MSG_RECOGNIZER_START_LISTENING:

                如果(Build.VERSION.SDK_INT&GT; = Build.VERSION_ codeS.JELLY_BEAN)
                {
                    //关闭蜂鸣声
                    target.mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM,真正的);
                }
                 如果(!target.mIsListening)
                 {
                     target.mSpeechRecognizer.startListening(target.mSpeechRecognizerIntent);
                     target.mIsListening = TRUE;
                    //Log.d(TAG,消息开始听); // $ NON-NLS-1 $
                 }
                 打破;

             案例MSG_RECOGNIZER_CANCEL:
                  target.mSpeechRecognizer.cancel();
                  target.mIsListening = FALSE;
                  //Log.d(TAG,消息取消识别); // $ NON-NLS-1 $
                  打破;
         }
   }
}

//为果冻豆解决倒计时
保护CountDownTimer mNoSpeechCountDown =新CountDownTimer(5000,5000)
{

    @覆盖
    公共无效onTick(长millisUntilFinished)
    {
        // TODO自动生成方法存根

    }

    @覆盖
    公共无效onFinish()
    {
        mIsCountDownOn = FALSE;
        消息消息= Message.obtain(空,MSG_RECOGNIZER_CANCEL);
        尝试
        {
            mServerMessenger.send(消息);
            消息= Message.obtain(空,MSG_RECOGNIZER_START_LISTENING);
            mServerMessenger.send(消息);
        }
        赶上(RemoteException的E)
        {

        }
    }
};

@覆盖
公共无效的onDestroy()
{
    super.onDestroy();

    如果(mIsCountDownOn)
    {
        mNoSpeechCountDown.cancel();
    }
    如果(mSpeechRecognizer!= NULL)
    {
        mSpeechRecognizer.destroy();
    }
}

保护类SpeechRecognitionListener实现RecognitionListener
{

    私有静态最后字符串变量=SpeechRecognitionListener;

    @覆盖
    公共无效onBeginningOfSpeech()
    {
        //语音输入将被处理,所以没有必要向下计数了
        如果(mIsCountDownOn)
        {
            mIsCountDownOn = FALSE;
            mNoSpeechCountDown.cancel();
        }
        //Log.d(TAG,onBeginingOfSpeech); // $ NON-NLS-1 $
    }

    @覆盖
    公共无效onBufferReceived(byte []的缓冲区)
    {

    }

    @覆盖
    公共无效onEndOfSpeech()
    {
        //Log.d(TAG,onEndOfSpeech); // $ NON-NLS-1 $
     }

    @覆盖
    公共无效onerror的(INT错误)
    {
        如果(mIsCountDownOn)
        {
            mIsCountDownOn = FALSE;
            mNoSpeechCountDown.cancel();
        }
         mIsListening = FALSE;
         消息消息= Message.obtain(空,MSG_RECOGNIZER_START_LISTENING);
         尝试
         {
                mServerMessenger.send(消息);
         }
         赶上(RemoteException的E)
         {

         }
        //Log.d(TAG,错误=+误差); // $ NON-NLS-1 $
    }

    @覆盖
    公共无效的onEvent(INT事件类型,捆绑PARAMS)
    {

    }

    @覆盖
    公共无效onPartialResults(包partialResults)
    {

    }

    @覆盖
    公共无效onReadyForSpeech(包PARAMS)
    {
        如果(Build.VERSION.SDK_INT&GT; = Build.VERSION_ codeS.JELLY_BEAN)
        {
            mIsCountDownOn =真;
            mNoSpeechCountDown.start();
            mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM,假);
        }
        Log.d(TAG,onReadyForSpeech); // $ NON-NLS-1 $
    }

    @覆盖
    公共无效onResults(捆绑结果)
    {
        //Log.d(TAG,onResults); // $ NON-NLS-1 $

    }

    @覆盖
    公共无效onRmsChanged(浮动rmsdB)
    {

    }

}

@覆盖
公众的IBinder onBind(意向为arg0){
    // TODO自动生成方法存根
    返回null;
}
}
 

解决方案

类成员

 私人诠释mBindFlag;
私人信使mServiceMessenger;
 

在的onCreate启动服务()

  @覆盖
保护无效的onCreate(包savedInstanceState)
{
    super.onCreate(savedInstanceState);

    意向书的服务=新的意图(activityContext,VoiceCommandService.class);
    activityContext.startService(服务);
    mBindFlag = Build.VERSION.SDK_INT&LT; Build.VERSION_ codeS.ICE_CREAM_SANDWICH? 0:Context.BIND_ABOVE_CLIENT;

}
 

在ONSTART绑定服务()

  @覆盖
保护无效的OnStart()
{
    super.onStart();

    bindService(新意图(这一点,VoiceCommandService.class),mServiceConnection,mBindFlag);
}

@覆盖
保护无效的onStop()
{
    super.onStop();

    如果(mServiceMessenger!= NULL)
    {
        unbindService(mServiceConnection);
        mServiceMessenger = NULL;
    }
}
 

mServiceConnection成员

 私人最终ServiceConnection mServiceConnection =新ServiceConnection()
{
    @覆盖
    公共无效onServiceConnected(组件名名称,服务的IBinder)
    {
        如果(调试){Log.d(TAG,onServiceConnected);} // $ NON-NLS-1 $

        mServiceMessenger =新的信使(服务);
        消息味精=新的Message();
        msg.what = VoiceCommandService.MSG_RECOGNIZER_START_LISTENING;

        尝试
        {
            mServerMessenger.send(MSG);
        }
        赶上(RemoteException的E)
        {
            e.printStackTrace();
        }
    }

    @覆盖
    公共无效onServiceDisconnected(组件名名)
    {
        如果(调试){Log.d(TAG,onServiceDisconnected);} // $ NON-NLS-1 $
        mServiceMessenger = NULL;
    }

}; // mServiceConnection
 

在服务

  @覆盖
公众的IBinder onBind(意向意图)
{
    Log.d(TAG,onBind); // $ NON-NLS-1 $

    返回mServerMessenger.getBinder();
}
 

I'm trying to create a service to run continuous speech recognition in Android 4.2. Using the answer from this link ( Android Speech Recognition as a service on Android 4.1 & 4.2 ), I created a service that is run from an Activity. My problem is that I get null exceptions when accessing mTarget.mAudioManager or mTarget.mSpeechRecognizerIntent in the handleMessage method. The target (and mTarget object created from it) is not null, but all the objects inside it are.

What am I doing wrong here?

Relevant Activity Code (static methods called from activity, activityContext is the activity this method is called from):

public static void init(Context context)
{
   voiceCommandService = new VoiceCommandService();
   activityContext = context;
}

public static void startContinuousListening()
{
    Intent service = new Intent(activityContext, VoiceCommandService.class);
    activityContext.startService(service);

    Message msg = new Message();
    msg.what = VoiceCommandService.MSG_RECOGNIZER_START_LISTENING; 

    try
    {
      voiceCommandService.mServerMessenger.send(msg);
    } 
    catch (RemoteException e)
   {
    e.printStackTrace();
   }

}

Service Code:

public class VoiceCommandService extends Service
{
protected AudioManager mAudioManager; 
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
protected final Messenger mServerMessenger = new Messenger(new IncomingHandler(this));

protected boolean mIsListening;
protected volatile boolean mIsCountDownOn;

static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;

@Override
public void onCreate()
{
    super.onCreate();
    mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 
    mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
    mSpeechRecognizer.setRecognitionListener(new SpeechRecognitionListener());
    mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                                     RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
                                     this.getPackageName());
}

protected static class IncomingHandler extends Handler
{
    private WeakReference<VoiceCommandService> mtarget;

    IncomingHandler(VoiceCommandService target)
    {
        mtarget = new WeakReference<VoiceCommandService>(target);
    }


    @Override
    public void handleMessage(Message msg)
    {
        final VoiceCommandService target = mtarget.get();

        switch (msg.what)
        {
            case MSG_RECOGNIZER_START_LISTENING:

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
                {
                    // turn off beep sound  
                    target.mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
                }
                 if (!target.mIsListening)
                 {
                     target.mSpeechRecognizer.startListening(target.mSpeechRecognizerIntent);
                     target.mIsListening = true;
                    //Log.d(TAG, "message start listening"); //$NON-NLS-1$
                 }
                 break;

             case MSG_RECOGNIZER_CANCEL:
                  target.mSpeechRecognizer.cancel();
                  target.mIsListening = false;
                  //Log.d(TAG, "message canceled recognizer"); //$NON-NLS-1$
                  break;
         }
   } 
} 

// Count down timer for Jelly Bean work around
protected CountDownTimer mNoSpeechCountDown = new CountDownTimer(5000, 5000)
{

    @Override
    public void onTick(long millisUntilFinished)
    {
        // TODO Auto-generated method stub

    }

    @Override
    public void onFinish()
    {
        mIsCountDownOn = false;
        Message message = Message.obtain(null, MSG_RECOGNIZER_CANCEL);
        try
        {
            mServerMessenger.send(message);
            message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
            mServerMessenger.send(message);
        }
        catch (RemoteException e)
        {

        }
    }
};

@Override
public void onDestroy()
{
    super.onDestroy();

    if (mIsCountDownOn)
    {
        mNoSpeechCountDown.cancel();
    }
    if (mSpeechRecognizer != null)
    {
        mSpeechRecognizer.destroy();
    }
}

protected class SpeechRecognitionListener implements RecognitionListener
{

    private static final String TAG = "SpeechRecognitionListener";

    @Override
    public void onBeginningOfSpeech()
    {
        // speech input will be processed, so there is no need for count down anymore
        if (mIsCountDownOn)
        {
            mIsCountDownOn = false;
            mNoSpeechCountDown.cancel();
        }               
        //Log.d(TAG, "onBeginingOfSpeech"); //$NON-NLS-1$
    }

    @Override
    public void onBufferReceived(byte[] buffer)
    {

    }

    @Override
    public void onEndOfSpeech()
    {
        //Log.d(TAG, "onEndOfSpeech"); //$NON-NLS-1$
     }

    @Override
    public void onError(int error)
    {
        if (mIsCountDownOn)
        {
            mIsCountDownOn = false;
            mNoSpeechCountDown.cancel();
        }
         mIsListening = false;
         Message message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
         try
         {
                mServerMessenger.send(message);
         }
         catch (RemoteException e)
         {

         }
        //Log.d(TAG, "error = " + error); //$NON-NLS-1$
    }

    @Override
    public void onEvent(int eventType, Bundle params)
    {

    }

    @Override
    public void onPartialResults(Bundle partialResults)
    {

    }

    @Override
    public void onReadyForSpeech(Bundle params)
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
        {
            mIsCountDownOn = true;
            mNoSpeechCountDown.start();
            mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
        }
        Log.d(TAG, "onReadyForSpeech"); //$NON-NLS-1$
    }

    @Override
    public void onResults(Bundle results)
    {
        //Log.d(TAG, "onResults"); //$NON-NLS-1$

    }

    @Override
    public void onRmsChanged(float rmsdB)
    {

    }

}

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}
}

解决方案

Class members

private int mBindFlag;
private Messenger mServiceMessenger;

Start service in onCreate()

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

    Intent service = new Intent(activityContext, VoiceCommandService.class);
    activityContext.startService(service);
    mBindFlag = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH ? 0 : Context.BIND_ABOVE_CLIENT;

}

Bind service in onStart()

@Override
protected void onStart()
{
    super.onStart();

    bindService(new Intent(this, VoiceCommandService.class), mServiceConnection, mBindFlag);
}

@Override
protected void onStop()
{
    super.onStop();

    if (mServiceMessenger != null)
    {
        unbindService(mServiceConnection);
        mServiceMessenger = null;
    }
}

mServiceConnection member

private final ServiceConnection mServiceConnection = new ServiceConnection()
{
    @Override
    public void onServiceConnected(ComponentName name, IBinder service)
    {
        if (DEBUG) {Log.d(TAG, "onServiceConnected");} //$NON-NLS-1$

        mServiceMessenger = new Messenger(service);
        Message msg = new Message();
        msg.what = VoiceCommandService.MSG_RECOGNIZER_START_LISTENING; 

        try
        {
            mServerMessenger.send(msg);
        } 
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name)
    {
        if (DEBUG) {Log.d(TAG, "onServiceDisconnected");} //$NON-NLS-1$
        mServiceMessenger = null;
    }

}; // mServiceConnection

In the service

@Override
public IBinder onBind(Intent intent)
{
    Log.d(TAG, "onBind");  //$NON-NLS-1$

    return mServerMessenger.getBinder();
}

这篇关于Android的语音识别连续服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆