porcupineManager.stop() 和 .destroy() 不起作用

Jas*_*ith 5 java android android-studio

我一直在尝试实现一种应用程序检测唤醒词的方法,例如“Hey google”或“Jarvis”。我做了一些研究,发现 porcupine 有助于解决唤醒词问题,但现在的问题是我似乎无法触发 startRecognition() 再次侦听用户输入,然后继续进行。我仍然尝试触发 startRecognition() 但后来它要求我做 SpeechRecognizer.Destroy() 我尝试用 porcupine onDestroy 方法做但后来它停止工作。对不起,如果我混淆了任何人,我会附上我的代码我将非常感谢大家的帮助,因为我已经尝试解决这个问题一段时间了。

另一个问题是下面这行代码做了什么?

PendingIntent contentIntent = PendingIntent.getActivity(
                                    this,
                                    0,
                                    new Intent(this, MainActivity.class), // this line ?
                                    0);
Run Code Online (Sandbox Code Playgroud)

目前的代码:(

public class PorcupineService extends Service {

private static final int REQUEST_RECORD_AUDIO_PERMISSION_CODE = 1;
private SpeechRecognizer speechRecognizer;
TextToSpeech textToSpeech;
String userResponse;
Float speechRate = 2f;

private static final String CHANNEL_ID = "PorcupineServiceChannel";
private PorcupineManager porcupineManager;

private int numUtterances;

private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel notificationChannel = new NotificationChannel(
                CHANNEL_ID,
                "Porcupine",
                NotificationManager.IMPORTANCE_HIGH);

        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(notificationChannel);
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    createNotificationChannel();

    PendingIntent pendingIntent = PendingIntent.getActivity(
            this,
            0,
            new Intent(this, MainActivity.class),
            0);

    numUtterances = 0;

    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Wake word")
            .setContentText("Service running")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentIntent(pendingIntent)
            .build();

    startForeground(1234, notification);

    try {
        porcupineManager = new PorcupineManager.Builder()
                .setKeyword(Porcupine.BuiltInKeyword.JARVIS)
                .setSensitivity(0.7f).build(
                        getApplicationContext(),
                        (keywordIndex) -> {
                            Log.i("YOU SAID IT!", "yesss");

                            textSpeechInitialize();
                            startRecognition();
                            listening();

                            numUtterances++;

                            PendingIntent contentIntent = PendingIntent.getActivity(
                                    this,
                                    0,
                                    new Intent(this, MainActivity.class),
                                    0);

                            final String contentText = numUtterances == 1 ? " time!" : " times!";
                            Notification n = new NotificationCompat.Builder(this, CHANNEL_ID)
                                    .setContentTitle("Wake word")
                                    .setContentText("Detected " + numUtterances + contentText)
                                    .setSmallIcon(R.drawable.ic_launcher_background)
                                    .setContentIntent(contentIntent)
                                    .build();

                            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                            assert notificationManager != null;
                            notificationManager.notify(1234, n);
                        });
        porcupineManager.start();
    } catch (PorcupineException e) {
        Log.e("PORCUPINE", e.toString());
    }

    return super.onStartCommand(intent, flags, startId);
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onDestroy() {
    try {
        porcupineManager.stop();
        porcupineManager.delete();
        speechRecognizer.destroy();
    } catch (PorcupineException e) {
        Log.e("PORCUPINE", e.toString());
    }

    super.onDestroy();
}

public void listening(){
    speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
    speechRecognizer.setRecognitionListener(new RecognitionListener() {

        @Override
        public void onReadyForSpeech(Bundle params) {
        }

        @Override
        public void onBeginningOfSpeech() {}

        @Override
        public void onRmsChanged(float rmsdB) {}

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

        @Override
        public void onEndOfSpeech() {}

        @Override
        public void onError(int error) {
            String errorMessage = getErrorText(error);
            Log.i(">>> INFO", "Failed " + errorMessage);
        }

        @Override
        public void onResults(Bundle results) {
            ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
            userResponse = matches.get(0);
            userResponse = userResponse.toLowerCase();
            toSpeak(userResponse);
        }

        @Override
        public void onPartialResults(Bundle partialResults) {}

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

    });
}

public void textSpeechInitialize(){
    textToSpeech = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if (status == TextToSpeech.SUCCESS){
                textToSpeech.setLanguage(Locale.getDefault());
                textToSpeech.setSpeechRate(speechRate);
                String greet = greetings();
                toSpeak(greet);
                startRecognition();
            } else {
                Toast.makeText(getApplicationContext(), "Feature not supported", Toast.LENGTH_SHORT).show();
            }
        }
    });
}

public String getErrorText(int errorCode) {
    String message;
    switch (errorCode) {
        ...
    }
    return message;
}

public static String greetings(){
    String s = "";
    Calendar c = Calendar.getInstance();
    int time = c.get(Calendar.HOUR_OF_DAY);

    if (time >= 0 && time < 12){
        s = "Good Morning sir! how can I help you today?";
    } else if (time >= 12 && time < 16){
        s = "Good Afternoon sir";
    } else if (time >= 16 && time < 22){
        s = "Good Evening sir";
    }
    else if (time >= 22 && time < 24){
        s = "Hello sir, you need to take some rest... its getting late!";
    }
    return s;
}

private void startRecognition() {
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getPackageName());
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "en");
    speechRecognizer.startListening(intent);
}

private void toSpeak(String toSpeak){

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Log.i(">>>Voice Info", String.valueOf(textToSpeech.getVoice()));
    }
    try {
        textToSpeech.speak(toSpeak, TextToSpeech.QUEUE_FLUSH, null);
    } catch (Exception e){
        e.printStackTrace();
    }
}
}
Run Code Online (Sandbox Code Playgroud)

小智 -1

  1. 由于 startRecognition() 没有被触发,请检查 MainActivity 中录制音频的权限。您的应用程序的 AndroidManifest.xml 应包含以下行:

<uses-permission android:name="android.permission.RECORD_AUDIO"/>

或者,您可能必须明确请求用户许可。你可以参考Medium上的这篇文章:

https://medium.com/picovoice/no-way-google-build-your-own-wake-word-service-on-android-339a0189ff4c

  1. Intent 是 android.content.Intent 类型的对象。它基本上是一个被动数据结构,保存要执行的操作的抽象描述(例如启动活动或服务)。在这里,它启动 MainActivity 类,该类在用户登录移动 SDK 应用程序后立即触发。

    new Intent(this, MainActivity.class)

有关更多详细信息,您可以查看以下文档: