capacitor-microphone 0.1.15 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -40,6 +40,8 @@ private boolean isDestroyed = false;
|
|
|
40
40
|
private long lastStopTime = 0;
|
|
41
41
|
private static final long RESTART_COOLDOWN_MS = 400;
|
|
42
42
|
private Runnable delayedStartRunnable;
|
|
43
|
+
private boolean restartScheduled = false;
|
|
44
|
+
|
|
43
45
|
|
|
44
46
|
|
|
45
47
|
@PluginMethod
|
|
@@ -149,6 +151,22 @@ public void startListening(PluginCall call) {
|
|
|
149
151
|
startListeningInternal(call, lang);
|
|
150
152
|
}
|
|
151
153
|
|
|
154
|
+
private void safeRestartListening() {
|
|
155
|
+
if (restartScheduled) return;
|
|
156
|
+
restartScheduled = true;
|
|
157
|
+
|
|
158
|
+
getActivity()
|
|
159
|
+
.getWindow()
|
|
160
|
+
.getDecorView()
|
|
161
|
+
.postDelayed(() -> {
|
|
162
|
+
restartScheduled = false;
|
|
163
|
+
if (!isDestroyed && isListening && speechRecognizer != null) {
|
|
164
|
+
speechRecognizer.startListening(speechIntent);
|
|
165
|
+
}
|
|
166
|
+
}, 350);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
|
|
152
170
|
|
|
153
171
|
private void startListeningInternal(PluginCall call, String lang) {
|
|
154
172
|
isDestroyed = false;
|
|
@@ -187,10 +205,7 @@ private void startListeningInternal(PluginCall call, String lang) {
|
|
|
187
205
|
|
|
188
206
|
if (error == SpeechRecognizer.ERROR_NO_MATCH ||
|
|
189
207
|
error == SpeechRecognizer.ERROR_SPEECH_TIMEOUT) {
|
|
190
|
-
|
|
191
|
-
if (!isDestroyed && isListening && speechRecognizer != null) {
|
|
192
|
-
speechRecognizer.startListening(speechIntent);
|
|
193
|
-
}
|
|
208
|
+
safeRestartListening();
|
|
194
209
|
return;
|
|
195
210
|
}
|
|
196
211
|
|
|
@@ -215,7 +230,7 @@ private void startListeningInternal(PluginCall call, String lang) {
|
|
|
215
230
|
}
|
|
216
231
|
|
|
217
232
|
if (!isDestroyed && isListening && speechRecognizer != null) {
|
|
218
|
-
|
|
233
|
+
safeRestartListening();
|
|
219
234
|
}
|
|
220
235
|
}
|
|
221
236
|
|
|
@@ -250,6 +265,14 @@ private void startListeningInternal(PluginCall call, String lang) {
|
|
|
250
265
|
RecognizerIntent.EXTRA_LANGUAGE, lang);
|
|
251
266
|
speechIntent.putExtra(
|
|
252
267
|
RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
|
|
268
|
+
speechIntent.putExtra(
|
|
269
|
+
RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS,
|
|
270
|
+
1500
|
|
271
|
+
);
|
|
272
|
+
speechIntent.putExtra(
|
|
273
|
+
RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS,
|
|
274
|
+
1500
|
|
275
|
+
);
|
|
253
276
|
|
|
254
277
|
|
|
255
278
|
speechRecognizer.startListening(speechIntent);
|
|
@@ -317,98 +340,147 @@ private void startListeningInternal(PluginCall call, String lang) {
|
|
|
317
340
|
call.resolve();
|
|
318
341
|
}
|
|
319
342
|
|
|
343
|
+
|
|
344
|
+
|
|
320
345
|
@PluginMethod
|
|
321
346
|
public void restartListening(PluginCall call) {
|
|
322
|
-
// 1. Obtener lenguaje actual o del parámetro
|
|
323
347
|
String currentLang = "es-MX";
|
|
324
|
-
if (
|
|
325
|
-
currentLang =
|
|
326
|
-
|
|
327
|
-
currentLang = call.getString("lang", "es-MX");
|
|
348
|
+
if (speechIntent != null) {
|
|
349
|
+
currentLang = speechIntent.getStringExtra(RecognizerIntent.EXTRA_LANGUAGE);
|
|
350
|
+
if (currentLang == null) currentLang = "es-MX";
|
|
328
351
|
}
|
|
352
|
+
currentLang = call.getString("lang", currentLang);
|
|
329
353
|
|
|
330
|
-
// 2. Guardar para usar después
|
|
331
354
|
final String lang = currentLang;
|
|
332
355
|
|
|
333
|
-
//
|
|
356
|
+
// Resolver INMEDIATAMENTE
|
|
334
357
|
call.resolve(new JSObject().put("success", true));
|
|
335
358
|
|
|
336
|
-
//
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
getActivity().runOnUiThread(() -> {
|
|
342
|
-
isListening = false;
|
|
343
|
-
isDestroyed = true;
|
|
344
|
-
|
|
345
|
-
if (delayedStartRunnable != null) {
|
|
346
|
-
getActivity()
|
|
347
|
-
.getWindow()
|
|
348
|
-
.getDecorView()
|
|
349
|
-
.removeCallbacks(delayedStartRunnable);
|
|
350
|
-
delayedStartRunnable = null;
|
|
351
|
-
}
|
|
359
|
+
// Hacer el restart real EN EL UI THREAD desde el inicio
|
|
360
|
+
getActivity().runOnUiThread(() -> {
|
|
361
|
+
// DESTRUIR TODO
|
|
362
|
+
isListening = false;
|
|
363
|
+
isDestroyed = true;
|
|
352
364
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
365
|
+
if (delayedStartRunnable != null) {
|
|
366
|
+
getActivity()
|
|
367
|
+
.getWindow()
|
|
368
|
+
.getDecorView()
|
|
369
|
+
.removeCallbacks(delayedStartRunnable);
|
|
370
|
+
delayedStartRunnable = null;
|
|
371
|
+
}
|
|
358
372
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
373
|
+
if (speechRecognizer != null) {
|
|
374
|
+
speechRecognizer.cancel();
|
|
375
|
+
speechRecognizer.setRecognitionListener(null);
|
|
376
|
+
speechRecognizer.destroy();
|
|
377
|
+
speechRecognizer = null;
|
|
378
|
+
}
|
|
362
379
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
}
|
|
380
|
+
currentCall = null;
|
|
381
|
+
speechIntent = null;
|
|
366
382
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
383
|
+
// Reiniciar después de 500ms
|
|
384
|
+
getActivity()
|
|
385
|
+
.getWindow()
|
|
386
|
+
.getDecorView()
|
|
387
|
+
.postDelayed(() -> startListeningInternalWithoutCall(lang), 500);
|
|
388
|
+
});
|
|
389
|
+
}
|
|
371
390
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
391
|
+
// Nueva versión que NO requiere un PluginCall
|
|
392
|
+
private void startListeningInternalWithoutCall(String lang) {
|
|
393
|
+
isDestroyed = false;
|
|
394
|
+
isListening = true;
|
|
376
395
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
}).start();
|
|
381
|
-
}
|
|
396
|
+
if (getPermissionState("microphone") != PermissionState.GRANTED) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
382
399
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if (delayedStartRunnable != null) {
|
|
386
|
-
getActivity().runOnUiThread(() -> {
|
|
387
|
-
getActivity()
|
|
388
|
-
.getWindow()
|
|
389
|
-
.getDecorView()
|
|
390
|
-
.removeCallbacks(delayedStartRunnable);
|
|
391
|
-
});
|
|
392
|
-
delayedStartRunnable = null;
|
|
400
|
+
if (!SpeechRecognizer.isRecognitionAvailable(getContext())) {
|
|
401
|
+
return;
|
|
393
402
|
}
|
|
394
403
|
|
|
395
|
-
// Limpiar speech recognizer
|
|
396
404
|
if (speechRecognizer != null) {
|
|
405
|
+
stopSpeech();
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
getActivity().runOnUiThread(() -> {
|
|
397
409
|
try {
|
|
398
|
-
speechRecognizer.
|
|
399
|
-
speechRecognizer.
|
|
410
|
+
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(getActivity());
|
|
411
|
+
speechRecognizer.setRecognitionListener(new RecognitionListener() {
|
|
412
|
+
@Override public void onReadyForSpeech(Bundle params) {}
|
|
413
|
+
@Override public void onBeginningOfSpeech() {}
|
|
414
|
+
@Override public void onRmsChanged(float rmsdB) {}
|
|
415
|
+
@Override public void onBufferReceived(byte[] buffer) {}
|
|
416
|
+
@Override public void onEndOfSpeech() {}
|
|
417
|
+
|
|
418
|
+
@Override
|
|
419
|
+
public void onError(int error) {
|
|
420
|
+
if (isDestroyed || !isListening) return;
|
|
421
|
+
|
|
422
|
+
if (error == SpeechRecognizer.ERROR_NO_MATCH ||
|
|
423
|
+
error == SpeechRecognizer.ERROR_SPEECH_TIMEOUT) {
|
|
424
|
+
if (!isDestroyed && isListening && speechRecognizer != null) {
|
|
425
|
+
safeRestartListening();
|
|
426
|
+
}
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
stopSpeech();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
@Override
|
|
434
|
+
public void onResults(Bundle results) {
|
|
435
|
+
if (!isListening) return;
|
|
436
|
+
|
|
437
|
+
ArrayList<String> matches =
|
|
438
|
+
results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
|
|
439
|
+
|
|
440
|
+
if (matches != null && !matches.isEmpty()) {
|
|
441
|
+
notifyListeners(
|
|
442
|
+
"partialResult",
|
|
443
|
+
new JSObject()
|
|
444
|
+
.put("text", matches.get(0))
|
|
445
|
+
.put("isFinal", true)
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
safeRestartListening();
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
@Override
|
|
453
|
+
public void onPartialResults(Bundle partialResults) {
|
|
454
|
+
if (!isListening || isDestroyed) return;
|
|
455
|
+
|
|
456
|
+
ArrayList<String> matches =
|
|
457
|
+
partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
|
|
458
|
+
|
|
459
|
+
if (matches != null && !matches.isEmpty()) {
|
|
460
|
+
notifyListeners(
|
|
461
|
+
"partialResult",
|
|
462
|
+
new JSObject()
|
|
463
|
+
.put("text", matches.get(0))
|
|
464
|
+
.put("isFinal", false)
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
@Override public void onEvent(int eventType, Bundle params) {}
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
|
|
473
|
+
speechIntent.putExtra(
|
|
474
|
+
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
|
|
475
|
+
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
|
|
476
|
+
speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, lang);
|
|
477
|
+
speechIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
|
|
478
|
+
|
|
479
|
+
speechRecognizer.startListening(speechIntent);
|
|
400
480
|
} catch (Exception e) {
|
|
401
|
-
//
|
|
481
|
+
// Log error si es necesario
|
|
402
482
|
}
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// Resetear estado
|
|
407
|
-
currentCall = null;
|
|
408
|
-
speechIntent = null;
|
|
409
|
-
isListening = false;
|
|
410
|
-
isDestroyed = true;
|
|
411
|
-
lastStopTime = System.currentTimeMillis();
|
|
483
|
+
});
|
|
412
484
|
}
|
|
413
485
|
|
|
414
486
|
|