From 0f9ba39415401e2e18ad366aa440e294ec4ccfb8 Mon Sep 17 00:00:00 2001 From: tobika Date: Fri, 5 Jul 2024 15:47:14 +0200 Subject: [PATCH 1/3] add allowForSilence during recording --- README.md | 63 ++++++++++++++++--- .../speechrecognition/SpeechRecognition.java | 40 +++++++++++- src/definitions.ts | 32 +++++++++- 3 files changed, 125 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 89f5b1c..9e7c871 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,8 @@ No further action required. * [`isListening()`](#islistening) * [`checkPermissions()`](#checkpermissions) * [`requestPermissions()`](#requestpermissions) +* [`addListener('endOfSegmentedSession', ...)`](#addlistenerendofsegmentedsession-) +* [`addListener('segmentResults', ...)`](#addlistenersegmentresults-) * [`addListener('partialResults', ...)`](#addlistenerpartialresults-) * [`addListener('listeningState', ...)`](#addlistenerlisteningstate-) * [`removeAllListeners()`](#removealllisteners) @@ -203,6 +205,52 @@ Request the speech recognition permission. -------------------- +### addListener('endOfSegmentedSession', ...) + +```typescript +addListener(eventName: 'endOfSegmentedSession', listenerFunc: () => void) => Promise +``` + +Called when allowForSilence set to > 0 and segmented session has ended. (Android only) + +On Android it doesn't work if popup is true. + +| Param | Type | +| ------------------ | ------------------------------------ | +| **`eventName`** | 'endOfSegmentedSession' | +| **`listenerFunc`** | () => void | + +**Returns:** Promise<PluginListenerHandle> + +**Since:** 6.0.2 + +-------------------- + + +### addListener('segmentResults', ...) + +```typescript +addListener(eventName: 'segmentResults', listenerFunc: (data: { matches: string[]; }) => void) => Promise +``` + +Called when allowForSilence set to > 0 and segment result received. (Android only) + +On Android it doesn't work if popup is true. + +Provides segment result. + +| Param | Type | +| ------------------ | ------------------------------------------------------ | +| **`eventName`** | 'segmentResults' | +| **`listenerFunc`** | (data: { matches: string[]; }) => void | + +**Returns:** Promise<PluginListenerHandle> + +**Since:** 6.0.2 + +-------------------- + + ### addListener('partialResults', ...) ```typescript @@ -265,13 +313,14 @@ Remove all the listeners that are attached to this plugin. #### UtteranceOptions -| Prop | Type | Description | -| -------------------- | -------------------- | ---------------------------------------------------------------- | -| **`language`** | string | key returned from `getSupportedLanguages()` | -| **`maxResults`** | number | maximum number of results to return (5 is max) | -| **`prompt`** | string | prompt message to display on popup (Android only) | -| **`popup`** | boolean | display popup window when listening for utterance (Android only) | -| **`partialResults`** | boolean | return partial results if found | +| Prop | Type | Description | +| --------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **`language`** | string | key returned from `getSupportedLanguages()` | +| **`maxResults`** | number | maximum number of results to return (5 is max) | +| **`prompt`** | string | prompt message to display on popup (Android only) | +| **`popup`** | boolean | display popup window when listening for utterance (Android only) | +| **`partialResults`** | boolean | return partial results if found | +| **`allowForSilence`** | number | allows milliseconds of silence during recording. Needs number over 0 (Android only) You need to listen to segmentResults to receive the data. On Android it doesn't work if popup is true. | #### PermissionStatus diff --git a/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java b/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java index 0f3fcab..52ac00f 100644 --- a/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java +++ b/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java @@ -83,7 +83,8 @@ public void start(PluginCall call) { String prompt = call.getString("prompt", null); boolean partialResults = call.getBoolean("partialResults", false); boolean popup = call.getBoolean("popup", false); - beginListening(language, maxResults, prompt, partialResults, popup, call); + int allowForSilence = call.getInt("allowForSilence", 0); + beginListening(language, maxResults, prompt, partialResults, popup, call, allowForSilence); } @PluginMethod @@ -159,7 +160,8 @@ private void beginListening( String prompt, final boolean partialResults, boolean showPopup, - PluginCall call + PluginCall call, + int allowForSilence ) { Logger.info(getLogTag(), "Beginning to listen for audible speech"); @@ -171,6 +173,12 @@ private void beginListening( intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, partialResults); intent.putExtra("android.speech.extra.DICTATION_MODE", partialResults); + if (allowForSilence > 0) { + intent.putExtra(RecognizerIntent.EXTRA_SEGMENTED_SESSION, RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS); + intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, allowForSilence); + intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, allowForSilence); + } + if (prompt != null) { intent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt); } @@ -332,6 +340,34 @@ public void onPartialResults(Bundle partialResults) { } catch (Exception ex) {} } + @Override + public void onSegmentResults(Bundle results) { + ArrayList matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); + + try { + JSArray jsArray = new JSArray(matches); + + if (this.call != null) { + if (!this.partialResults) { + this.call.resolve(new JSObject().put("status", "success").put("matches", jsArray)); + } else { + JSObject ret = new JSObject(); + ret.put("matches", jsArray); + notifyListeners("segmentResults", ret); + } + } + } catch (Exception ex) { + this.call.resolve(new JSObject().put("status", "error").put("message", ex.getMessage())); + } + } + + @Override + public void onEndOfSegmentedSession() { + JSObject ret = new JSObject(); + notifyListeners("endOfSegmentedSession", ret); + + } + @Override public void onEvent(int eventType, Bundle params) {} } diff --git a/src/definitions.ts b/src/definitions.ts index 1b0bb8d..331dba9 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -65,6 +65,29 @@ export interface SpeechRecognitionPlugin { * @since 5.0.0 */ requestPermissions(): Promise; + /** + * Called when allowForSilence set to > 0 and segmented session has ended. (Android only) + * + * On Android it doesn't work if popup is true. + * + * @since 6.0.2 + */ + addListener( + eventName: 'endOfSegmentedSession', + listenerFunc: () => void + ): Promise; + /** + * Called when allowForSilence set to > 0 and segment result received. (Android only) + * + * On Android it doesn't work if popup is true. + * + * Provides segment result. + * + * @since 6.0.2 + */ + addListener(eventName: 'segmentResults', listenerFunc: (data: { + matches: string[]; + }) => void): Promise; /** * Called when partialResults set to true and result received. * @@ -78,7 +101,6 @@ export interface SpeechRecognitionPlugin { eventName: 'partialResults', listenerFunc: (data: { matches: string[] }) => void, ): Promise; - /** * Called when listening state changed. * @@ -117,4 +139,12 @@ export interface UtteranceOptions { * return partial results if found */ partialResults?: boolean; + /** + * allows milliseconds of silence during recording. Needs number over 0 (Android only) + * + * You need to listen to segmentResults to receive the data. + * + * On Android it doesn't work if popup is true. + */ + allowForSilence?: number; } From fc65d76eb30b20351df57f2bb264d28695b18a57 Mon Sep 17 00:00:00 2001 From: tobika Date: Fri, 5 Jul 2024 16:03:33 +0200 Subject: [PATCH 2/3] run linter/fmt --- .../community/speechrecognition/SpeechRecognition.java | 1 - src/definitions.ts | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java b/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java index 52ac00f..b155548 100644 --- a/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java +++ b/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java @@ -365,7 +365,6 @@ public void onSegmentResults(Bundle results) { public void onEndOfSegmentedSession() { JSObject ret = new JSObject(); notifyListeners("endOfSegmentedSession", ret); - } @Override diff --git a/src/definitions.ts b/src/definitions.ts index 331dba9..a535954 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -74,7 +74,7 @@ export interface SpeechRecognitionPlugin { */ addListener( eventName: 'endOfSegmentedSession', - listenerFunc: () => void + listenerFunc: () => void, ): Promise; /** * Called when allowForSilence set to > 0 and segment result received. (Android only) @@ -85,9 +85,10 @@ export interface SpeechRecognitionPlugin { * * @since 6.0.2 */ - addListener(eventName: 'segmentResults', listenerFunc: (data: { - matches: string[]; - }) => void): Promise; + addListener( + eventName: 'segmentResults', + listenerFunc: (data: { matches: string[] }) => void, + ): Promise; /** * Called when partialResults set to true and result received. * From 4eb68b749eae983d893b1a801df907e1ae804746 Mon Sep 17 00:00:00 2001 From: Tobias Kausch Date: Mon, 8 Sep 2025 12:11:37 +0200 Subject: [PATCH 3/3] fix wrong handling of segment result --- .../community/speechrecognition/SpeechRecognition.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java b/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java index 8ca7b1d..b2646ea 100644 --- a/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java +++ b/android/src/main/java/com/getcapacitor/community/speechrecognition/SpeechRecognition.java @@ -340,13 +340,9 @@ public void onSegmentResults(Bundle results) { JSArray jsArray = new JSArray(matches); if (this.call != null) { - if (!this.partialResults) { - this.call.resolve(new JSObject().put("status", "success").put("matches", jsArray)); - } else { - JSObject ret = new JSObject(); - ret.put("matches", jsArray); - notifyListeners("segmentResults", ret); - } + JSObject ret = new JSObject(); + ret.put("matches", jsArray); + notifyListeners("segmentResults", ret); } } catch (Exception ex) { this.call.resolve(new JSObject().put("status", "error").put("message", ex.getMessage()));