Open ghKoty opened 1 year ago
Hi !
I had the same problem with isShowPopupAndroid = false. And for now i fixed it. I'm not on the same version as you.
I had to investigate this problem. And it seams when you're not using the popup, google services can't manage errors.
Thanks to the adb debugger I found multiple exception with a runtime exception --> CRASH.
Like this one:
So I go in the plugin with Android Studio and manage exception for now.
public class MainActivity extends UnityPlayerActivity
{
private TextToSpeech tts;
private SpeechRecognizer speech;
private Intent intent;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tts = new TextToSpeech(this, initListener);
speech = SpeechRecognizer.createSpeechRecognizer(this);
speech.setRecognitionListener(recognitionListener);
}
@Override
public void onDestroy() {
// Don't forget to shutdown tts!
if (tts != null) {
tts.stop();
tts.shutdown();
}
if (speech != null) {
speech.destroy();
}
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && null != data) {
try
{
ArrayList<String> text = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
UnityPlayer.UnitySendMessage("SpeechToText", "onResults", text.get(0));
}
catch(NullPointerException e)
{
Log.i("Unity", "NullPointerException from a onPartialResults " + e.getMessage());
}
}
}
// speech to text
public void OnStartRecording() {
intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, Bridge.languageSpeech);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, Bridge.languageSpeech);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Bridge.languageSpeech);
intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
//intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 2000);
intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 2000);
//intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, 2000);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);
//onLog("test");
/*Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, languageSpeech);
intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, languageSpeech);
intent.putExtra(RecognizerIntent.EXTRA_ONLY_RETURN_LANGUAGE_PREFERENCE, languageSpeech);
intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, Long.valueOf(5000));
intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, Long.valueOf(3000));
intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, Long.valueOf(3000));
if (!prompt.equals("")) intent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);
UnityPlayer.currentActivity.startActivityForResult(intent, RESULT_SPEECH);*/
this.runOnUiThread(new Runnable() {
@Override
public void run() {
speech.startListening(intent);
}
});
UnityPlayer.UnitySendMessage("SpeechToText", "onMessage", "CallStart, Language:" + Bridge.languageSpeech);
}
public void OnStopRecording() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
speech.stopListening();
}
});
UnityPlayer.UnitySendMessage("SpeechToText", "onMessage", "CallStop");
}
public void onLog(String m)
{
UnityPlayer.UnitySendMessage("SpeechToText", "onLog", m.toString());
}
RecognitionListener recognitionListener = new RecognitionListener() {
@Override
public void onReadyForSpeech(Bundle params) {
UnityPlayer.UnitySendMessage("SpeechToText", "onReadyForSpeech", params.toString());
}
@Override
public void onBeginningOfSpeech() {
UnityPlayer.UnitySendMessage("SpeechToText", "onBeginningOfSpeech", "");
}
@Override
public void onRmsChanged(float rmsdB) {
//UnityPlayer.UnitySendMessage("SpeechToText", "onRmsChanged", "" + rmsdB);
}
@Override
public void onBufferReceived(byte[] buffer) {
UnityPlayer.UnitySendMessage("SpeechToText", "onMessage", "onBufferReceived: " + buffer.length);
}
@Override
public void onEndOfSpeech() {
UnityPlayer.UnitySendMessage("SpeechToText", "onEndOfSpeech", "");
}
@Override
public void onError(int error) {
UnityPlayer.UnitySendMessage("SpeechToText", "onError", "" + error);
}
@Override
public void onResults(Bundle results) {
try
{
ArrayList<String> text = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
UnityPlayer.UnitySendMessage("SpeechToText", "onResults", text.get(0));
}
catch (NullPointerException e)
{
Log.i("Unity", "NullPointerException from a onResults " + e.getMessage());
}
}
@Override
public void onPartialResults(Bundle partialResults) {
try
{
ArrayList<String> text = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
UnityPlayer.UnitySendMessage("SpeechToText", "onPartialResults", text.get(0));
}
catch(NullPointerException e)
{
Log.i("Unity", "NullPointerException from a onPartialResults " + e.getMessage());
}
catch(IndexOutOfBoundsException i)
{
Log.i("Unity", "IndexOutOfBoundsException from a onResults " + i.getMessage());
}
}
@Override
public void onEvent(int eventType, Bundle params) {
UnityPlayer.UnitySendMessage("SpeechToText", "onMessage", "onEvent");
}
};
////
public void OnStartSpeak(String valueText)
{
tts.speak(valueText, TextToSpeech.QUEUE_FLUSH, null, valueText);
}
public void OnSettingSpeak(String language, float pitch, float rate) {
tts.setPitch(pitch);
tts.setSpeechRate(rate);
int result = tts.setLanguage(getLocaleFromString(language));
UnityPlayer.UnitySendMessage("TextToSpeech", "onSettingResult", "" + result);
}
public void OnStopSpeak()
{
tts.stop();
}
TextToSpeech.OnInitListener initListener = new TextToSpeech.OnInitListener()
{
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS)
{
OnSettingSpeak(Locale.US.toString(), 1.0f, 1.0f);
tts.setOnUtteranceProgressListener(utteranceProgressListener);
}
}
};
UtteranceProgressListener utteranceProgressListener=new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
UnityPlayer.UnitySendMessage("TextToSpeech", "onStart", utteranceId);
}
@Override
public void onError(String utteranceId) {
UnityPlayer.UnitySendMessage("TextToSpeech", "onError", utteranceId);
}
@Override
public void onDone(String utteranceId) {
UnityPlayer.UnitySendMessage("TextToSpeech", "onDone", utteranceId);
}
};
/**
* Convert a string based locale into a Locale Object.
* Assumes the string has form "{language}_{country}_{variant}".
* Examples: "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr_MAC"
*
* @param localeString The String
* @return the Locale
*/
public static Locale getLocaleFromString(String localeString)
{
if (localeString == null)
{
return null;
}
localeString = localeString.trim();
if (localeString.equalsIgnoreCase("default"))
{
return Locale.getDefault();
}
// Extract language
int languageIndex = localeString.indexOf('_');
String language;
if (languageIndex == -1)
{
// No further "_" so is "{language}" only
return new Locale(localeString, "");
}
else
{
language = localeString.substring(0, languageIndex);
}
// Extract country
int countryIndex = localeString.indexOf('_', languageIndex + 1);
String country;
if (countryIndex == -1)
{
// No further "_" so is "{language}_{country}"
country = localeString.substring(languageIndex+1);
return new Locale(language, country);
}
else
{
// Assume all remaining is the variant so is "{language}_{country}_{variant}"
country = localeString.substring(languageIndex+1, countryIndex);
String variant = localeString.substring(countryIndex+1);
return new Locale(language, country, variant);
}
}
}
I had NullPointerException and IndexOutOfBoundsException to avoid those problems for now. And also had intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true); in the intent started without popup.
So exception are catch and application doesn't crashed !
I need to re-build the plugin also
Android studio not working on my pc, can you give me rebuild of this plugin for Unity?
Hi !
I had the same problem with isShowPopupAndroid = false. And for now i fixed it. I'm not on the same version as you.
- Unity version 2021.3.10
- Android version 8 and 9
I had to investigate this problem. And it seams when you're not using the popup, google services can't manage errors.
Thanks to the adb debugger I found multiple exception with a runtime exception --> CRASH.
Like this one:
So I go in the plugin with Android Studio and manage exception for now.
public class MainActivity extends UnityPlayerActivity { private TextToSpeech tts; private SpeechRecognizer speech; private Intent intent; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); tts = new TextToSpeech(this, initListener); speech = SpeechRecognizer.createSpeechRecognizer(this); speech.setRecognitionListener(recognitionListener); } @Override public void onDestroy() { // Don't forget to shutdown tts! if (tts != null) { tts.stop(); tts.shutdown(); } if (speech != null) { speech.destroy(); } super.onDestroy(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && null != data) { try { ArrayList<String> text = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); UnityPlayer.UnitySendMessage("SpeechToText", "onResults", text.get(0)); } catch(NullPointerException e) { Log.i("Unity", "NullPointerException from a onPartialResults " + e.getMessage()); } } } // speech to text public void OnStartRecording() { intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, Bridge.languageSpeech); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, Bridge.languageSpeech); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Bridge.languageSpeech); intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true); //intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 2000); intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 2000); //intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, 2000); intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName()); intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3); //onLog("test"); /*Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, languageSpeech); intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, languageSpeech); intent.putExtra(RecognizerIntent.EXTRA_ONLY_RETURN_LANGUAGE_PREFERENCE, languageSpeech); intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, Long.valueOf(5000)); intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, Long.valueOf(3000)); intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, Long.valueOf(3000)); if (!prompt.equals("")) intent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt); UnityPlayer.currentActivity.startActivityForResult(intent, RESULT_SPEECH);*/ this.runOnUiThread(new Runnable() { @Override public void run() { speech.startListening(intent); } }); UnityPlayer.UnitySendMessage("SpeechToText", "onMessage", "CallStart, Language:" + Bridge.languageSpeech); } public void OnStopRecording() { this.runOnUiThread(new Runnable() { @Override public void run() { speech.stopListening(); } }); UnityPlayer.UnitySendMessage("SpeechToText", "onMessage", "CallStop"); } public void onLog(String m) { UnityPlayer.UnitySendMessage("SpeechToText", "onLog", m.toString()); } RecognitionListener recognitionListener = new RecognitionListener() { @Override public void onReadyForSpeech(Bundle params) { UnityPlayer.UnitySendMessage("SpeechToText", "onReadyForSpeech", params.toString()); } @Override public void onBeginningOfSpeech() { UnityPlayer.UnitySendMessage("SpeechToText", "onBeginningOfSpeech", ""); } @Override public void onRmsChanged(float rmsdB) { //UnityPlayer.UnitySendMessage("SpeechToText", "onRmsChanged", "" + rmsdB); } @Override public void onBufferReceived(byte[] buffer) { UnityPlayer.UnitySendMessage("SpeechToText", "onMessage", "onBufferReceived: " + buffer.length); } @Override public void onEndOfSpeech() { UnityPlayer.UnitySendMessage("SpeechToText", "onEndOfSpeech", ""); } @Override public void onError(int error) { UnityPlayer.UnitySendMessage("SpeechToText", "onError", "" + error); } @Override public void onResults(Bundle results) { try { ArrayList<String> text = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); UnityPlayer.UnitySendMessage("SpeechToText", "onResults", text.get(0)); } catch (NullPointerException e) { Log.i("Unity", "NullPointerException from a onResults " + e.getMessage()); } } @Override public void onPartialResults(Bundle partialResults) { try { ArrayList<String> text = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); UnityPlayer.UnitySendMessage("SpeechToText", "onPartialResults", text.get(0)); } catch(NullPointerException e) { Log.i("Unity", "NullPointerException from a onPartialResults " + e.getMessage()); } catch(IndexOutOfBoundsException i) { Log.i("Unity", "IndexOutOfBoundsException from a onResults " + i.getMessage()); } } @Override public void onEvent(int eventType, Bundle params) { UnityPlayer.UnitySendMessage("SpeechToText", "onMessage", "onEvent"); } }; //// public void OnStartSpeak(String valueText) { tts.speak(valueText, TextToSpeech.QUEUE_FLUSH, null, valueText); } public void OnSettingSpeak(String language, float pitch, float rate) { tts.setPitch(pitch); tts.setSpeechRate(rate); int result = tts.setLanguage(getLocaleFromString(language)); UnityPlayer.UnitySendMessage("TextToSpeech", "onSettingResult", "" + result); } public void OnStopSpeak() { tts.stop(); } TextToSpeech.OnInitListener initListener = new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { OnSettingSpeak(Locale.US.toString(), 1.0f, 1.0f); tts.setOnUtteranceProgressListener(utteranceProgressListener); } } }; UtteranceProgressListener utteranceProgressListener=new UtteranceProgressListener() { @Override public void onStart(String utteranceId) { UnityPlayer.UnitySendMessage("TextToSpeech", "onStart", utteranceId); } @Override public void onError(String utteranceId) { UnityPlayer.UnitySendMessage("TextToSpeech", "onError", utteranceId); } @Override public void onDone(String utteranceId) { UnityPlayer.UnitySendMessage("TextToSpeech", "onDone", utteranceId); } }; /** * Convert a string based locale into a Locale Object. * Assumes the string has form "{language}_{country}_{variant}". * Examples: "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr_MAC" * * @param localeString The String * @return the Locale */ public static Locale getLocaleFromString(String localeString) { if (localeString == null) { return null; } localeString = localeString.trim(); if (localeString.equalsIgnoreCase("default")) { return Locale.getDefault(); } // Extract language int languageIndex = localeString.indexOf('_'); String language; if (languageIndex == -1) { // No further "_" so is "{language}" only return new Locale(localeString, ""); } else { language = localeString.substring(0, languageIndex); } // Extract country int countryIndex = localeString.indexOf('_', languageIndex + 1); String country; if (countryIndex == -1) { // No further "_" so is "{language}_{country}" country = localeString.substring(languageIndex+1); return new Locale(language, country); } else { // Assume all remaining is the variant so is "{language}_{country}_{variant}" country = localeString.substring(languageIndex+1, countryIndex); String variant = localeString.substring(countryIndex+1); return new Locale(language, country, variant); } } }
I had NullPointerException and IndexOutOfBoundsException to avoid those problems for now. And also had intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true); in the intent started without popup.
So exception are catch and application doesn't crashed !
I need to re-build the plugin also
hey buddy, I have done the change you mentioned, in the android project. Could you please tell shortly how do I rebuild the plugin in android studio.? I mean I tried rebuilding the project in android studio but I believe i need a .jar file for the unity plugin right?
hey buddy, I have done the change you mentioned, in the android project. Could you please tell shortly how do I rebuild the plugin in android studio.? I mean I tried rebuilding the project in android studio but I believe i need a .jar file for the unity plugin right?
I know I'm a bit late to this issue, but this worked for me:
.aar
file (SpeechToText\app\build\outputs\aar) created by Android Studio..aar
file..zip
extension.classes.jar
file inside the extracted folder to SpeechToTextPlugin.jar
.Also, this issue might have something to do with this: [Bug] Null results with Voice Recognition Service...
In my case, I am getting the speech results in onPartialResults
but null in onResults
.
hey buddy, I have done the change you mentioned, in the android project. Could you please tell shortly how do I rebuild the plugin in android studio.? I mean I tried rebuilding the project in android studio but I believe i need a .jar file for the unity plugin right?
I know I'm a bit late to this issue, but this worked for me:
- Rebuild the project as you did.
- Go to the location of the
.aar
file (SpeechToText\app\build\outputs\aar) created by Android Studio.- Create a duplicate of the
.aar
file.- Rename it with the
.zip
extension.- Extract the ZIP file.
- Rename the
classes.jar
file inside the extracted folder toSpeechToTextPlugin.jar
.- Import it into Unity.
Do you have the .jar? I really never use Android Studio and I don't know how it works....
Do you have the .jar? I really never use Android Studio and I don't know how it works....
You can download the .jar
file here: https://github.com/Uralstech/speech-and-text-unity-ios-android/releases/tag/1.0.0
I have made a few other changes - if you're interested you can check the commits: https://github.com/j1mmyto9/speech-and-text-unity-ios-android/compare/main...Uralstech:speech-and-text-unity-ios-android:main
Hi @Uralstech, When i use SpeechToTextPlugin.jar from main source, app get crashes when speak stop in onResults. because its has null value, when i try to use jar from link you share its not crashing now. but its does not print result because its null. when enable show android popup - when start recording - can see the result when user stop speaking but not using speech popup android, cant get the same result when user stop speaking. how to solve this issue.
Hi @Uralstech, When i use SpeechToTextPlugin.jar from main source, app get crashes when speak stop in onResults. because its has null value, when i try to use jar from link you share its not crashing now. but its does not print result because its null. when enable show android popup - when start recording - can see the result when user stop speaking but not using speech popup android, cant get the same result when user stop speaking. how to solve this issue.
Hi! Thanks for checking out my fork, @JebarajDaniel!
You will have to keep track of the partial results in a variable, like this:
private string _partialResults;
private void Start()
{
// STT & TTS setup code goes here.
SpeechToText.Instance.onResultCallback += (results) =>
{
if (string.IsNullOrEmpty(results))
Debug.Log(_partialResults);
else
Debug.Log(results);
_partialResults = string.Empty;
};
SpeechToText.Instance.onPartialResultsCallback += (partialResults) => _partialResults = partialResults;
}
hi @Uralstech thanks for reaching out. Do you have the .jar file with this changes? I really never use Android Studio before and I don't know how it works.... if you help me - how to make jar file with this changes - its very great to learn new thing from now on. thanks
Do you have the .jar? I really never use Android Studio and I don't know how it works....
You can download the
.jar
file here: https://github.com/Uralstech/speech-and-text-unity-ios-android/releases/tag/1.0.0 I have made a few other changes - if you're interested you can check the commits: main...Uralstech:speech-and-text-unity-ios-android:main
You can find the .jar
file here. If you want to build the latest code, follow these steps:
Clone the repository: Clone or download the repository.
Open in Android Studio: Open the project in Android Studio to build the native plugin.
Modify as Needed: You can make changes to the Java source files as per your project's requirements.
Build the Plugin: Use Android Studio's build tools to compile and generate a new .aab
file.
Integrate with Unity: Replace the existing plugin in your Unity project with the newly built version, if necessary.
Some information:
If isShowPopupAndroid = true it's working fine, but if isShowPopupAndroid = false it's not working: