Es sieht so aus, als hätte Google die Offline-Spracherkennung von Google Now für Apps von Drittanbietern verfügbar gemacht. Es wird von der App Utter verwendet .
Hat jemand Implementierungen gesehen, wie einfache Sprachbefehle mit dieser Offline-Sprachaufzeichnung ausgeführt werden können? Verwenden Sie nur die reguläre SpeechRecognizer-API und sie funktioniert automatisch?
Antworten:
Google hat die Offline-Erkennung in diesem Suchupdate stillschweigend aktiviert, es sind jedoch (noch) keine API oder zusätzlichen Parameter in der SpeechRecognizer-Klasse verfügbar . {Siehe Bearbeiten am Ende dieses Beitrags} Die Funktionalität ist ohne zusätzliche Codierung verfügbar. Das Gerät des Benutzers muss jedoch korrekt konfiguriert sein, damit es funktioniert. Hier liegt das Problem, und ich würde mir vorstellen, warum viele Entwickler Nehmen wir an, sie vermissen etwas.
Außerdem hat Google bestimmte Jelly Bean-Geräte aufgrund von Hardwareeinschränkungen daran gehindert, die Offline-Erkennung zu verwenden. Für welche Geräte dies gilt, ist nicht dokumentiert. Tatsächlich ist nichts dokumentiert. Die Konfiguration der Funktionen für den Benutzer hat sich (für sie) als Versuch und Irrtum erwiesen. Es funktioniert für einige sofort - Für diejenigen, die es nicht tun, ist dies der 'Leitfaden', den ich ihnen zur Verfügung stelle.
BEARBEITEN: Das vorübergehende Ändern des Gebietsschemas des Geräts auf Englisch in Großbritannien scheint dies ebenfalls zu starten, damit es für einige funktioniert.
Einige Nutzer gaben an, dass sie noch einige Male neu starten mussten, bevor es funktionieren würde, aber sie alle gelangen schließlich dorthin, oft unerklärlich zu dem Auslöser, dessen Schlüssel sich in der Google Search APK befinden , also nicht im öffentlichen Bereich oder ein Teil von AOSP .
Soweit ich feststellen kann, testet Google die Verfügbarkeit einer Verbindung, bevor entschieden wird, ob die Offline- oder Online-Erkennung verwendet wird. Wenn eine Verbindung anfänglich verfügbar ist, aber vor der Antwort verloren geht, gibt Google einen Verbindungsfehler aus und greift nicht auf Offline zurück. Nebenbei bemerkt, wenn eine Anfrage für die netzwerksynthetisierte Stimme gestellt wurde, wird kein Fehler angezeigt, wenn dies fehlschlägt - Sie erhalten Stille.
Das Google Search-Update hat keine zusätzlichen Funktionen in Google Now aktiviert. Wenn Sie versuchen, es ohne Internetverbindung zu verwenden, tritt ein Fehler auf. Ich erwähne dies, als ich mich fragte, ob die Fähigkeit so leise zurückgezogen werden würde, wie es schien, und daher in der Produktion nicht als verlässlich angesehen werden sollte.
Wenn Sie beabsichtigen, die SpeechRecognizer-Klasse zu verwenden, seien Sie gewarnt, es ist ein ziemlich schwerwiegender Fehler damit verbunden, für dessen Behandlung Ihre eigene Implementierung erforderlich ist.
Wenn nicht speziell offline = true angefordert werden kann , ist es unmöglich, diese Funktion zu steuern, ohne die Datenverbindung zu manipulieren. Müll. Sie erhalten Hunderte von Benutzer-E-Mails, in denen Sie gefragt werden, warum Sie etwas so Einfaches nicht aktiviert haben!BEARBEITEN: Seit API-Level 23 wurde ein neuer Parameter EXTRA_PREFER_OFFLINE hinzugefügt, an den sich der Google-Erkennungsdienst anscheinend zu halten scheint.
Hoffe das oben genannte hilft.
quelle
Ich möchte den Leitfaden verbessern, den die Antwort https://stackoverflow.com/a/17674655/2987828 mit Bildern an die Benutzer sendet. Es ist der Satz "Für diejenigen, die es nicht tun, ist dies der 'Leitfaden', den ich ihnen zur Verfügung stelle." das möchte ich verbessern.
Der Benutzer sollte auf die vier in diesen Bildern blau hervorgehobenen Schaltflächen klicken:
Dann kann der Benutzer beliebige Sprachen auswählen. Wenn der Download abgeschlossen ist, sollte er die Verbindung zum Netzwerk trennen und dann auf die Schaltfläche "Mikrofon" der Tastatur klicken.
Es funktionierte für mich (Android 4.1.2), dann funktionierte die Spracherkennung sofort, ohne neu zu starten. Ich kann jetzt Anweisungen an die Shell von Terminal Emulator diktieren! Auf einem Padfone 2 von ASUS ist es offline doppelt schneller als online.
Diese Bilder werden unter cc by-sa 3.0 lizenziert, wobei die Zuordnung zu stackoverflow.com/a/21329845/2987828 erforderlich ist. Sie können diese Bilder daher an einer beliebigen Stelle zusammen mit dieser Zuordnung hinzufügen.
(Dies ist die Standardrichtlinie aller Bilder und Texte auf stackoverflow.com)
quelle
Eine einfache und flexible Offline-Erkennung unter Android wird von CMUSphinx implementiert, einem Open-Source-Toolkit zur Spracherkennung. Es funktioniert rein offline, schnell und konfigurierbar. Es kann beispielsweise kontinuierlich nach Schlüsselwörtern suchen.
Den neuesten Code und das neueste Tutorial finden Sie hier .
Update 2019 : Die Zeit vergeht schnell, CMUSphinx ist nicht mehr so genau. Ich empfehle stattdessen das Kaldi Toolkit. Die Demo ist da .
quelle
Kurz gesagt, ich habe nicht die Implementierung, sondern die Erklärung.
Google hat die Offline-Spracherkennung für Apps von Drittanbietern nicht verfügbar gemacht. Die Offline-Erkennung ist nur über die Tastatur zugänglich. Ben Randall (der Entwickler von Äußersten!) Erklärt seine Problemumgehung in einem Artikel bei Android Police:
Von Utter! Behauptet, die erste Nicht-IME-App zu sein, die die Offline-Spracherkennung in Jelly Bean nutzt
quelle
Ich habe meinen Sprachdienst erfolgreich mit Offline-Funktionen implementiert, indem ich onPartialResults offline und onResults online verwendet habe.
quelle
Ich habe mich damit befasst und festgestellt, dass Sie das Offline-Paket für Ihre Sprache installieren müssen. Meine Spracheinstellung war "Español (Estados Unidos)", aber es gibt kein Offline-Paket für diese Sprache. Als ich die gesamte Netzwerkverbindung deaktivierte, erhielt ich von RecognizerIntent eine Warnung, dass Google nicht erreicht werden kann, und ändere die Sprache in "Englisch (USA)" (weil ich bereits das Offline-Paket habe) und startete den RecognizerIntent, der gerade funktioniert hat.
Tasten: Spracheinstellung == Offline-Spracherkennungspaket
quelle
Es ist anscheinend möglich, die Offline-Spracherkennung manuell zu installieren, indem die Dateien direkt heruntergeladen und manuell an den richtigen Speicherorten installiert werden. Ich denke, dies ist nur eine Möglichkeit, die Hardwareanforderungen von Google zu umgehen. Ich persönlich musste jedoch nicht neu starten oder so, sondern wechselte einfach nach Großbritannien und wieder zurück.
quelle
Das Arbeitsbeispiel ist unten angegeben.
MyService.class
public class MyService extends Service implements SpeechDelegate, Speech.stopDueToDelay { public static SpeechDelegate delegate; @Override public int onStartCommand(Intent intent, int flags, int startId) { //TODO do something useful try { if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { ((AudioManager) Objects.requireNonNull( getSystemService(Context.AUDIO_SERVICE))).setStreamMute(AudioManager.STREAM_SYSTEM, true); } } catch (Exception e) { e.printStackTrace(); } Speech.init(this); delegate = this; Speech.getInstance().setListener(this); if (Speech.getInstance().isListening()) { Speech.getInstance().stopListening(); } else { System.setProperty("rx.unsafe-disable", "True"); RxPermissions.getInstance(this).request(permission.RECORD_AUDIO).subscribe(granted -> { if (granted) { // Always true pre-M try { Speech.getInstance().stopTextToSpeech(); Speech.getInstance().startListening(null, this); } catch (SpeechRecognitionNotAvailable exc) { //showSpeechNotSupportedDialog(); } catch (GoogleVoiceTypingDisabledException exc) { //showEnableGoogleVoiceTyping(); } } else { Toast.makeText(this, R.string.permission_required, Toast.LENGTH_LONG).show(); } }); } return Service.START_STICKY; } @Override public IBinder onBind(Intent intent) { //TODO for communication return IBinder implementation return null; } @Override public void onStartOfSpeech() { } @Override public void onSpeechRmsChanged(float value) { } @Override public void onSpeechPartialResults(List<String> results) { for (String partial : results) { Log.d("Result", partial+""); } } @Override public void onSpeechResult(String result) { Log.d("Result", result+""); if (!TextUtils.isEmpty(result)) { Toast.makeText(this, result, Toast.LENGTH_SHORT).show(); } } @Override public void onSpecifiedCommandPronounced(String event) { try { if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { ((AudioManager) Objects.requireNonNull( getSystemService(Context.AUDIO_SERVICE))).setStreamMute(AudioManager.STREAM_SYSTEM, true); } } catch (Exception e) { e.printStackTrace(); } if (Speech.getInstance().isListening()) { Speech.getInstance().stopListening(); } else { RxPermissions.getInstance(this).request(permission.RECORD_AUDIO).subscribe(granted -> { if (granted) { // Always true pre-M try { Speech.getInstance().stopTextToSpeech(); Speech.getInstance().startListening(null, this); } catch (SpeechRecognitionNotAvailable exc) { //showSpeechNotSupportedDialog(); } catch (GoogleVoiceTypingDisabledException exc) { //showEnableGoogleVoiceTyping(); } } else { Toast.makeText(this, R.string.permission_required, Toast.LENGTH_LONG).show(); } }); } } @Override public void onTaskRemoved(Intent rootIntent) { //Restarting the service if it is removed. PendingIntent service = PendingIntent.getService(getApplicationContext(), new Random().nextInt(), new Intent(getApplicationContext(), MyService.class), PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); assert alarmManager != null; alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service); super.onTaskRemoved(rootIntent); } }
Für mehr Details,
Hoffe das wird jemandem in Zukunft helfen.
quelle