TextToSpeech With a String Array - android

I tried to follow this question here String array incrementing each string
but it didn't want to work, What im trying to do is when the button is clicked increment what the TextToSpeech voice is going to say by incrementing the string. therefore start at string 0, then 1 to 2 to 3 to 4 ect and loop back around. heres the code
String Array Code
String [] speakLetters = { "Letter A for Ant", "Letter b for Bat", "Letter C for Cat" ....... , "Letter Z for zoo"};
The array is laid out just fine its just not working when trying to increment. it either says its just ANT for the first one and never increments or it freezes if I change the code.
Code for trying to increment the array
mNextBtn.setOnClickListener(new OnClickListener() {
int cIndex = 0;
int stringLength = speakLetters.length;
String speakNow = speakLetters[stringLength];
cIndex = (cIndex++); // I also tried here cIndex = (cIndex + 1) % stringLength;
tts.speak(speakNow, TextToSpeech.QUEUE_FLUSH, null);
mNextBtn.setEnabled(mSCanvas.isUndoable());
}
Yes I am writing this to an scanvas I wanted to include that just incase that could be the problem even though I doubt it is.
What am I doing wrong?

Declare cIndex variable as class member outside your click listener block:
int cIndex = 0;
and then modify click handler code:
mNextBtn.setOnClickListener(new OnClickListener() {
String speakNow = speakLetters[cIndex];
tts.speak(speakNow, TextToSpeech.QUEUE_FLUSH, null);
cIndex++;
cIndex %= speakLetters.length;
mNextBtn.setEnabled(mSCanvas.isUndoable());
});

Related

Creating resource reference ints programmatically

I am building a quiz app with questions in a string resource, as well as an answer. They are formatted by numbers like so:
<string name="ques1">What color is the sky?</string>
<string name="ques2">What sound does a cow make?</string>
The answers are also strings corresponding to the same number as the questions:
<string name="ans1">Blue</string>
<string name="ans2">Moo</string>
I have created a QA class for holding both a question and the answer, as well as the user's response from an EditText. At the "loading" of my app these classes are created and filled by reading from the strings resource.
I can programmatically enter these no problem, it is a lot of copy pasting but it will get the job done:
QA.setQuestion(getString(R.string.ques1));
QA.setAnswer(getString(R.string.ans1));
quizList.add(QA);
QA.setQuestion(getString(R.string.ques2));
QA.setAnswer(getString(R.string.ans2));
quizList.add(QA);
etc...
The problem is that I want to be able to add questions and answers to the xml at any time without having to add yet another repetition of the above method. What I want to do is essentially this:
String refBase = "R.string."
String ans = "ans";
String ques = "ques";
int numOfQues = 25; //only change when questions are added or removed
for (int i = 0; i < numOfQues; i++)
{
String referenceQ = refBase + ques + i;
String referenceA = refBase + ans + i;
QA.setQuestion(getString(referenceQ));
QA.setAnswer(getString(referenceA));
quizList.add(QA);
}
I cannot cast a string to an int like this obviously, but I am wondering if there is a way to implement a reference "builder", where I don't have to repeat many lines of code just to read another string with the same name but incremented number.
I understand that I can also just create an array.xml with one for questions and one for answers, making sure their position in each array corresponds. This would be easiest I think, but I guess I am wondering if it is possible to create references to string values through the code like my example?
You can use this method to get the question or answer String by its resource name:
String getQAString(boolean isQuestion, int index) {
String prefix = isQuestion? "ques" : "ans";
int resId = getResources().getIdentifier(prefix + index, "string", getPackageName());
return resId != 0? getString(resId) : "";
}
The loop to add questions and answers (assume they start from 1 and end at 25):
int numOfQues = 25;
for (int i = 1; i <= numOfQues; i++) {
String referenceQ = getQAString(true, i);
String referenceA = getQAString(false, i);
QA.setQuestion(referenceQ);
QA.setAnswer(referenceA);
quizList.add(QA);
}

Getting Int from EditText causes error?

So first of all sorry if this has already been asked and answered before, I couldn't find anything relating to my issue.
So I'm working on a project for college and I need to get int values from EditText widgets. I was told to use parseInt to do this however when running my program, that line of code causes the application to crash. I don't know what I'm doing wrong, I'm still very new to android development, thanks for the help :)
public void Calculate (View view)
{
int MilesTravelled;
int FuelUsed;
int MPG;
/* the two lines below are what cause the application to crash */
MilesTravelled = Integer.parseInt(txtMilesTravelled.getText().toString());
FuelUsed = Integer.parseInt(txtFuelUsed.getText().toString());
FuelUsed = (int) (FuelUsed / 4.55);
MPG = MilesTravelled / FuelUsed;
lblMPG.setText(FuelUsed);
}
Do you have this in the onCreate() function?
EditText txtMilesTravelled = (EditText) findViewById(R.id.YourEditText);
But I think you mixed Integer and int. They are not the same:
See this link!
First of all, don't capitalize the first letter of an variables or method names. Following the Java coding conventions, only do that for classes.
What is probably causing your app to crash is you trying to set the text of a label to an integer. The setText method for a TextView needs to take in a string.
So change:
lblMPG.setText(FuelUsed);
to:
lblMPG.setText(String.valueOf(FuelUsed));
Otherwise it might be that it's trying to parse a non-numerical string to an integer.
For exmaple, if the EditText is blank, it will cause your app to crash. To prevent that, try this:
int MilesTravelled = 0, FuelUsed = 0;
try {
MilesTravelled = Integer.parseInt(txtMilesTravelled.getText().toString());
FuelUsed = Integer.parseInt(txtFuelUsed.getText().toString());
} catch (NumberFormatException nfe) {
Toast.makeText(getApplicationContext(), "Error NFE!", 0).show();
nfe.printStackTrace();
}
This way, it will catch a NumberFormatException error (parsing a string to an integer that can't be represented as an integer, such as "hello"). If it catches the error, it will toast that an error has occurred and your integer variables will remain 0.
Or you could just test if the strings contain only digits using the following regex:
int MilesTravelled = 0, FuelUsed = 0;
if (txtMilesTravelled.getText().toString().matches("[0-9]+")) {
MilesTravelled = Integer.parseInt(txtMilesTravelled.getText().toString());
} else {
// contains characters that are not digits
}
if (txtFuelUsed.getText().toString().matches("[0-9]+")) {
FuelUsed = Integer.parseInt(txtFuelUsed.getText().toString());
} else {
// contains characters that are not digits
}
If that's not the problem, then make sure you define your variables properly.
txtMilesTravelled and txtFuelUsed should be EditText:
EditText txtMilesTravelled = (EditText)findViewById(R.id.txtMilesTravelled);
EditText txtFuelUsed = (EditText)findViewById(R.id.txtFuelUsed);
And make sure that your R.id.editText actually exists on your layout and that the IDs are the correct ones.
Last thing, make sure FuelUsed is not 0 before calculating MPG because then you are dividing by 0:
int MPG = 0;
if (FuelUsed != 0) {
MPG = MilesTravelled / FuelUsed;
}
I am assuming that you're entering perfect integers in the EditTexts. It might be a good idea to use the trim function txtMilesTravelled.getText().toString().trim() before using parseInt.
However, I think the major problem is here : lblMPG.setText(FuelUsed);
FuelUsed is an integral value, when you pass an integer to setText(), it looks for a string resource with that integral value. So you should be passing a String to the setText() method.
Use : lblMPG.setText(Integer.toString(FuelUsed));

How to give pause or gap between words in TTS in android

I have given a text in mytts.speak("hi hello hi",parameter,parameter...);
But the words are continuously said without any gap or pause, I want to provide some time gap between words for more clarity.
How could I achieve this ?
If I understand your question correctly, this thread has the answer (by rushi).
Simply add a delay into the TTS queue by splitting the string and loop over the snippets via a for loop:
mytts.speak(snippet, QUEUE_ADD, null);
mytts.playSilentUtterance(2000, QUEUE_ADD, null);
Simply add a comma everywhere you want there to be pauses inserted.
For example: If you want the following web address to be said slower, enter it as a, t, t, r, s.gov
I realize this may not be suitable for some applications, but it definitely works.
This is how I put a longer pause between each word:
//initialize and declare TextToSpeech as tts
//"line" is the String you are trying to speak
char ch = '';
String temp = "";
for(int counter = 0; counter < line.length; counter++)
{
ch = charAt(counter);
temp = temp + ch;
if(ch == ' ' || counter == (line.length() - 1))
{
tts.speak(temp, TextToSpeech.QUE_ADD, null, null);
tts.playSilentUtterance(1000, TextToSpeech.QUEUE_ADD,null);
temp = "";
}
}
Try adding '/ / / / /' to your text. It should give you it some breathing room. If you want a longer pause, try adding more.
You can split you sentence in words and speak them in a for loop in a new thread. Splitting the phrase will give you a little delay, but if you want a longer one you could work on thread and make them wait.
It would be something like this:
final Handler h = new Handler();
String[] words = text.split(" ");
for (final CharSequence word : words) {
Runnable t = new Thread() {
#Override
public void run() {
m_TTS.speak(word, TextToSpeech.QUEUE_ADD, null, "TTS_ID");
}
};
h.postDelayed(t, 1000);
}

Android - Getting User Input As An Integer

I'm a new Android developer. As a starting project, I'm trying to create a basic addition calculator. I have an EditText which is supposed to take the input (input is a string) and convert it to int1 when Button1 is pressed. When Button2 is pressed, it is supposed to take the input, convert it to int2, add int1 and int2 together and store the result in the int ans, and set the text of the EditText to ans. However, when I try to use Integer.parseInt(et.getText().toString()) I get an error and the app force closes. Could anyone provide me with the code to properly convert these Strings to integers? Thank you.
static int fn = 0;
static int sn = 0;
static int ans = 0;
static int pro = 0;
//"+" Button Clicked//
if(pro == 0){
fn = Integer.parseInt(entry.getText().toString());
entry.setText("");
pro++;
}else{
//MessageBox Crap//
//"=" Button Clicked//
sn = Integer.parseInt(entry.getText().toString());
ans = fn + sn;
entry.setText(ans);
Shouldn't ans be converted to a string before you set the contents of the EditText?

Android String Not Equal

I am brand new to Java and Android so I am sure this will be an easy question/answer. I know that to find out if a string is equal to another string you use the equal function. In my situation, I am scanning a QR Code where the result of the scan is Similar to "EMPLOYEE~~John Smith~~DIVISION~~Maintenance". I need to know how to do the following:
String contents = intent.getStringExtra("SCAN_RESULT");
// I know that "contents" contains the string " EMPLOYEE~~John Smith~~DIVISION~~Maintenance"
String[] myJunk = contents.split("~~");
// This should split everything up into an array named myJunk (right)?
String val1 = myJunk[0];
// Now val1 Should be equal to "EMPLOYEE"
if (myJunk[0].equals(val1)){
// Do Something
}
In the example Java Code, myJunk[0] never equals val1. What am I doing wrong?
i've tried this and it works , so try to display the contents variable , probably the problem is in the extras , try to display it in logCat :
String contents = "EMPLOYEE~~John Smith~~DIVISION~~Maintenance";
String[] myJunk = contents.split("~~");
// This should split everything up into an array named myJunk (right)?
String val1 = myJunk[0];
Toast.makeText(this, "val1 = "+val1, Toast.LENGTH_LONG).show();
Toast.makeText(this, "val2 = "+myJunk[1], Toast.LENGTH_LONG).show();
// Now val1 Should be equal to "EMPLOYEE"
if (myJunk[0].equals(val1)){
Toast.makeText(this, "equals", Toast.LENGTH_LONG).show();
}
Your string is:
EMPLOYEE~~John Smith~~DIVISION~~Maintenance
So after spliting, myJunk[0] will contain EMPLOYEE (notice the space in front of the word EMPLOYEE).
So before comparing , you will need to trim your value
The method i usually use, is to print out my variables when in doubt. So if you are unsure of where the problem is, you could try something like this.
(It requires you to be able to see the output, in logcat for example)
String contents = intent.getStringExtra("SCAN_RESULT");
// I know that "contents" contains the string " EMPLOYEE~~John Smith~~DIVISION~~Maintenance"
System.out.println("contents is "+contents );
String[] myJunk = contents.split("~~");
// This should split everything up into an array named myJunk (right)?
System.out.println("Array size is "+myJunk.length);
String val1 = myJunk[0];
// Now val1 Should be equal to "EMPLOYEE"
for(int i=0; i < myJunk.length; i++) {
System.out.println("String "+i+ "in array is: "+myJunk[i]);
}
//Here i run through the array and print every element.
if (myJunk[0].equals(val1)){
// Do Something
}
It is a bit overkill, but this is mostly to show one way of getting all the information you need to find the problem :)

Categories

Resources