Android - 是否可以将语音识别用作命令

Android - Is it possible to use Speech recognition as a command

我知道这很明显但是你们可以提供任何关于如何使用 Speech/Voice recognition 命令你的 phone 的教程或链接,比如转动 on/off 你的相机手电筒,通知收到一条消息,就像一个助手。您可以提供任何链接或教程吗?我正打算做一个这样的应用程序。谢谢

Speech 是一个 "STT"(语音到文本)系统,因此意味着您的输入将是一个 String...您可以制作一个 receiveCommand(String input) 函数,并制作方法来电。

由于您想操作您的设备,通常是不用手,并在其他活动中执行任务,您可能希望 运行 您的输入作为 Service,甚至 InputMethodService 可能合适。

package your_package.goes.here;

import android.app.Service;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
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.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;

import java.util.ArrayList;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

public class STT_Services extends Service {
    private static Intent speechIntent;

    private SpeechRecognizer speechRecognizer;
    private ImageView microphoneView;
    private WindowManager windowManager;
    private Handler handler;
    private static Timer timer;

    public STT_Services() {
    }

    private void enforceTimeToLive() {
        if (timer != null) {
            timer.cancel();
        }
        timer = new Timer();
        timer.schedule(
                new TimerTask() {
                    @Override
                    public void run() {
                        stopSelf();
                    }
                },
                120000
        );
    }

    private void showMic() {
        handler.removeCallbacksAndMessages(null);
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (microphoneView != null) {
                    microphoneView.setVisibility(View.VISIBLE);
                }
            }
        });
    }

    private void hideMic() {
        handler.removeCallbacksAndMessages(null);
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (microphoneView != null) {
                    microphoneView.setVisibility(View.GONE);
                }
            }
        });
    }

    @Override
    public void onCreate() {
        Log.v(TAG, "onCreate()");
        super.onCreate();
        handler = new Handler(getMainLooper());
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        if (windowManager != null) {
            microphoneView = new ImageView(this);
            microphoneView.setImageResource(R.drawable.microphone);
            microphoneView.setColorFilter(Color.RED);
            DisplayMetrics displayMetrics = new DisplayMetrics();
            windowManager.getDefaultDisplay().getMetrics(displayMetrics);
            windowManager.addView(
                    microphoneView,
                    new WindowManager.LayoutParams(
                            // (int w, int h, int xpos, int ypos, int _type, int _flags, int _format)
                            displayMetrics.widthPixels / 2,//ViewGroup.LayoutParams.WRAP_CONTENT,
                            displayMetrics.heightPixels / 2,//ViewGroup.LayoutParams.WRAP_CONTENT,
                            0,
                            0,
                            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                            PixelFormat.TRANSPARENT
                    )
            );
            hideMic();
        }
        speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        speechIntent.putExtra(
                RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
        );
        speechIntent.putExtra(
                RecognizerIntent.EXTRA_LANGUAGE,
                Locale.getDefault()
        );
        if (speechRecognizer == null) {
            speechRecognizer = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
            speechRecognizer.setRecognitionListener(
                    new RecognitionListener() {
                        @Override
                        public void onReadyForSpeech(Bundle params) {
                            Log.v(TAG, "onReadyForSpeech(Bundle params)");
                            showMic();
                        }

                        @Override
                        public void onBeginningOfSpeech() {
                            Log.v(TAG, "onBeginningOfSpeech()");
                        }

                        @Override
                        public void onRmsChanged(float rmsdB) {
                            // Log.v(TAG, "onRmsChanged(float rmsdB)");
                        }

                        @Override
                        public void onBufferReceived(byte[] buffer) {
                            Log.v(TAG, "onBufferReceived(byte[] buffer)");
                        }

                        @Override
                        public void onEndOfSpeech() {
                            Log.v(TAG, "onEndOfSpeech()");
                            hideMic();
                        }

                        @Override
                        public void onError(int error) {
                            Log.v(TAG, "onError(int error) -> " + error);
                            switch (error) {
                                case SpeechRecognizer.ERROR_AUDIO:
                                    Log.v(TAG, "ERROR_AUDIO");
                                    break;
                                case SpeechRecognizer.ERROR_CLIENT:
                                    Log.v(TAG, "ERROR_CLIENT");
                                    break;
                                case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
                                    Log.v(TAG, "ERROR_INSUFFICIENT_PERMISSIONS");
                                    break;
                                case SpeechRecognizer.ERROR_NETWORK:
                                    Log.v(TAG, "ERROR_NETWORK");
                                    break;
                                case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
                                    Log.v(TAG, "ERROR_NETWORK_TIMEOUT");
                                    break;
                                case SpeechRecognizer.ERROR_NO_MATCH:
                                    Log.v(TAG, "ERROR_NO_MATCH");
                                    break;
                                case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
                                    Log.v(TAG, "ERROR_RECOGNIZER_BUSY");
                                    break;
                                case SpeechRecognizer.ERROR_SERVER:
                                    Log.v(TAG, "ERROR_SERVER");
                                    break;
                                case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
                                    Log.v(TAG, "ERROR_SPEECH_TIMEOUT");
                                    break;
                                default:
                                    Log.v(TAG, "switch (error) -> default: -> Unknown error: " + error);
                                    break;
                            }
                            hideMic();
                        }

                        @Override
                        public void onResults(Bundle results) {
                            Log.v(TAG, "onResults(Bundle results)");
                            ArrayList<String> myResults = results.getStringArrayList(
                                    SpeechRecognizer.RESULTS_RECOGNITION
                            );
                            if (myResults != null) {
                                if (myResults.size() > 0) {
                                    String text = myResults.get(0);
                                    Log.v(TAG, "Text: (" + text + ")");
                                    // IN HERE, YOU DO THE SWITCH WITH YOUR COMMANDS
                                    switch(text){
                                       case "stuff":
                                          break;
                                       case "start":
                                          break;
                                       case "stop":
                                          break;
                                       default:
                                          Log.v(TAG, "could not understand(" + text + ")");
                                          break;
                                    }
                                }
                            } else {
                                Log.v(TAG, "NO results in Bundle (getStringArrayList returned null)");
                            }
                        }

                        @Override
                        public void onPartialResults(Bundle partialResults) {
                            Log.v(TAG, "onPartialResults(Bundle partialResults)");
                        }

                        @Override
                        public void onEvent(int eventType, Bundle params) {
                            Log.v(TAG, "onEvent(int eventType, Bundle params)");
                        }
                    }
            );
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.v(TAG, "onStartCommand(Intent intent, int flags, int startId)");
        if (intent != null) {
            String cmd = intent.getStringExtra(CONSTANTS.VOICE_SERVICE_COMMAND);
            if (cmd != null) {
                Log.v(TAG, "onStartCommand -> Cmd: " + cmd);
                switch (cmd) {
                    case CONSTANTS.VOICE_SERVICE_COMMAND_LISTEN_START:
                        // if (isReadyToUse) {
                        speechRecognizer.startListening(speechIntent);
                        showMic();
                        // }
                        enforceTimeToLive();
                        break;
                    case CONSTANTS.VOICE_SERVICE_COMMAND_LISTEN_STOP:
                        speechRecognizer.stopListening();
                        hideMic();
                        break;
                    case CONSTANTS.VOICE_SERVICE_COMMAND_DIE:
                        hideMic();
                        stopSelf();
                        break;
                    default:
                }
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.v(TAG, "onDestroy()");
        super.onDestroy();
        speechIntent = null;
        if (speechRecognizer != null) {
            speechRecognizer.stopListening();
            speechRecognizer.destroy();
        }
        // isReadyToUse = false;
        if (windowManager != null) {
            windowManager.removeView(microphoneView);
            windowManager = null;
            microphoneView = null;
        }
        handler = null;
        if (timer != null) {
            timer.cancel();
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.v(TAG, "onBind(Intent intent)");
        return null; // no binding, Broadcasted texts only
    }
}