it-swarm.com.de

Offline-Spracherkennung in Android (JellyBean)

Offenbar hat Google die Offline-Spracherkennung von Google Now für Apps von Drittanbietern verfügbar gemacht. Es wird von der App namens Utter verwendet.

Hat jemand Implementierungen gesehen, wie Sie mit dieser Offline-Sprachreferenz einfache Sprachbefehle ausführen können? Verwenden Sie nur die normale SpeechRecognizer-API, und das funktioniert automatisch?

78
rmooney

Google hat die Offline-Erkennung in diesem Suchupdate im Hintergrund aktiviert, es sind jedoch (noch) keine APIs 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 dafür richtig konfiguriert sein fange an zu arbeiten und hier liegt das Problem und ich würde mir vorstellen, warum viele Entwickler annehmen, dass ihnen etwas "fehlt".

Außerdem hat Google aufgrund von Hardwareeinschränkungen die Verwendung der Offline-Erkennung für bestimmte Jelly Bean-Geräte eingeschränkt. Für welche Geräte dies zutrifft, ist nicht dokumentiert. Tatsächlich ist nichts dokumentiert. Die Konfiguration der Funktionen für den Benutzer hat sich als (für ihn) probeweise 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.

  1. Vergewissern Sie sich, dass der Standard-Spracherkenner Android auf Google und nicht auf Samsung/Vlingo eingestellt ist
  2. Deinstallieren Sie alle Offline-Erkennungsdateien, die Sie bereits in den Google Voice Search-Einstellungen installiert haben
  3. Rufen Sie die Anwendungseinstellungen von Android auf und prüfen Sie, ob Sie die Updates für die Anwendungen Google Search und Google Voice Search deinstallieren können.
  4. Wenn Sie dies nicht tun können, gehen Sie in den Play Store und prüfen Sie, ob Sie dort die Option haben.
  5. Neustart (wenn Sie 2, 3 oder 4 erreicht haben)
  6. Aktualisieren Sie die Google-Suche und die Google-Sprachsuche im Play Store (wenn Sie 3 oder 4 erreicht haben oder ein Update ohnehin verfügbar ist).
  7. Neustart (wenn Sie 6 erreicht haben)
  8. Installieren Sie die Offline-Sprachdateien von English UK
  9. Starten Sie neu
  10. Verwenden Sie absolut! für eine Verbindung
  11. Wechseln Sie in den Flugzeugmodus und probieren Sie es aus
  12. Sobald es funktioniert, sollte auch die Offline-Erkennung anderer Sprachen wie Englisch (USA) funktionieren.

BEARBEITEN: Die vorübergehende Änderung des Gebietsschemas für das Gerät auf Englisch (UK) scheint für einige auch ein Kickstart zu sein.

Einige Benutzer meldeten, sie müssten noch einige Male neu starten, bevor es funktionieren würde, aber sie gelangen schließlich alle dorthin, oft unerklärlich dahin, was der Auslöser war, dessen Schlüssel sich im Google Search APK befindet , also nicht gemeinfrei oder Teil von AOSP .

Nach dem, was ich feststellen kann, testet Google die Verfügbarkeit einer Verbindung, bevor entschieden wird, ob die Offline- oder die Online-Erkennung verwendet wird. Wenn anfangs eine Verbindung verfügbar ist, diese jedoch vor der Antwort verloren geht, gibt Google einen Verbindungsfehler aus, der nicht auf die Offline-Verbindung zurückgreift. Als Randnotiz, wenn eine Anfrage für die Netzwerksynthetisierte Sprache gestellt wurde, wird kein Fehler ausgegeben, 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ückgenommen werden würde, wie es schien, und daher in der Produktion nicht darauf vertraut werden sollte.

Wenn Sie beabsichtigen, die SpeechRecognizer-Klasse zu verwenden, müssen Sie gewarnt sein, dass ein hübsches schwerwiegender Fehler damit verbunden ist, für dessen Behandlung Ihre eigene Implementierung erforderlich ist.

Da die Anforderung offline = true nicht spezifisch möglich ist, kann diese Funktion nicht gesteuert werden, ohne die Datenverbindung zu manipulieren. Müll. Sie werden in Hunderten von Benutzer-E-Mails gefragt, warum Sie etwas so Einfaches nicht aktiviert haben.

EDIT: Seit API-Ebene 23 wurde ein neuer Parameter hinzugefügt EXTRA_PREFER_OFFLINE an den sich der Google-Erkennungsdienst anscheinend zu halten scheint.

Hoffe, das oben genannte hilft.

71
brandall

Ich möchte den Leitfaden verbessern, den die Antwort https://stackoverflow.com/a/17674655/2987828 seinen Benutzern mit Bildern sendet. Es ist der Satz "Für diejenigen, die dies nicht tun, ist dies der" Leitfaden ", den ich ihnen zur Verfügung stellen werde." dass ich verbessern will.

Der Benutzer sollte in den folgenden Bildern auf die vier blau hervorgehobenen Schaltflächen klicken:

Go to your Android Application Settings, select Languages and input,edit Settings of Google Voice typing,select Download Offline speech recognition,select your languages in the ALL tab.

Der Benutzer kann dann 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 ohne Neustart. Ich kann jetzt Anweisungen an die Shell des Terminal-Emulators diktieren! Und es ist doppelt so schnell offline wie auf einem Padfone 2 von ASUS.

Diese Images sind unter cc by-sa 3.0 lizenziert, wobei die Zuordnung zu stackoverflow.com/a/21329845/2987828 erforderlich ist. Sie können diese Bilder daher zusammen mit dieser Zuordnung hinzufügen.

(Dies ist die Standardrichtlinie für alle Bilder und Texte auf stackoverflow.com.)

20
user2987828

Eine einfache und flexible Offline-Erkennung unter Android wird von CMUSphinx, einem Open-Source-Spracherkennungs-Toolkit, implementiert. Sie arbeitet rein offline, schnell und konfigurierbar. Sie kann beispielsweise kontinuierlich auf Schlüsselwörter achten. 

Den neuesten Code und Tutorial finden Sie hier .

16
Nikolay Shmyrev

Kurz gesagt, ich habe nicht die Implementierung, sondern die Erklärung.

Google hat die Offline-Spracherkennung nicht für Apps von Drittanbietern verfügbar gemacht. Die Offlineerkennung ist nur über die Tastatur erreichbar. Ben Randall (der Entwickler von Absolut!) Erklärt in einem Artikel bei Android Police seine Problemumgehung:

Ich hatte meine eigene Tastatur implementiert und wechselte zwischen Google Voice Typing und die Standardtastatur des Benutzers mit einer unsichtbaren Bearbeitung Textfeld und transparente Aktivität, um die Eingabe zu erhalten. Dirty Hack!

Dies war die einzige Möglichkeit dies zu tun, da Offline-Voice-Typing nur .__ sein konnte. Ausgelöst durch eine IME oder eine Systemanwendung (das war mein Root-Hack) . Die andere Art der Erkennungs-API… hat sie nicht ausgelöst und ist fehlgeschlagen mit einem Serverfehler. … Für den Workaround wurde viel Arbeit für mich verschwendet! Aber zumindest war ich bereit für die Umsetzung ...

Von Utter! Behauptet, die erste Nicht-IME-App zu sein, die die Offline-Spracherkennung in Jelly Bean verwendet

7
Leon Joosse

Ich habe meinen Speech-Service erfolgreich mit Offline-Funktionen implementiert, indem onPartialResults offline und onResults online verwendet wurde.

3
P. Stresow

Ich habe mich damit beschäftigt und ich habe bemerkt, 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. Wenn ich also alle Netzwerkverbindungen ausschaltete, erhielt ich eine Meldung von RecognizerIntent, die besagt, dass Google nicht erreichbar ist. Dann ändere ich die Sprache in "English (US)" (weil ich bereits das Offline-Paket habe) und den RecognizerIntent gestartet, der gerade geklappt hat.

Tasten: Spracheinstellung == Offline Voice Recognizer Package

2
Akino

Offensichtlich ist es möglich, die Offline-Spracherkennung manuell zu installieren, indem die Dateien direkt heruntergeladen und manuell an den richtigen Stellen installiert werden. Ich denke, dies ist nur eine Möglichkeit, die Hardware-Anforderungen von Google zu umgehen. Ich persönlich musste aber gar nicht neu starten oder so, ich wechselte einfach nach UK und wieder zurück.

1
Riju Chatterjee

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,

https://github.com/sachinvarma/Speech-Recognizer

Ich hoffe, dass dies in Zukunft jemandem helfen wird.

0
Sachin Varma