Android Speech to text for number and email ID - android

I am using Android Speech to text for speech recognition.
final Intent sttIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
final String language = config.getLanguage().replace('-', '_');
sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, language);
sttIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
sttIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.getPackageName());
// WORKAROUND for https://code.google.com/p/android/issues/detail?id=75347
sttIntent.putExtra("android.speech.extra.EXTRA_ADDITIONAL_LANGUAGES", new String[]{language});
return sttIntent;
I am having problem while getting phone number and email id.
It is not giving proper results.
Suppose if user say "triple two triple three five hundred one"
In this case STT should give me 222333501, but it is giving some number and string as result.
Suppose if user say "abc_cde#gmail.com", in this case also it is giving at the rate of and underscore as strings.
Is there any native way to solve this problem.
I have referred a java utility Convert words to number to convert string to number if valid but i am not sure that would work in all cases.
Any help is appreciated.

Related

Using Locale as String to display different page

I have used this line to check the locale.
String local = context.getResources().getConfiguration().locale.getDisplayCountry();
Toast.MakeText(this,local,Toast.LENGTH_SHORT).show();
It shows Australia (this is where I am).
But I need to display different pages based on locale. so what I have done is
if (local=="Australia")
runpage1();
else
runpage2();
But, it doesn't check the local as "Australia", so straight goes to the else line. I tried like
String x;
if (local=="Australia")
x = "1";
else
x="2";
Toast.MakeText(this,x,Toast.LENGTH_SHORT).show();
It shows 2. ( I am trying to write to make it as simple as possible, so nobody gets confused with previously asked questions)
Can anybody please suggest me why I am being unable to treat locale as String value ?
I have tried using this too.
TelephonyManager teleMgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String myCode = teleMgr.getSimCountryIso();
But, same thing, myCode is also cannot be checked as String.
Any suggestions will be great.
== for test only reference..equals() for check String values. So you have to compare like this :
String x;
if (local.trim().equals("Australia"))
x = "1";
else
x="2";
Toast.MakeText(this,x,Toast.LENGTH_SHORT).show();

Text to speech returns a different non-existant Locale after setting an existing one

original question
I have a standard texttospeech, android.speech.tts.TextToSpeech
I initialize it and set a language by using tts.setLanguage(Locale.getDefault())
That default Locale is de_DE (for germany, correct).
Right after setting it, i ask the tts to give me its language tts.getLanguage()
now it tells me that its set to "deu_DEU"
There is no Locale with that setting. So i cant even check if its set to the right language because i cant find the Locale object that has the matching values.
Issue might be related to Android 4.3, but i didnt find any info.
Background is, that i need to show values with the same decimal symbol, but tts needs the correct symbol or it says "dot" in german which makes NO sense at all.
Conclusion:
A Locale is a container that contains a string that is composed of a language, a country and an optional string. Every text-to-speech engine can return a custom Locale like "eng_USA_texas".
Furthermore the Locale that is returned by the tts engine can only be a "close match" to the wanted Locale. So "en_US" instead of "en_UK".
However, Locale has a method called getLanguage() and it returns the first part of above mentioned string. "en" or "eng". Those Language codes are regulated by ISO and one can hope that everyone sticks to it. (see link in the accepted answer)
So checking for tts.getLanguage().getLanguage().startsWith("en") should always be true if its some form of english language setting and the ISO standards are fulfilled.
It is important to mention that Locales should not be compared by locale_a == locale_b as both can be different objects yet have the same content, they are containers of sort.
Always compare with locale_a.equals(locale_b)
I hope this helps people sort out some problems with tts and language
You're right, it's frustrating how the locale codes the TTS object uses are different to those of the device locale. I don't understand why this decision was made.
To add further complication, the TTS Engine can supply all kinds of different locales, such as eng_US_sarah or en-US-female etc. It's down to the TTS Engine how these are stored and displayed.
I've had to write additional code to iterate through the returned locales and attempt to match them to the locale the system can use, or vica-versa.
To start with, take a look at how the engines you have installed are returning their locale information. You can then start to collate in your code a list to associate 'deu_DEU' to 'de_De'.
This is often simplistic by using split("_") & startsWith(String), but unfortunately not for all locales.
Here's some base code I've used to analyse the installed TTS Engines' locale structure.
private void getEngines() {
final Intent ttsIntent = new Intent();
ttsIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
final PackageManager pm = getActivity().getPackageManager();
final List<ResolveInfo> list = pm.queryIntentActivities(ttsIntent, PackageManager.GET_META_DATA);
final ArrayList<Intent> intentArray = new ArrayList<Intent>(list.size());
for (int i = 0; i < list.size(); i++) {
final Intent getIntent = new Intent();
getIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
getIntent.setPackage(list.get(i).activityInfo.applicationInfo.packageName);
getIntent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
intentArray.add(getIntent);
}
for (int i = 0; i < intentArray.size(); i++) {
startActivityForResult(intentArray.get(i), i);
}
}
#Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
try {
if (data != null) {
System.out.print(data.getStringArrayListExtra("availableVoices").toString());
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
From the above ISO-3 codes and the device locale format, you should be able to come up with something for the locales you are concerned with.
I've been intending to submit an enhancement request to AOSP for a while, as all TTS Engines need to use constant values and extras such as gender etc need to be added to use the TTS Engines to their full capabilities.
EDIT: Further to your edit, note the wording regarding setLanguage(). The individual TTS Engine will try and match as close as possible to the requested locale, but that applied locale may be completely wrong, depending on how lenient the Engine provider is in their code and their response.
After creating an object of TextToSpeech class, you should configure it (or check it's available state/values) into TextToSpeech.OnInitListener's onInit() callback. You will get reliable information there about your TextToSpeech object.
Check my answer here:
https://stackoverflow.com/a/65620221/7835969

How to use more then one language in android speech recognition at the same time

All we know that many languages includes several words from other languages. While using android speech recognition (Androdi4.1) to develop an android application, we need that app process the speech input with two languages (EN and TR) at the same time (or asynch) and bring us both of the results.
English word "Burger" in Turkish pronunciation is "Börgır" .
If we use android speech recognition in english, application understands Burger as Burger
(on text) .
If we use android speech recognition in turkish, application understands Burger as Börgır(on text)
This is because Turkish language is written as spoken.
For example:
speech recognition result with Turkish option: Börgır yemek istiyorum
speech recognition result with English option: Burger xxxxx yyyyyyyyy
Expected result is(with combined result) : Burger yemek istiyorum
So do you know how to process two languages at the same time , with android speech recognition to collect both results, after that we will combine them in order to get best results.
Below code is used for implementing android speech recognition within application:
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
// Specify the calling package to identify your application
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "tr"); --- or eng-us
This can't be done using the current Android APIs.
You could try to run two instances of SpeechRecognizer at the same time (one with a Turkish EXTRA_LANGUAGE, the other with English). This will probably not work because different services cannot use the microphone at the same time.
You could try to implement the recording part yourself and then push the resulting byte array to two different recognizers. But there is no API for that.
I solved it like that:
language = "tr-TR";
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, language);
intent.putExtra(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES, language);
intent.putExtra(RecognizerIntent.EXTRA_ONLY_RETURN_LANGUAGE_PREFERENCE, language);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, language);
intent.putExtra(RecognizerIntent.EXTRA_RESULTS, language);
startActivityForResult(intent, REQUEST_CODE);
I suggest that you pick one language for the speech recognizer like english. Then when you speak your other language, see what the speech recognizer comes up with. You may be able to interpret the english recognition of that.
For example, if you want to speak spanish to the english recognizer and the user says "si" in spanish, you might notice the recognizer recognizes that as "see"

Not able to make a call when #31# is added

I am trying to implement calling facility from my app. When some condition is true, I am hiding my caller id by adding #31# before my number. Although if #31# is not added, call is made perfectly allright but when #31# is added, blank screen pops up, as if the Phone app is loading, and my application screen comes back. My code snippet is this
String ph = "123456789";
String phNumber;
if (hideCallerId) {
phNumber = "#31#" + ph;
}
else {
phNumber = ph;
}
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+phNumber));
startActivity(intent);
Case 1: when phNumber is 123456789, then call is made without problem.
Case 2: when phNumber is #31#123456789, then blank screen pops up and user comes back to my application screen.
Although when I am dialing from my device using #31#123456789, call is successfully made.
What I am missing out. Can anybody help me out.
Links didn't helped me Link1.
Thanks in advance.
This isn't really an answer but my rep isn't high enough for a comment. Is there any chance you have phnumber declared as an int or anything? Maybe the #'s are messing it up?
If that doesn't work have you tried using ACTION_DIAL? the android developer site has more info on the differences between them here. Hope it helps.
You simply have to encode the phone number.
String phonenumber = "03012345,1234,#31#,98765"; // , = pauses
encodedPhonenumber = URLEncoder.encode(phonenumber, "UTF-8");
startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + encodedPhonenumber)));
You may want to have a look at this one. Not able to make a call when #31# is added
You need to encode the '#' because it behaves like a dial command, then if you set your action call intent data with a number starting with '#', it will instead call a blank number, trying to dial a number like 8488449#848 if not encoded will dial 8488449 that's why you need to encode at least the '#' symbol with Uri.encode("#")
for example to dial 8488449#848, i will do the following:
startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:8488449"+Uri.encode("#")+"848"));

How to add grammar to default VoiceDialer App?

I am trying to add a few commands to android default voicedialer app. It has commands like Open, dial, call, redial etc, I want to include lets say 'Find' to it. I have downloaded the source code from here and compiled it in Eclipse. the application sets up Grammar for arguments of these commands like it stores the names and phone numbers of the persons in contact list to generate intents when their names are recognized for CALL JOHN voice command. For CALL in this command it is just comparing the first word of resulting recognized string to "CALL".
I added "FIND" as an extra else if condition in the onRecognitionSuccess() function as shown below:
public class CommandRecognizerEngine extends RecognizerEngine
{
............
protected void onRecognitionSuccess(RecognizerClient recognizerClient) throws InterruptedException
{
.....................
if ("DIAL".equalsIgnoreCase(commands[0]))
{
Uri uri = Uri.fromParts("tel", commands[1], null);
String num = formatNumber(commands[1]);
if (num != null)
{
addCallIntent(intents, uri, literal.split(" ")[0].trim() + " " + num, "", 0);
}
}
................
else if ("FIND".equalsIgnoreCase(commands[0]))
{
if (Config.LOGD)
Log.d(TAG, "FIND detected...");
}
}//end onRecognitionSuccess
}//end CommandRecognizerEngine
but my app can't recognize it. Does anyone know how does recognizer detects commands like OPEN or CALL etc or refer me to appropriate documentation?
Thanks.
As it has been over a year, I doubt you need this answer anymore. However, some other people might find this through Google, as I did.
Right now, the best way to apply grammars to speech recognition on Android is to set the number of results higher, and then filter the results based on your grammar. It is not perfect, as the word recognized may not have passed a threshold to be included in the list, but it does greatly improve the accuracy of all speech recognition applications where the types of things you can say are somewhat limited.

Categories

Resources