Text to Speech is not working in the activity (android) - android

I am developing an activity that reads the balance for the user. When the user enter the Balance activity it should read the balance immediately. But that's not working for me here is the code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_balance);
EditText editTextTotalBalance= (EditText) findViewById(R.id.editTextBalanceNow);
new Thread(new Runnable() {
public void run() {
myTTS=new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status)
{
if(status != TextToSpeech.ERROR)
{
myTTS.setLanguage(Locale.UK);
}
}
});
}
}).start();
// take the string from the edit text to read the balance
String speech=editTextTotalBalance.getText().toString();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
ttsGreater21(speech);
}
else {
ttsUnder20(speech);
}
}// end of onCreate method
#SuppressWarnings("deprecation")
private void ttsUnder20(final String speech) {
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
#Override
public void run() {
try {
HashMap<String, String> map = new HashMap<>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, map);
}
catch(Exception excep){
}
}
};
mainHandler.post(myRunnable);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void ttsGreater21(final String speech) {
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
#Override
public void run() {
try {
String utteranceId=this.hashCode() + "";
myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null, utteranceId);
}
catch(Exception excep){
}
}
};
mainHandler.post(myRunnable);
}
public void onPause(){
if(myTTS !=null){
myTTS.stop();
myTTS.shutdown();
}
super.onPause();
}
Also, it shows me an error says Skipped 81 frames! The application may be doing too much work on its main thread. for that I add many thread in my code.
Also, I check for the API version because when I implemented it regularly I found there are some SmartPhones are not working well for the speech and it let the app crushed.
Thank you looking forward for your help,

Related

Android TextToSpeech in Chrome ARC

I'm trying to port my android app to Chrome using ARCWelder. The TextToSpeech component doesn't seem to work. In one activity I have an indeterminate progress circle waiting until the TTS engine is initialized. On Chrome, it either spins forever or returns a NullPointerException. Is TTS not available in Chrome? Running ChromeOS on a Chromebox.
UtteranceProgressListener ttsListener = new UtteranceProgressListener() {
#Override
public void onStart(String s) {
Logg.d("speech started: " + s);
if (loadingDialog.isShowing()) {
loadingDialog.dismiss();
}
}
#Override
public void onDone(String s) {
Logg.d("speech done: " + s);
if (s.equals("1")) {
nextWord();
} else if (s.equals("2")) {
CheckLeave();
}
}
#Override
public void onError(String s) {
Logg.e("Text to Speech error speaking: " + s);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
showProgressDialog();
}
#Override
protected void onResume() {
if (tts==null) {
Logg.d("re-initializing TTS");
tts=new TextToSpeech(getApplicationContext(),
new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR){
tts.setSpeechRate(.5f + .25f * (Integer)KVDB.GetValue("speechRate",2));
tts.setLanguage(Locale.US);
if (pauseTime != 0) {
//Paused. Say nothing.
} else if (currentWord == null) {
startTime = new ExcelDate();
nextWord();
} else if (currentWord.length() == 0) {
nextWord();
} else {
reSpeak();
}
}
}
});
tts.setOnUtteranceProgressListener(ttsListener);
}
super.onResume();
}
private void showProgressDialog() {
loadingDialog = new ProgressDialog(this);
loadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
loadingDialog.setTitle(getString(R.string.test_loading_msg));
loadingDialog.show();
}
As you found, it does look like we don't have any kind of default TTS service provider as part of the ARC package. There is not one provided by the base Android OS at all.
Please feel free to file a bug for it.

Using handler to change ui, still "only the original thread that created a view hierarchy can touch its views." error

I have two threads, two handlers. From thread i check a random number and send result to handle to update ui. But i am getting the error "only the original thread that created a view hierarchy can touch its views.". I searched some articles, they tell to use handler. I am doing that, yet can not avoid the errors.
After some checking, I found that it crashes when A sends the result. In case of B, it works
Also, can i use one handler for two thread?
public class MainActivity extends Activity implements View.OnClickListener{
Button start;
TextView status_B, status_A;
Boolean isRunning;
Thread Athread, Bthread;
int a, b;
Handler a_Handler, b_Handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initialize variables
start = (Button) findViewById(R.id.button);
start.setOnClickListener(this);
status_B = (TextView) findViewById(R.id.textView);
status_A = (TextView) findViewById(R.id.textView1);
a_Handler = new Handler() {
public void handleMessage(Message msg)
{
int number = msg.getData().getInt("number");
String winner = msg.getData().getString("winner");
start.setEnabled(true);
isRunning = false;
status_A.setText(winner + number);
}
};
b_Handler = new Handler() {
public void handleMessage(Message msg)
{
int number = msg.getData().getInt("number");
String winner = msg.getData().getString("winner");
start.setEnabled(true);
isRunning = false;
status_B.setText(winner + number);
}
};
}
#Override
protected void onStart() {
super.onStart();
isRunning = false;
}
#Override
public void onClick(View v) {
start.setEnabled(false);
status_B.setText("Guessing...");
if (!isRunning)
{
Athread = new Thread(new Runnable() {
#Override
public void run() {
while (isRunning)
{
try
{
Athread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
a = (int) (Math.random()*1000);
System.out.println("a "+ a);
if(a%7 == 0) {
isRunning = false;
Bundle bundle = new Bundle();
bundle.putString("winner", "A");
bundle.putInt("number", a);
Message msg = a_Handler.obtainMessage();
msg.setData(bundle);
a_Handler.handleMessage(msg);
}
}
}
});
Bthread = new Thread(new Runnable() {
#Override
public void run() {
while(isRunning)
{
try
{
Bthread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
b = (int) (Math.random()*1000);
System.out.println("b "+ b);
if(b%7 == 0) {
isRunning = false;
Bundle bundle = new Bundle();
bundle.putString("winner", "B");
bundle.putInt("number", b);
Message msg = b_Handler.obtainMessage();
msg.setData(bundle);
b_Handler.sendMessage(msg);
}
}
}
});
isRunning = true;
Athread.start();
Bthread.start();
}
}
}
You need put your code to modify views on UI thread:
a_Handler = new Handler() {
public void handleMessage(Message msg)
{
final int number = msg.getData().getInt("number");
final String winner = msg.getData().getString("winner");
runOnUiThread(new Runnable() {
#Override
public void run() {
start.setEnabled(true);
status_A.setText(winner + number);
}
});
isRunning = false;
}
};
b_Handler = new Handler() {
public void handleMessage(Message msg)
{
final int number = msg.getData().getInt("number");
final String winner = msg.getData().getString("winner");
runOnUiThread(new Runnable() {
#Override
public void run() {
start.setEnabled(true);
status_B.setText(winner + number);
}
});
isRunning = false;
}
};

Getting error while implementing thread android

Am new in android .. am trying to implement thread in a android. But am getting error .. I googled and getting answer "AsyncTask", but truly i dont know how to implement
Error message
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
my code
final Thread thread = new Thread(){
#Override
public void run() {
try {
DatabaseHandler dbh = new DatabaseHandler(test.this);
result=dbh.Verify(1);
if(result != ""){
getData();
progress.dismiss();
}
else{
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
Use following code to run in UI thread.
Runnable runnable = new Runnable() {
#Override
public void run() {
handler.post(new Runnable() { // This thread runs in the UI
#Override
public void run() {
DatabaseHandler dbh = new DatabaseHandler(test.this);
result=dbh.Verify(1);
if(result != ""){
getData();
progress.dismiss();
}
else{
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
new Thread(runnable).start();
Seems like you need to create your handler in MainActivity and then pass it further. Like so:
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
}

Using Threading, Runnable and Message in Android

This is my scenario. A class A implements Runnable. When user click a button, there will show a progress dialog and call the method searchMap() to search an address. The dialog dismisses after 10 seconds. I really misunderstand how to execute the run() method. this is my creepy code.
public class AddLocationMapActivity extends MapActivity implements Runnable {
private ProgressDialog progressDialog;
private MyHandler myHandler;
private Message msg;
#Override
public void run() {
mapCurrentAddress();
}
public void mapLocation(View v) // click event here{
progress();
Thread thread = new Thread(this);
thread.start();
}
private class MyHandler extends Handler{
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what) {
case NOT_OK_MESSAGE: // Fail
alert(AddLocationMapActivity.this, message());
progressDialog.dismiss();
break;
case OK_MESSAGE: // Success
found(); // Point to the appropiate address
progressDialog.dismiss();
break;
case EXPTION_MESSAGE: // Exception
alert(AddLocationMapActivity.this, "Unexpected error");
progressDialog.dismiss();
break;
}
}
}
protected void mapCurrentAddress() {
String addressString = addressText.getText().toString();
Geocoder g = new Geocoder(this);
List<Address> addresses;
myHandler = new MyHandler();
msg = myHandler.obtainMessage();
try {
addresses = g.getFromLocationName(addressString, 1);
if (addresses.size() > 0) {
//address = addresses.get(0);
msg.what = OK_MESSAGE;
myHandler.sendEmptyMessage(OK_MESSAGE);
} else {
// show the user a note that we failed to get an address
myHandler.sendEmptyMessage(NOT_OK_MESSAGE);
}
} catch (IOException e) {
// show the user a note that we failed to get an address
//e.printStackTrace();
myHandler.sendEmptyMessage(EXPTION_MESSAGE);
}
}
private void progress() {
progressDialog = ProgressDialog.show(this,
"Checking", "Contacting Map Server");
Thread progressThread = new Thread();
progressThread.start();
}
}
When click event occurs, the program fails with exception Uncaught Handler
here's a little bit of my threading code that doesn't give away too much...
progress = ProgressDialog.show(this, "", "Loading...", true);
new Thread(new Runnable() {
#Override
public void run()
{
// get some network content
Chooser.this.runOnUiThread(new Runnable() {
#Override
public void run()
{
progress.dismiss();
// update the UI
}
});
}
}).start();

How can I prevent UI hang, when my service runs a TimerTask?

I have a service which contains a Timer and TimerTask for receiving data from Webservice in periods of time. When my TimerTask runs, the UI hangs until the Webservice process complete. How can I put my task in a thread to prevent the UI hanging?
My code:
Timer timerSyncFull = new Timer();
class taskSyncFull extends TimerTask {
#Override
public void run() {
hSyncFull.sendEmptyMessage(0);
}
};
final Handler hSyncFull = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
procSyncFull();
return false;
}
});
public void procSyncFull() {
try {
// My webservice process
} catch (Exception e) {
}
}
#Override
public void onStart(Intent intent, int startId) {
timerSyncFull = new Timer();
timerSyncFull.schedule(new taskSyncFull(), 5*60*1000,
5*60*1000);
}
Use AsyncTasks or attach your Handler to another Looper thread.
I used the following code and my problem solved:
class taskSendMapMovements extends TimerTask {
#Override
public void run() {
hhSendMapMovements.sendEmptyMessage(0);
}
};
// /////////////////////
final Runnable rSendMapMovements = new Runnable()
{
public void run()
{
procSendMapMovements();
}
};
final Handler hhSendMapMovements = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
performOnBackgroundThread(rSendMapMovements);
return false;
}
});
// /////////////////////
public void procSendMapMovements() {
try {
showToast("some text");
//My Main Process
} catch (Exception e) {
}
}
#Override
public void onStart(Intent intent, int startId) {
try {
timerSendMapMovements = new Timer();
timerSendMapMovements
.schedule(new taskSendMapMovements(),
10*60*1000,
10*60*1000);
//
} catch (NumberFormatException e) {
Toast.makeText(this, "error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
final Handler hToast = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
Toast.makeText(SrvDataExchange.this,
msg.getData().getString("msg"),
Toast.LENGTH_LONG).show();
return false;
}
});
private void showToast(String strMessage) {
Message msg = new Message();
Bundle b = new Bundle();
b.putString("msg", strMessage);
msg.setData(b);
hToast.sendMessage(msg);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
#Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
Simply invoke your procSyncFull() method in thread or asyncTask.
final Handler hSyncFull = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
Thread thread=new Thread()
{
public void run(){
procSyncFull();
}
}
return false;
}
});
private Handler webserviceCompletionHandler=new Handler()
{
#Override
public boolean handleMessage(Message msg) {
return false;
}
};
use AsyncTask carry out your execution in doInBackground() and populate it in onPostExecute()
AsyncTask Example

Categories

Resources