Clear the contents of an EditText Field once button is pressed - android

I am creating a simple app which automatically triggers a button b once the contents of an EditText field called a contains a key phrase. I am wanting to clear the contents of the edit text field automatically say after 2 seconds. Is there a easy way to implement this into my code below?
public class PocketSphinxActivity extends Activity implements RecognitionListener
{
private static final String KWS_SEARCH = "wakeup";
/* Keyword we are looking for to activate menu */
private static final String KEYPHRASE = "open voice command"; //adjust this keyphrase!
private SpeechRecognizer recognizer;
private HashMap<String, Integer> captions;
ListView lv;
TextView tv;
EditText a;
Button b;
Button c;
Boolean isDone = false;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
// Prepare the data for UI
captions = new HashMap<String, Integer>();
captions.put(KWS_SEARCH, R.string.kws_caption);
setContentView(R.layout.main);
((TextView) findViewById(R.id.caption_text))
.setText("Preparing the recognizer");
lv = (ListView) findViewById(R.id.lvVoiceReturn);
tv = (TextView) findViewById(R.id.result_text);
a = (EditText) findViewById(R.id.TFusername);
b = (Button) findViewById(R.id.bVoice);
c = (Button)findViewById(R.id.Blogin);
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
new AsyncTask<Void, Void, Exception>() {
#Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(PocketSphinxActivity.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
#Override
protected void onPostExecute(Exception result) {
if (result != null) {
((TextView) findViewById(R.id.caption_text))
.setText("Failed to init recognizer " + result);
} else {
switchSearch(KWS_SEARCH);
}
}
}.execute();
//line added.../////////////////////////
a.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().trim().equalsIgnoreCase("open voice command")) {
//
//Do your stuff here OR button.performClick()
//
//DELAY
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (!isDone) {
b.performClick();
isDone = true;
}
}
}, 500);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
////////////////////////////////////////
}
#Override
public void onDestroy() {
super.onDestroy();
recognizer.cancel();
recognizer.shutdown();
}
/**
* In partial result we get quick updates about current hypothesis. In
* keyword spotting mode we can react here, in other modes we need to wait
* for final result in onResult.
*/
#Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null)
return;
String text = hypothesis.getHypstr();
//((TextView) findViewById(R.id.result_text)).setText(text);
((EditText) findViewById(R.id.TFusername)).setText(text);
}
/**
* This callback is called when we stop the recognizer.
*/
#Override
public void onResult(Hypothesis hypothesis) {
//((TextView) findViewById(R.id.result_text)).setText("");
((EditText) findViewById(R.id.TFusername)).setText("");
if (hypothesis != null) {
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
//a.setText((String) tv.getText());
//tv = TextView.getText().toString();
}
}
#Override
public void onBeginningOfSpeech() {
}
/**
* We stop recognizer here to get a final result
*/
#Override
public void onEndOfSpeech() {
if (!recognizer.getSearchName().equals(KWS_SEARCH))
switchSearch(KWS_SEARCH);
}
private void switchSearch(String searchName) {
recognizer.stop();
// 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);
}
private void setupRecognizer(File assetsDir) throws IOException {
// The recognizer can be configured to perform multiple searches
// of different kind and switch between them
recognizer = defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
// To disable logging of raw audio comment out this call (takes a lot of space on the device)
.setRawLogDir(assetsDir)
// Threshold to tune for keyphrase to balance between false alarms and misses
.setKeywordThreshold(1e-45f)
// Use context-independent phonetic search, context-dependent is too slow for mobile
.setBoolean("-allphone_ci", true)
.getRecognizer();
recognizer.addListener(this);
/** In your application you might not need to add all those searches.
* They are added here for demonstration. You can leave just one.
*/
// Create keyword-activation search.
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
}
#Override
public void onError(Exception error) {
((TextView) findViewById(R.id.caption_text)).setText(error.getMessage());
}
#Override
public void onTimeout() {
switchSearch(KWS_SEARCH);
}
//Assign button clicks to go to a new activity:
public void onButtonClick_1(View v){
if (v.getId() == R.id.bVoice){
String str_1 = a.getText().toString();
//Go to the relevant page if any part of the phrase or word entered in the 'EditText' field contains 'command' which is not case sensitive
if (str_1.toLowerCase().contains("command")) {
Intent userintent = new Intent(PocketSphinxActivity.this, Gvoice.class);
startActivity(userintent);
} else {
Toast.makeText(getApplicationContext(), "Incorrect Information", Toast.LENGTH_SHORT).show();
}
}
}
//Added this to clear the 'open voice command' text when pressing back from a activity window
//This at the moment seems to only work when typing the command, If I use speech to text to say'open voice command
#Override
public void onResume(){
super.onResume();
isDone = false;
a.setText("");
}
}
Additionally, due to using a boolean method, if I go back to this activity using the back button etc in my app, it does not seem to trigger the option again. Is there a way to cause it to trigger b again if I return back to the same window/activity?
I'll really appreciate some useful help in modifying part of my code shown above.

For the first part, you're actually doing it already on your code. The only thing that I don't understand is as to why do you have the boolean isDone? Have you tried removing it? Since if you already cleared the EditText, even if it does go through onTextChanged again, it wont pass the first condition again (Here I'm presuming that bs action is to clear the text of a).
For the text checking, I think you can use androids TextUtils.equals() :
TextUtils.equals(s, "open voice command");
EDIT
Okay. So I re-analyzed your post and your comments and ended up with this flow of behavior.
The First time the activity runs, when you type in "open voice command" in EditText a, Button b will be automatically clicked and will proceed to starting an activity and MUST clear EditText a. Pressing back to the activity that contains both EditText a and Button b, you want the EditText a onTextChangeListener to still function.
With those in mind, I ended up modifying your code as below:
public class MainActivity extends AppCompatActivity {
EditText a;
Button b;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize Views
a = (EditText) findViewById(R.id.a);
b = (Button) findViewById(R.id.b);
// Initialize listeners
a.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (TextUtils.equals(s, "open voice command")) {
Log.d("SAMPLE", ">>>>>>> Running handler!....");
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
a.setText(null);
b.performClick();
}
}, 500);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SampleActivity.class);
startActivity(intent);
}
});
}
}
When I type in "open voice command" in EditText a, is automatically gets cleared and calls the performClick() for Button b. After I get back to the activity. Nothing happens, the handler doesn't run since the text value of EditText a is empty. The handler will only trigger again if you type in "open voice command".
EDIT 2
Here is the code I am running. I just commented out most of the codes that are not related to the concern on your post. I'm getting the correct behavior you are aiming for.
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.speech.RecognitionListener;
import android.speech.SpeechRecognizer;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
public class PocketSphinxActivity extends Activity implements RecognitionListener {
private static final String KWS_SEARCH = "wakeup";
/* Keyword we are looking for to activate menu */
private static final String KEYPHRASE = "open voice command"; //adjust this keyphrase!
private SpeechRecognizer recognizer;
private HashMap<String, Integer> captions;
ListView lv;
TextView tv;
EditText a;
Button b;
Button c;
Boolean isDone = false;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_main);
// Prepare the data for UI
// captions = new HashMap<String, Integer>();
// captions.put(KWS_SEARCH, R.string.kws_caption);
// ((TextView) findViewById(R.id.caption_text))
// .setText("Preparing the recognizer");
// lv = (ListView) findViewById(R.id.lvVoiceReturn);
// tv = (TextView) findViewById(R.id.result_text);
a = (EditText) findViewById(R.id.a);
b = (Button) findViewById(R.id.b);
// c = (Button) findViewById(R.id.Blogin);
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
// new AsyncTask<Void, Void, Exception>() {
// #Override
// protected Exception doInBackground(Void... params) {
// try {
// Assets assets = new Assets(PocketSphinxActivity.this);
// File assetDir = assets.syncAssets();
// setupRecognizer(assetDir);
// } catch (IOException e) {
// return e;
// }
// return null;
// }
//
// #Override
// protected void onPostExecute(Exception result) {
// if (result != null) {
// ((TextView) findViewById(R.id.caption_text))
// .setText("Failed to init recognizer " + result);
// } else {
// switchSearch(KWS_SEARCH);
// }
// }
// }.execute();
//line added.../////////////////////////
a.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().trim().equalsIgnoreCase("open voice command")) {
//
//Do your stuff here OR button.performClick()
//
//DELAY
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (!isDone) {
b.performClick();
isDone = true;
}
}
}, 500);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
////////////////////////////////////////
}
#Override
public void onDestroy() {
super.onDestroy();
// recognizer.cancel();
// recognizer.shutdown();
}
/**
* In partial result we get quick updates about current hypothesis. In
* keyword spotting mode we can react here, in other modes we need to wait
* for final result in onResult.
*/
// #Override
// public void onPartialResult(Hypothesis hypothesis) {
// if (hypothesis == null)
// return;
//
// String text = hypothesis.getHypstr();
// //((TextView) findViewById(R.id.result_text)).setText(text);
// ((EditText) findViewById(R.id.TFusername)).setText(text);
// }
/**
* This callback is called when we stop the recognizer.
*/
// #Override
// public void onResult(Hypothesis hypothesis) {
// //((TextView) findViewById(R.id.result_text)).setText("");
// ((EditText) findViewById(R.id.TFusername)).setText("");
// if (hypothesis != null) {
// String text = hypothesis.getHypstr();
// makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
//
//
// //a.setText((String) tv.getText());
// //tv = TextView.getText().toString();
// }
// }
/**
* We stop recognizer here to get a final result
*/
#Override
public void onEndOfSpeech() {
// if (!recognizer.getSearchName().equals(KWS_SEARCH))
// switchSearch(KWS_SEARCH);
}
private void switchSearch(String searchName) {
// recognizer.stop();
//
// // 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);
}
private void setupRecognizer(File assetsDir) throws IOException {
// The recognizer can be configured to perform multiple searches
// of different kind and switch between them
// recognizer = defaultSetup()
// .setAcousticModel(new File(assetsDir, "en-us-ptm"))
// .setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
//
// // To disable logging of raw audio comment out this call (takes a lot of space on the device)
// .setRawLogDir(assetsDir)
//
// // Threshold to tune for keyphrase to balance between false alarms and misses
// .setKeywordThreshold(1e-45f)
//
// // Use context-independent phonetic search, context-dependent is too slow for mobile
// .setBoolean("-allphone_ci", true)
//
// .getRecognizer();
// recognizer.addListener(this);
/** In your application you might not need to add all those searches.
* They are added here for demonstration. You can leave just one.
*/
// Create keyword-activation search.
// recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
}
// #Override
// public void onError(Exception error) {
// ((TextView) findViewById(R.id.caption_text)).setText(error.getMessage());
// }
// #Override
// public void onTimeout() {
// switchSearch(KWS_SEARCH);
// }
//Assign button clicks to go to a new activity:
public void onButtonClick_1(View v) {
if (v.getId() == R.id.b) {
String str_1 = a.getText().toString();
//Go to the relevant page if any part of the phrase or word entered in the 'EditText' field contains 'command' which is not case sensitive
if (str_1.toLowerCase().contains("command")) {
Intent userintent = new Intent(PocketSphinxActivity.this, Gvoice.class);
startActivity(userintent);
} else {
Toast.makeText(getApplicationContext(), "Incorrect Information", Toast.LENGTH_SHORT).show();
}
}
}
//Added this to clear the 'open voice command' text when pressing back from a activity window
//This at the moment seems to only work when typing the command, If I use speech to text to say'open voice command
#Override
public void onResume() {
super.onResume();
isDone = false;
a.setText("");
}
}

Related

I want to stop my thread when press the back button and on button click (Android studio)

my android application has two activities, when i press the on click button in main activity its move to 2nd activity and read the Bluetooth serial data values using following thread function. I want to stop the thread when i press the back button. or when press the on-click button on 2nd activity. Please help I'm new to android.
my thread function
void beginListenForData()
{
final Handler handler = new Handler();
stopThread = false;
buffer = new byte[1024];
Thread thread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopThread)
{
try
{
int byteCount = inputStream1.available();
if(byteCount > 0)
{
byte[] rawBytes = new byte[byteCount];
inputStream1.read(rawBytes);
final String string=new String(rawBytes,"UTF-8");
handler.post(new Runnable() {
public void run()
{
recDataString.append(string); //keep appending to string until ~
//keep appending to string until ~
int endOfLineIndex = recDataString.indexOf("~"); // determine the end-of-line
if (endOfLineIndex > 0) { // make sure there data before ~
// String dataInPrint = string.substring(0, endOfLineIndex); // extract string
if (recDataString.charAt(0) == '#') //if it starts with # we know it is what we are looking for
{
String sensor0 = recDataString.substring(1, 4); //get sensor value from string between indices 1-5
String sensor1 = recDataString.substring(5,9); //same again...
stringToFloat1 = Float.parseFloat(sensor0);
stringToFloat2 = Float.parseFloat(sensor1);
floatToInt1 = (int)stringToFloat1 ;
floatToInt2 = (int)stringToFloat2;
if ((floatToInt1 != lastFloatToInt1) ||(floatToInt2 != lastFloatToInt2 )){
Log.d("hell=" , "ohhhhhhhhhhhhhhhh");
movieMethod();
}
lastFloatToInt1 = floatToInt1 ;
lastFloatToInt2 = floatToInt2 ;
}
recDataString.delete(0, recDataString.length()); //clear all string data
}
}
});
}
}
catch (IOException ex)
{
stopThread = true;
}
}
}
});
thread.start();
}
As I understand, you know how to stop thread but you don't know the where you put the stopThread's flag? then below is the points.
public class SecondActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
Button myButton = findViewById(R.id.my_button_id_from_xml);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
stopThread = true;
}
});
}
//Back button listener
#Override
public void onBackPressed() {
stopThread = true;
super.onBackPressed();
}
}
Use this:
Button button;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
yourThread.interrupt();
}
});
}
//Back button listener
#Override
public void onBackPressed() {
yourThread.interrupt();
super.onBackPressed();
}
}
You can use Activity overriden Method-:
#Override
public void onBackPressed() {
super.onBackPressed();
//Do your stuff here
}

ZXingScannerView scan bulk mode in handleresult

I'm trying to implement Bulk Scan mode in me.dm7.barcodescanner:zxing:1.9 library. This is my snippet codes. Im trying to do multiple scan which from the codes for now i just trying to display each of the scan result in messagedialogue. however, after the first scan resulthandler, the second time scan automatically kill the activity.
private ZXingScannerView mScannerView;
private boolean mFlash;
private boolean mAutoFocus;
private int mCameraId = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scanner);
ViewGroup contentFrame = (ViewGroup) findViewById(R.id.content_frame);
mScannerView = new ZXingScannerView(this);
setupFormats();
contentFrame.addView(mScannerView);
}
//i want to make my scanner able to keep scanning getting the result.
//however after the first scan, the second scan will automatically close the activity
#Override
public void handleResult(Result result) {
try {
if(!result.getText().equals("")){
//In message dialogue will have 1 button handle on onDialogPositiveClick
showMessageDialog("Contents = " + result.getText() + ", Format =
" + result.getBarcodeFormat().toString());
}
} catch (Exception e) {
} finally {
}
}
public void showMessageDialog(String message) {
DialogFragment fragment = MessageDialogFragment.newInstance("Scan
Results", message, this);
fragment.show(getSupportFragmentManager(), "scan_results");
}
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
mScannerView.resumeCameraPreview(this);
}
#Override
public void onPause() {
super.onPause();
mScannerView.stopCamera();
closeMessageDialog();
closeFormatsDialog();
}
#Override
public void onResume() {
super.onResume();
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
Try it with onActivityResult
/*Here is where we come back after the Barcode Scanner is done*/
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
// contents contains whatever the code was
String contents = intent.getStringExtra("SCAN_RESULT");
// Format contains the type of code i.e. UPC, EAN, QRCode etc...
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_FORMATS", "PRODUCT_MODE,CODE_39,CODE_93,CODE_128,DATA_MATRIX,ITF");
startActivityForResult(intent, 0); // start the next scan
} else if (resultCode == RESULT_CANCELED) {
//do whatever else you want.
}
}
}
you have to add handler or TimerTask for secondTime Scan.after get first scan result in handleResult you have to start scanning again after some delay, whatever delay you want add to handler.
#Override
public void handleResult(final Result rawResult) {
runOnUiThread(new Runnable() {
#Override
public void run() {
handleDecode(rawResult);
}
});
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mScannerView.resumeCameraPreview(CaptureActivity.this);
}
}, 4000);// 4 sec delay to restart scan again.
}

Automatically click Button if EditText is correct

I am creating a simple app, I require a button called 'bVoice' to be automatically pressed after 500ms if the EditText field contains the correct information.
How do I write the handler to do this in the following code:
//Assign button clicks to got to a new activity:
public void onButtonClick_1(View v){
if (v.getId() == R.id.bVoice){
String str_1 = a.getText().toString();
//Go to the relevant page if any part of the phrase or word entered in the 'EditText' field contains 'next' which is not case sensitive
if (str_1.toLowerCase().contains("command")) {
Intent userintent = new Intent(PocketSphinxActivity.this, Display_1.class);
startActivity(userintent);
} else {
Toast.makeText(getApplicationContext(), "Incorrect Information", Toast.LENGTH_SHORT).show();
}
}
}
Below is the full code I have got thus far (Updated):
public class PocketSphinxActivity extends Activity implements RecognitionListener
{
private static final String KWS_SEARCH = "wakeup";
/* Keyword we are looking for to activate menu */
private static final String KEYPHRASE = "open voice command"; //adjust this keyphrase!
private SpeechRecognizer recognizer;
private HashMap<String, Integer> captions;
ListView lv;
TextView tv;
EditText a;
Button b;
Button c;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
// Prepare the data for UI
captions = new HashMap<String, Integer>();
captions.put(KWS_SEARCH, R.string.kws_caption);
setContentView(R.layout.main);
((TextView) findViewById(R.id.caption_text))
.setText("Preparing the recognizer");
lv = (ListView) findViewById(R.id.lvVoiceReturn);
tv = (TextView) findViewById(R.id.result_text);
a = (EditText) findViewById(R.id.TFusername);
b = (Button) findViewById(R.id.bVoice);
c = (Button)findViewById(R.id.Blogin);
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
new AsyncTask<Void, Void, Exception>() {
#Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(PocketSphinxActivity.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
#Override
protected void onPostExecute(Exception result) {
if (result != null) {
((TextView) findViewById(R.id.caption_text))
.setText("Failed to init recognizer " + result);
} else {
switchSearch(KWS_SEARCH);
}
}
}.execute();
a.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().trim().equalsIgnoreCase("open voice command")) {
//
//Do your stuff here OR button.performClick()
//
//DELAY
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
b.performClick();
}
}, 500);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
recognizer.cancel();
recognizer.shutdown();
}
/**
* In partial result we get quick updates about current hypothesis. In
* keyword spotting mode we can react here, in other modes we need to wait
* for final result in onResult.
*/
#Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null)
return;
String text = hypothesis.getHypstr();
//((TextView) findViewById(R.id.result_text)).setText(text);
((EditText) findViewById(R.id.TFusername)).setText(text);
}
/**
* This callback is called when we stop the recognizer.
*/
#Override
public void onResult(Hypothesis hypothesis) {
//((TextView) findViewById(R.id.result_text)).setText("");
((EditText) findViewById(R.id.TFusername)).setText("");
if (hypothesis != null) {
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
//a.setText((String) tv.getText());
//tv = TextView.getText().toString();
}
}
#Override
public void onBeginningOfSpeech() {
}
/**
* We stop recognizer here to get a final result
*/
#Override
public void onEndOfSpeech() {
if (!recognizer.getSearchName().equals(KWS_SEARCH))
switchSearch(KWS_SEARCH);
}
private void switchSearch(String searchName) {
recognizer.stop();
// 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);
}
private void setupRecognizer(File assetsDir) throws IOException {
// The recognizer can be configured to perform multiple searches
// of different kind and switch between them
recognizer = defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
// To disable logging of raw audio comment out this call (takes a lot of space on the device)
.setRawLogDir(assetsDir)
// Threshold to tune for keyphrase to balance between false alarms and misses
.setKeywordThreshold(1e-45f)
// Use context-independent phonetic search, context-dependent is too slow for mobile
.setBoolean("-allphone_ci", true)
.getRecognizer();
recognizer.addListener(this);
/** In your application you might not need to add all those searches.
* They are added here for demonstration. You can leave just one.
*/
// Create keyword-activation search.
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
}
#Override
public void onError(Exception error) {
((TextView) findViewById(R.id.caption_text)).setText(error.getMessage());
}
#Override
public void onTimeout() {
switchSearch(KWS_SEARCH);
}
//Assign button clicks to go to a new activity:
public void onButtonClick_1(View v){
if (v.getId() == R.id.bVoice){
String str_1 = a.getText().toString();
}
UPDATED text with onResume at the bottom of code:
#Override
public void onResume(){
super.onResume();
isDone = false;
a.setText("");
}
If you want to do something based on the input in the edittext, then you could use a TextWatcher.
UPDATE
Create a global boolean variable:
Boolean isDone=false;
Then inside your Handler code update the code like this :
a.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().trim().equalsIgnoreCase("open voice command"))
{
//
//Do your stuff here OR button.performClick()
//
//DELAY
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (!isDone){
b.performClick();
isDone=true;
} }
}, 500);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
Just Add this code after your AsyncTask. i.e after
}.execute();
To import the Editable class, click on it and press alt+Enter.
Do the same for TextWatcher, click on it and then press alt+Enter.
Whatever code you type inside onTextChanged will get executed whenever the text in the EditText changes. SOLVES your automatic problem.

Utterance progress listener doesnot get called even after passing a hash map parameter

Here is my code, I have a series of questions that will be asked by TTS and after every question speech recognizer will be invoked.My utterance listener is never being called.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_speech_recognizer);
tts = new TextToSpeech(this /* context */, this /* listener */);
}
//This is called after first time user clicks a button
private void processEnquiry() {
// TODO Auto-generated method stub
for(int i=0;i<EnquiryList.size();i++)
{
speak(EnquiryList.get(i).toString());
}
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
initialized = true;
tts.setLanguage(Locale.ENGLISH);
if (queuedText != null) {
speak(queuedText);
}
}
}
public void speak(String text) {
// If not yet initialized, queue up the text.
if (!initialized) {
queuedText = text;
return;
}
queuedText = null;
// Before speaking the current text, stop any ongoing speech.
//tts.stop();
// Speak the text.
setTtsListener();
HashMap<String, String> map = new HashMap<String, String>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"MessageId");
tts.speak(text, TextToSpeech.QUEUE_ADD, map);
}
private void setTtsListener()
{
final SpeechRecognizer callWithResult = this;
int listenerResult = tts.setOnUtteranceProgressListener(new UtteranceProgressListener()
{
#Override
public void onDone(String utteranceId)
{
callWithResult.onDone(utteranceId);
}
#Override
public void onError(String utteranceId)
{
callWithResult.onError(utteranceId);
}
#Override
public void onStart(String utteranceId)
{
callWithResult.onStart(utteranceId);
}
});
if (listenerResult != TextToSpeech.SUCCESS)
{
Log.e(TAG, "failed to add utterance progress listener");
}
}
public void onDone(String utteranceId)
{
callSpeechRecognition();
}
public void onError(String utteranceId)
{
}
public void onStart(String utteranceId)
{
}
TextToSpeech.SUCCESS returns 0.
Here's a modified version of your script, where the onDone() method in the Utterance listener is called. I have eliminated many features that are not directly connected to the TTS playback, to create a barebones sample. If this works for you, then you can add back the other features one by one, testing that nothing breaks on the way.
import android.app.Activity;
import android.os.Bundle;
import android.speech.SpeechRecognizer;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;
import android.view.View;
import java.util.HashMap;
import java.util.Locale;
public class MainActivity extends Activity implements TextToSpeech.OnInitListener {
private TextToSpeech tts;
private SpeechRecognizer sr;
private boolean initialized;
private String queuedText;
private String TAG = "TTS";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_speech_recognizer);
tts = new TextToSpeech(this /* context */, this /* listener */);
tts.setOnUtteranceProgressListener(mProgressListener);
sr = SpeechRecognizer.createSpeechRecognizer(this); // added
}
// Modified for testing purposes
//This is called after first time user clicks a button
/*
private void processEnquiry() {
for (int i = 0; i < EnquiryList.size(); i++) {
speak(EnquiryList.get(i).toString());
}
}
*/
public void processEnquiry(View v) {
speak("Process enquiry");
}
// End of modification
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
initialized = true;
tts.setLanguage(Locale.ENGLISH);
if (queuedText != null) {
speak(queuedText);
}
}
}
public void speak(String text) {
// If not yet initialized, queue up the text.
if (!initialized) {
queuedText = text;
return;
}
queuedText = null;
// Before speaking the current text, stop any ongoing speech.
//tts.stop();
// Speak the text.
setTtsListener(); // no longer creates a new UtteranceProgressListener each time
HashMap<String, String> map = new HashMap<String, String>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
tts.speak(text, TextToSpeech.QUEUE_ADD, map);
}
private void setTtsListener() {
// Method radically simplified; callWithResult is retained but not used here
final SpeechRecognizer callWithResult = sr; // was `this`
}
private UtteranceProgressListener mProgressListener = new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
} // Do nothing
#Override
public void onError(String utteranceId) {
} // Do nothing.
#Override
public void onDone(String utteranceId) {
callSpeechRecognition();
}
};
private void callSpeechRecognition() {
Log.d(TAG, "callSpeechRecognition() called");
}
}
I'm not sure exactly and not sure if this answer will help you, but I think you should not set UtteranceProgressListener every time you request TTS to speak, instead you should set the listener at onInit() once.
And note that the empty text will not be spoken so no callback will be invoked as well.
Though basically setting the listener after TTS initialization looks fine for me and works without problems on my Nexus5 and GalaxyS4, even if setting the listener every time I request TTS to speak, so there might be some device specific problems or some TTS engine specific problems.
Oops I forgot to mention that UtteranceProgressListener is available on API level 15 and above, so the listener will no be invoked on API level 14 and below.

Text to Speech not playing sound for first time, but playing for the next time

I am using this kind of text to speech in one of my class in my app(Code edited to show outlook & exact requirement.). I will show some content on my view & if we click the button , I want to play the sound that is by using this texttospeech engine... But for First time it is not playing the sound. From the next click onwards the TEXTTOSPEECH engine is working nicely
Iwant to know how to overcome this issue....
public class LearnActivity extends Activity implements OnClickListener, OnInitListener {
AudioManager audioManager;
float volume;
TextToSpeech textToSpeech;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_learn);
textToSpeech = new TextToSpeech(this, this);
textToSpeech.setLanguage(Locale.US);
textToSpeech.setSpeechRate(0.95f);
method();
}
public void method(){
bt.setonClickListener(new onClickListener(){
public void onClick(View v){
playSound(datasource.getItemSound);
}
});
}
public void playSound(String sound){
textToSpeech.speak(sound,TextToSpeech.QUEUE_FLUSH,null);
}
#Override
public void onInit(int status) {
// TODO Auto-generated method stub
}
NOTE:- This also meet my Requirement, How to play sound from TEXTTOSPEECH engine directly without using any onClicks etc.,... because I also wants to play a startup sound that too with Android's Text-To-Speech engine only...
That's because you are clicking the button before the engine is ready.
You have to check if the TTS engine has successfully initialized on your onInit() method and enable/disable the play button accordingly.
Assuming that bt in your code is some sort of View that has setEnabled(boolean) method:
#Override
public void onInit(int status) {
bt.setEnabled(status == TextToSpeech.SUCCESS);
}
You always have to assume that the engine has not been initialized and hence keep your play button disabled by default.
I used RXJava to make a class that solves this problem. If your TTS engine is not ready when you want to use the speak method it will wait for the engine to get ready and then speaks the given string.
import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.util.Pair;
import android.widget.Toast;
import java.util.Locale;
import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
public class Pronunciation {
private TextToSpeech textToSpeech;
private int languageResult;
private boolean noError;
private final String errorMessage="Something went wrong with your text to speech engine";
private PublishSubject<Boolean> engineIsReady=PublishSubject.create();
private PublishSubject<Pair<String,Integer>> speakObservable=PublishSubject.create();
private CompositeDisposable compositeDisposable=new CompositeDisposable();
public Pronunciation(Context context) {
textToSpeech=new TextToSpeech(context, status -> {
if (status!=TextToSpeech.ERROR){
languageResult= textToSpeech.setLanguage(Locale.ENGLISH);
engineIsReady.onNext(true);
} else {
Toast.makeText(context,errorMessage
,Toast.LENGTH_LONG).show();
}
});
if (languageResult==TextToSpeech.LANG_MISSING_DATA||languageResult== TextToSpeech.LANG_NOT_SUPPORTED){
noError =false;
Toast.makeText(context,errorMessage
,Toast.LENGTH_LONG).show();
}else { noError =true;}
compositeDisposable.add( Observable.combineLatest(speakObservable, engineIsReady,
(stringIntegerPair, aBoolean) -> stringIntegerPair)
.subscribeOn(Schedulers.io())
.subscribe(pair->{
if (noError)
textToSpeech.speak( (pair).first
,(pair).second,null,null);
}));
}
public void speak(String text,int queueMode){
speakObservable.onNext(new Pair<>(text,queueMode));
}
public void stop(){
if (textToSpeech!=null){
textToSpeech.stop();
textToSpeech.shutdown();
}
compositeDisposable.clear();
}
}
first add RxJava dependency in your Gradle file
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
Then create an instance of this class in the onCreate method of your activity or fragment.Now you can pass the string and queue mode to the speak method.
pronunciation.speak("Hi", TextToSpeech.QUEUE_FLUSH));
Don't forget to call the stop method in onDestroy or onDetach to avoid memory leak
#Override
public void onDetach() {
super.onDetach();
pronunciation.stop();
}
you should write your program ...
public class MainActivity extends Activity implements TextToSpeech.OnInitListener, OnUtteranceCompletedListener {
TextToSpeech t1;
protected void onCreate(Bundle savedInstanceState) {
t1=new TextToSpeech(MainActivity.this, MainActivity.this);
}/////on creat
protected void onDestroy() {
if(t1!=null) {
t1.stop();
t1.shutdown();
t1=null;
}
super.onDestroy();
}
public void onInit(int arg0) {
t1.setOnUtteranceCompletedListener(this);
}
}//mainactivity
Add this command when button is clicked or everywhere you want to speak text.
t1.speak(text, TextToSpeech.QUEUE_FLUSH, null);
Just Put Delay For 5 Second And It's Working without any button Click
public class Final_Text_To_Speech_Activity extends AppCompatActivity implements TextToSpeech.OnInitListener {
private TextToSpeech tts; // For Text to Speech
CardView ScanProduct, SearchProduct;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TextToSpeech(this, this);
init();
// Just Put Delay For 5 Second And It's Working without any button Click
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
SpeakOutOnce("Welcome to Text To Speech Application");
}
}, 5000);
}
#Override
protected void onResume() {
super.onResume();
}
public void init() {
ScanProduct = (CardView) findViewById(R.id.scan_product);
SearchProduct = (CardView) findViewById(R.id.search_product);
// Search On Button Click
ScanProduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
speakOut("You have Just pressed Scan Option");
}
});
SearchProduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
speakOut("You have Just pressed Search Option ");
}
});
}
#Override
public void onDestroy() {
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
#Override
public void onInit(int status) {
int result = tts.setLanguage(Locale.US);
if (status == TextToSpeech.SUCCESS) {
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
} else {
speakOut("");
}
} else if (status == TextToSpeech.ERROR) {
Toast.makeText(this, "Sorry! Text To Speech failed...",
Toast.LENGTH_LONG).show();
}
}
private void speakOut(String text) {
tts.setPitch(1.0f); //Normal Pitch
tts.setSpeechRate(0.7f); // 1.0 is Normal speech Rate
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
private void SpeakOutOnce(String text) {
if (tts != null) {
tts.setPitch(1.0f); //Normal Pitch
tts.setSpeechRate(0.7f); // 1.0 is Normal speech Rate
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
}
}

Categories

Resources