【问题标题】:Google Now service in my application我的应用程序中的 Google Now 服务
【发布时间】:2014-03-18 16:44:31
【问题描述】:

我被一项服务和谷歌 TTS 阻止了。好吧,我希望一项服务在 bg 中启动,当我说“ok google”或我选择的任何内容时,开始文本识别的意图。我创建了服务,但现在......我该怎么办?我被困住了。这是服务:

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

    protected boolean mIsListening;
    protected volatile boolean mIsCountDownOn;
    private static boolean mIsStreamSolo;

    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<GnowService> mtarget;

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


        @Override
        public void handleMessage(Message msg)
        {
            final GnowService 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  
                        if (!mIsStreamSolo)
                        {
                            mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);
                            mIsStreamSolo = 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:
                    if (mIsStreamSolo)
                   {
                        mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, false);
                        mIsStreamSolo = false;
                   }
                      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
    {

        @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();

            }
            Log.d("", "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;
    }
}

我必须在我的MainActivity 中创建一些东西吗?我如何“告诉”应用程序识别例如“ok google”这样的词?开始意图?谢谢 编辑:

这是我在清单中集成的部分:

<receiver
            android:name=".mBootCompletedReceiver"
            android:enabled="true"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />

            </intent-filter>
    </receiver>
        <service android:name=".GnowService"></service>

在我的 MainActivity 中,我创建了 Broadcastreceiver

private BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent serviceIntent = new Intent();
            serviceIntent.setAction("com.dd.speech.GnowService");
            context.startService(serviceIntent);
        }
    };

首先.. 到目前为止是正确的吗?还是我错了?然后,其他点我不知道我是否理解以及我是否能够做到。你有这部分代码的示例吗?

【问题讨论】:

    标签: java android speech-recognition google-now google-text-to-speech


    【解决方案1】:

    在我的回答中提出解决方案,识别器总是在听。在说出关键词之前,它什么也不做。假设应用在用户说“开始结束游戏”之前什么都不做,当用户说“结束游戏”时什么都不做。

    1. 在清单中注册 Intent.ACTION_BOOT_COMPLETED 并创建一个 BroadcastReceiver 类来监听此事件并启动服务。您的应用必须至少启动一次,接收方才能接收此广播。
    2. 在您的 MainActivity 中启动 onCreate 中的服务。如果要与服务器通信,则在 onStart 中绑定服务并在 onStop 中取消绑定。
    3. 在服务中,创建一个flag private boolean mShouldProcessResult;
    4. 在 onResults 中,如果 mShouldProcessResult 标志为假,只需检查结果是否包含“开始结束游戏”。如果是,请向用户指示应用程序将开始处理他/她的口语并将 mShouldProcessResult 标志设置为 true,否则什么也不做。如果 mShouldProcessResult 标志为真,则处理用户所说的任何内容,这应该包括“停止游戏结束”。

    请注意,电池寿命会大大缩短,在某些情况下会缩短一半。

    【讨论】:

    • 您的想法是否会在“开始结束游戏”被识别之前阻止口语进入互联网(谷歌服务器)(如“OK Google”适用于 Google Now)?如果没有,是否有可能在任何现有的 Android 版本中实现这一点?谢谢+1。
    • 那么你需要使用 Sphinx 或离线语音识别器,只有 Jelly Bean 提供。
    • 谢谢霍恩。 PocketSphinx 不是对 2.2 以上的所有 Android 版本都可用吗?如果是这样,您可能指的是其他一些只能从 JellyBean 获得的“离线语音识别器”。对?您是否考虑过特定​​的此类离线识别器? (即你能推荐一个吗?)
    • JellyBean 提供的离线功能是 Google 语音识别器。但是,您必须关闭互联网连接。所以我认为 PocketSphinx 是你的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多