This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
im trying to compare a text in android to avoid refreshing texts if it's not necessary (otherwise the texts for different fields are refreshed every 50ms).
With normal texts it is not a problem. Everything works fine.
But: If there are numbers in text the text seems not to be equal. Why?
Some examples:
"Abschaltpunkt" is equal to "Abschaltpunkt" (OK) /
"Gewicht" is equal to "Gewicht" (OK) /
"100 kg" is NOT equal to "100 kg" (NOK) /
"Abschaltpunkt 2" is NOT equal to "Abschaltpunkt 2" (NOK"
A new question after edit (the comparsion works fine now).
As you see I use the UI thread for refreshing the text. This app works in a network and receives arround 300 messages per second with different data (yes, it is necessary). Therefore I need the comparsion otherwise the thread is blocked and the app won't respond on user inputs.
Is there another solution? Or is my solution a good one?
This is my code:
/**
* Compares the current and new text und updates the text if necessary
* #param RessourceID given by R.id...
* #param New text
*/
private void ChangeText (final int RessourceID, final String sText) {
try {
TextView tv = (TextView) findViewById(RessourceID);
// Erst prüfen ob Text ersetzt werden muss -> Spart Rechenzeit
if (tv.getText().toString().equals(sText)) {
Log.e(this.getClass().getSimpleName(), "Text nicht ersetzen: " + tv.getText() + " != " + sText);
} else {
ChangeTextThread(tv, sText);
Log.e(this.getClass().getSimpleName(), "Text ersetzen: " + tv.getText() + " != " + sText );
}
} catch (Throwable t) {
Log.e(this.getClass().getSimpleName(), "ChangeText", t);
}
}
/**
* Change the text in UI tread
*/
private void ChangeTextThread (final TextView tv, final String sText) {
this.runOnUiThread(new Runnable() {
public void run() {
try {
tv.setText(sText);
} catch (Throwable t) {
Log.e(this.getClass().getSimpleName(), "ChangeTextThread", t);
}
}
});
}
try this way
if(tv.getText().toString().equals(sText))
Used .equals() or .equalsIgnoreCase() method for string comparison
Try below code:
if(tv.getText().toString.equalsIgnoreCase(sText)){
//Do your stuff here
}
Related
I'm using onPartialResult method to look if the hypotesis is one of the keyword I'm interested in and it works well.
Here's my code:
#Override
public void onPartialResult(Hypothesis hypothesis) {
Log.d(TAG, "onPartialResult");
if (hypothesis == null) {
return;
}
String text = hypothesis.getHypstr();
String wordWithProb = "";
String mostProbableWord = "";
int probability = -10000;
if (text.contains("|")) {
for (Segment seg : recognizer.getDecoder().seg()) {
wordWithProb += "|" + seg.getWord() + " " + seg.getProb() + "|";
if (seg.getProb() > probability)
mostProbableWord = seg.getWord().trim();
}
}
else
mostProbableWord = text.trim();
Log.i(TAG, "onPartialResults: " + mostProbableWord);
String recognizedCommand = "Please repeat";
if (mostProbableWord.equals("one")) {
//do something...
} else if (mostProbableWord.equals("two")) {
//do something...
} else if (mostProbableWord.equals("three")) {
//do something...
}
//text to speech
speak(recognizedCommand);
startListening(KWS_SEARCH);
}
Now I would like to handle the case where a user say something and it is not recognized as a keyword; in this case the hypotesis in the onPartialResult method is always null: is this expected? I was expecting a not null hypotesis here...
Considering that onPartialResult method is automatically called by pocketsphinx consinuously (also when there isn't any sound in the air) I cannot use the null hypothesis as my driving condition.
Moreover there is a text to speech after every recognition and so the recognition listener restart has to be handled carefully: recognizer must not be listening while text to speech is ongoing...
I tried some solution with onEndOfSpeech but none was good until now...
Any idea?
in this case the hypotesis in the onPartialResult method is always null: is this expected?
Yes
Moreover there is a text to speech after every recognition and so the recognition listener restart has to be handled carefully: recognizer must not be listening while text to speech is ongoing
Correct
I'm modifying the pocketsphinx android demo to test continuous keywords spotting based on a keywords list and relative thresholds.
When the onResult method of my implementation of edu.cmu.pocketsphinx.RecognitionListener is called this string
hypothesis.getHypstr() will contain the list of possible matches.
I read here that to get every single match and their weights it is possible to do like this:
for (Segment seg : recognizer.getDecoder().seg()) {
System.out.println(seg.getWord() + " " + seg.getProb());
}
However my code running is never iterating over segments like if SegmentList was empty while hypothesis.getHypstr() shows more than one match.
To reproduce the case I'm using this keyword list with very low tresholds so that more matches are easily found:
rainbow /1e-50/
about /1e-50/
blood /1e-50/
energies /1e-50/
My onPartialResult method is doing nothing while:
public void onEndOfSpeech() {
switchSearch(KWS_SEARCH);
}
public void onResult(Hypothesis hypothesis) {
if (hypothesis != null) {
for (Segment seg : recognizer.getDecoder().seg()) {
//No iteration is done here!!!
Log.d("onResult", seg.getWord() + " " + seg.getProb());
}
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
}
For example if I say "energies" then hypothesis.getHypstr()="blood about energies blood" but no iteration is done over SegmentList: I can see it by putting a breakpoint at the beginning of the onResult method.
Any suggestion?
Thanks
There is a threading issue here. onResult message is delivered when recognizer is already restarted in switchSearch and so hypothesis is cleared and query for result returns nothing.
You can put this code inside switchSearch before recognizer is restarted, then it will work ok:
private void switchSearch(String searchName) {
boolean wasRunning = recognizer.stop();
if (wasRunning) {
for (Segment seg : recognizer.getDecoder().seg()) {
Log.d("!!!! ", seg.getWord());
}
}
// If we are not spotting, start listening with timeout (10000 ms or 10 seconds).
if (searchName.equals(KWS_SEARCH))
recognizer.startListening(searchName);
else
recognizer.startListening(searchName, 10000);
String caption = getResources().getString(captions.get(searchName));
((TextView) findViewById(R.id.caption_text)).setText(caption);
}
If you use only keyword spotting, you can also put this code inside onPartialResult which is invoked as soon as keyphrase is detected, not when silence is detected. That makes reaction faster. You do not need onEndOfSpeech and onResult in pure keyword spotting.
I have made an calculation, took of the decimals but now i would like to make so that it show a down rounded number.
I found that i can use math.floor but i can't get it in the code.
I took the decimals off but can't get it to round down.
code is like this (the part which does the math):
public void onClick(View view) {
if (etBarfles.getText().toString().equals("")) {
Toast.makeText(getActivity(), "Vul zowel bar in fles, inhoud fles als liters per " +
"minuut in!", Toast.LENGTH_SHORT).show();
} else {
if (etInhoudfles.getText().toString().equals("")) {
Toast.makeText(getActivity(), "Vul zowel bar in fles, inhoud fles als liters per " +
"minuut in!", Toast.LENGTH_SHORT).show();
} else {
if (etLitersperminuut.getText().toString().equals("")) {
Toast.makeText(getActivity(), "Vul zowel bar in fles, inhoud fles als liters " +
"per minuut in!", Toast.LENGTH_SHORT).show();
} else {
}
tvResult.setText(nodecimals((((Float.parseFloat(etBarfles.getText().toString()) *
(Float.parseFloat(etInhoudfles.getText().toString())) / (Float.parseFloat
(etLitersperminuut.getText().toString()))) / 60))));
}
}
}
private String nodecimals(float val) {
return String.format("%.0f", val);
}
Try the following
tvResult.setText(String.valueOf((int) Math.floor(((Float.parseFloat(etBarfles.getText()
.toString()) *
(Float.parseFloat(etInhoudfles.getText().toString())) / (Float.parseFloat
(etLitersperminuut.getText().toString()))) / 60))));
(int) Math.floor() will convert the value to an integer floor value, and then String.valueOf() will convert that int to String, so that you can set the same to the TextView.
THINGS TO IMPROVE:
You can make your code better by following these guidelines:
You are using the same line etBarfles.getText().toString() in multiple places for your check conditions. Its best if you initialize a variable with that value. Something like
String etBarFilesText = etBarfles.getText().toString();
Your condition etBarfles.getText().toString().equals("") can be written the Android way as follows
!TextUtils.isEmpty(etBarFilesText)
Your strings should be defined in your strings.xml. So if your error msgd is named error_string in the strings.xml then your Toast message will look something like this.
Toast.makeText(getActivity(), getString(R.string.error_string), Toast.LENGTH_SHORT).show();
Your line
tvResult.setText(nodecimals((((Float.parseFloat(etBarfles.getText().toString()) *
(Float.parseFloat(etInhoudfles.getText().toString())) / (Float.parseFloat
(etLitersperminuut.getText().toString()))) / 60))));
could have been wayy simpler, and more readable if you used different variables, instead of writing everything in a big single sentence.
Can someone help me, I'm killing myself over here. So in my activity I have this code and the application constantly displays that CurrentQ is not equal (currentQ.getODG() != answer.getText()) to the answer
I can see through LogCat with Log.d that the words are identical. I just can't understand what am I doing wrong.
08-25 05:28:45.125: D/yourans(25316): na život u mraku na život u mraku
this is from log cat
RadioGroup grp = (RadioGroup) findViewById(R.id.radioGroup1);
answer = (RadioButton) findViewById(grp.getCheckedRadioButtonId());
Log.d("yourans", currentQ.getODG() + " " + answer.getText());
if (currentQ.getODG().equals(answer.getText())) {
answer.setBackgroundResource(R.drawable.radiotocan);
Toast poruka1 = Toast.makeText(getApplicationContext(), "Točno!",
Toast.LENGTH_LONG);
View vieew1 = poruka1.getView();
// vieew.setBackgroundColor(Color.parseColor("#BD8BDC"));
vieew1.setBackgroundResource(R.drawable.toast1);
poruka1.setView(vieew1);
poruka1.setGravity(Gravity.CENTER_HORIZONTAL, 1, 1);
poruka1.show();
score1++;
Log.d("score1", "Your score" + score1);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
answer.setBackgroundResource(R.drawable.radiomain);
}
}, 300);
}
else if (currentQ.getODG() != answer.getText()) {
answer.setBackgroundResource(R.drawable.radionetocan);
Toast poruka2 = Toast.makeText(getApplicationContext(),
"Netočno, točan odgovor je:" + currentQ.getODG(),
Toast.LENGTH_LONG);
View vieew2 = poruka2.getView();
// vieew.setBackgroundColor(Color.parseColor("#BD8BDC"));
vieew2.setBackgroundResource(R.drawable.toast);
poruka2.setView(vieew2);
poruka2.setGravity(Gravity.CENTER_HORIZONTAL, 1, 1);
poruka2.show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
answer.setBackgroundResource(R.drawable.radiomain);
}
}, 300);
}
Try
if(currentQ.getODG().equalsIgnoreCase(answer.getText()))
instead of
if(currentQ.getODG()!=answer.getText())
Hope it helps!
Java uses the double-equals sign to check to see if the objects the two variables point to are the same object, not whether they are equivalent. Since both Strings are each returned by two separate method calls, they will never be the same object.
Instead you'll want to use one of the equality-testing methods from the String class:
.equals(String b) Tests to see if the two strings are exactly the same.
.equalsIgnoreCase(String b) Tests to see if the two strings are the same, ignoring whether they're uppercase or lowercase.
There are more options you can find in the String class's documentation, just check the public methods list.
In your case, change this line:
else if (currentQ.getODG() != answer.getText()) {
To read like:
else if (!currentQ.getODG().equals(answer.getText())) {
But for more flexibility in recognizing answers, use .equalsIgnoreCase() like this:
else if (!currentQ.getODG().equalsIgnoreCase(answer.getText())) {
try this:
change:
currentQ.getODG().equals(answer.getText())
to:
currentQ.getODG().trim().equalsIgnoreCase(answer.getText().trim())
change:
else if (currentQ.getODG() != answer.getText())
to:
else
I think probably there's blank space in your string, so use trim() to cut them out, then compare the strings while ignoring capital letter.
FYI: Reference.
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
Probably this will be so stupid to be asked, but I can't find the way to make it works and even to find the solution on Internet.
I need to concatenate 2 strings (variable STR_Prefix and string "TA+") to create a new one ("ATA+" or "BTA+"), then I have to check the value in an if-statement, but it fails, the if-statement doesn't detect the "ATA+".
But if I set the value of "STR_Action" directly to "ATA+" it works perfectly.
public void Test(boolean ok)
{
String STR_Action = "";
if (ok) { STR_Prefix = "A"; }
else { STR_Prefix = "B"; }
/* I have tried some ways to concatenate */
STR_Action = STR_Prefix + "TA+"; // Not working with the if-statement
// STR_Action = new StringBuilder(STR_Prefix).append("TA+").toString(); // Not working with the if-statement
/* But if-statement only works when I set STR_Action directly with = "ATA+" or "BTA+"; */
// STR_Action = "ATA+"; // This assign is detected by the if-statement
if (STR_Action == "ATA+")
{
Toast.makeText(getApplicationContext(), "ATA+", 0).show();
}
else if (STR_Action == "BTA+")
{
Toast.makeText(getApplicationContext(), "ATA-", 0).show();
}
else
{
Toast.makeText(getApplicationContext(), "Code not found", 0).show();
}
}
Please, help :'(
Thanks in advance
try this way used .equals() method for String comparison
if (STR_Action.equals("ATA+"))