Toast Messages do not show up - java

Hey I have a problem with toast messages which does not show up. I'm creating an app which displays user‘s message into Morse code and I want toast message show up to inform which character is diplayed now. But when I put it like below, toast messages do not show up. It's probably because next function which is called are somehow killing the previous one, cause when I removed other commands and left only showStatus() the messages appeared.
How can I deal with this situation?
public void dispDot()
{
final Parameters pM = cameraMorse.getParameters();
pM.setFlashMode(Parameters.FLASH_MODE_TORCH);
cameraMorse.setParameters(pM);
MorseActivity.backgroundMorse.setBackgroundResource(R.drawable.background1on);
waitFor(1);
pM.setFlashMode(Parameters.FLASH_MODE_OFF);
cameraMorse.setParameters(pM);
MorseActivity.backgroundMorse.setBackgroundResource(R.drawable.background1a);
}
//function that displays the line in Morse code
public void dispLine()
{
final Parameters pM = cameraMorse.getParameters();
pM.setFlashMode(Parameters.FLASH_MODE_TORCH);
cameraMorse.setParameters(pM);
MorseActivity.backgroundMorse.setBackgroundResource(R.drawable.background1on);
waitFor(3);
pM.setFlashMode(Parameters.FLASH_MODE_OFF);
cameraMorse.setParameters(pM);
MorseActivity.backgroundMorse.setBackgroundResource(R.drawable.background1a);
}
public void showStatus(char character)
{
//status1.setTextColor(Color.WHITE);
//status1.setText("Status: Now displaying "+character);
toast = Toast.makeText(MorseActivity.this, "Displaying "+character,Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 0, 30);
toast.show();
}
public void morseMessageTranslator()
{
morseMessage = textBox.getText().toString();
morseMessage = morseMessage.toUpperCase();
if(morseMessage.length()>0)
{
char character;
for(int a=0;a<morseMessage.length();a++)
{
character=morseMessage.charAt(a);
switch (character)
{
case 'A': //.-
showStatus('A');
dispDot();waitFor(1);dispLine();waitFor(1);
break;
case 'B': //-...
showStatus('B');
dispLine();waitFor(1);dispDot();waitFor(1);dispDot();waitFor(1);dispDot();waitFor(1);
break;
UPDATE:
Ok it turns out that waitFor() function is the cause.
public void waitFor (final int time)
{
Thread waitthread = new Thread(new Runnable() {
// After call for background.start this run method call
public void run() {
try {
Thread.sleep(time*500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
waitthread.start();
try {
waitthread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
But still don't know how to show toast before the wait is launched.

As your comments on this question show, the reason your Toasts aren't showing is because of your waitFor() method. As described, this performs a pointless calculation, which a) wastes precious CPU time (and therefore battery) and b) performs this on the UI thread. This means that anything that should happen on the UI thread won't happen all the time waitFor() is running, including Toasts.
You'll have to include some sort of threading here to get over this issue (the Android Developers website has a good tutorial). You'll want the dispDot, dispLine and waitFor calls to happen on a background thread. Bear in mind that if any of these three methods interact with your UI, they must do that back on the UI thread (see Communicating with the UI thread in the linked tutorial).
Previous (wrong) answer
You're creating your Toasts, but not calling show() on them! It's a very easy mistake to make. Just change the line:
toast = Toast.makeText(MorseActivity.this, "Displaying "+character,Toast.LENGTH_LONG);
to
toast = Toast.makeText(MorseActivity.this, "Displaying "+character,Toast.LENGTH_LONG).show();

Add .show() to the end of you toast codes
toast = Toast.makeText(MorseActivity.this, "Displaying "+character,Toast.LENGTH_LONG).show();

Related

Method in Toggle Button crashes

Hey guys I am having an issue that a method I am trying to run every thirty seconds is causing my toggle button to crash. My goal is to send data to a database based on the button click, and while the toggle button is on to continue sending that data through a method every thirty seconds. When I click the button, I get the Unfortunately error and the app crashes.
To save the length of this post, this button to send the data only one time works fine:
uploadOnce.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view) {
try {
SendCode(socket);
}catch(Exception e){
String stackTrace = Log.getStackTraceString(e);
sendEmail(stackTrace);
}
}
});
Notice that the above button click uses the SendCode method and it works correctly.
The error that I am having is using that same method with a timer on it, like so:
This is the toggle button onClick:
toggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
if (toggle.isChecked()) {
makeToast("On");
sendForever();
}
}catch (Exception e){
String stackTrace = Log.getStackTraceString(e);
sendEmail(stackTrace);
}
}
});
If I take the sendForever() method out, the toggle button works fine as expected.
This is the sendForever method in the toggle button:
public void sendForever(){
if(toggle.isChecked()) {
while (toggle.isChecked()) {
try {
new Handler().postDelayed(new Runnable() {
// Runs a timer to send code to database every 30 seconds
#Override
public void run() {
try {
SendCode(socket);
} catch (Exception e2) {
String stackTrace = Log.getStackTraceString(e2);
sendEmail(stackTrace);
}
}
}, 30000);
} catch (Exception e) {
String stackTrace = Log.getStackTraceString(e);
sendEmail(stackTrace);
}
sendForever();
}
}
}
So the goal is that when this method is called, it checks to see if the toggle button is in the "ON" state, then while it is on it will run the SendCode method (which works fine in the button to send it only once) then wait 30 seconds. After the 30 seconds is over I am going to call the method again until the toggle button is hit again and breaks the loop.
My problem I am having is that I am using this on an OBD2 sensor in my car, and it is not hitting the sendEmail methods to shoot me a stacktrace of the error, so I am not able to post the stacktrace as of now.
If anybody has any advice on what is going wrong or what I can look at to fix this, it would be greatly appreciated. Once again, sorry for not being able to put the stacktrace up right now, I will edit the post if I am able to acquire it.
You call sendForever() from the method itself (in a loop, even). That will result in a stack overflow as the recursion is limited only by the toggle condition. Just remove the recursive call, since you already have the loop handling the repetition (well, that would solve the stack overflow, but see next paragraph for further issues).
Note also that you have a blocking task running in the UI thread. Since you block the UI thread, the toolkit will have no chance to make the button not toggled anymore, essentially locking up your application. Simplest is probably checking the condition after the previous sending is done, and schedule a new one if needed.
A side note: It's needless to do an if (toggle.isChecked()) check in sendForever() since you have the same condition in the while loop.
try to dump the stack trace on file system instead of email... may be your whole application is crashing
or may be you should post the code of SendCode(socket) that function might be locking some resources that are not released in 30 sec i.e. before the next function call is made

Manipulation with JProgressBar in Swing

I have an app that connects reads file on remote server. File dynamically updates that's why I use Timer class to reread this file periodically.
Workflow is the following:
Open window where text will be displayed.
Start reading file (reread once per 15 sec using Timer)
In 15 seconds window is filled with data or I receive exceptions in log. Exceptions are suppressed and I continue trying to read data.
Exceptions are my problem, because user doesn't know what is happening now with an app.
There are at least two Exceptions I ran at:
- If file is absent, I receive FileNotFoundException.
- If server is on maintenance I receive other Exception (I catch it, so its name doesn't matter).
Here is how above looks like in code:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final RemoteReader reader = new RemoteReader();
Timer timer = new Timer(15000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
reader.getMainPanel().readData();
} catch (IOException e) {
//Here is a counter that increases after each exception throw
if(counter >5) {
JOptionPane.showOptionDialog(chat,
e.getMessage(),
e.getClass().getName(),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
new String[]{"Retry", "Cancel"}, //on Retry - make another 5 tries to read file, on cancel - close the window
null);
counter = 0;
}
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
});
timer.start();
}
});
}
public String readData() throws IOException {
// read and process data before returning it
// but for test purpose:
//BufferedReader br = new BufferedReader(new InputStreamReader(this.url.openStream()));
throw new IOException("cannot read file");
}
What I want to do is to add JProgressBar. On openning the main window progress bar appears and then data is read. If IOException throws 5 times in a row, show option dialog. Otherwise hide progress bar and show data. If remote file becomes unavailable, show option dialog. And pressing the retry button, show progress bar... then workflow starts from the very beginning.
Some code examples would help me, but I don't expect solution for the whole issue - advice, how it should be done in right way from design point of view will be enough. Samples of Oracle a little bit vague for me.
Even if WatchService, seen here, is not available, I'd still use SwingWorker, seen here and here.
You have considerable latitude in pacing the doInBackground() thread, e.g. Thread.sleep(15 * 1000).
You can setProgress() in the background and listen for any PropertyChangeEvent in the GUI.
You can update any GUI components in process(), which runs on the EDT.

Android :UI Thread Blocked

In my application I have created one customized dialog box ,which is showed in both webview and normal android application,and also I doing some background operation when the dialog box is showed, when ever I called the mydialog function it shows my customized dialog box and also it return some values,it is perfectly working when I use webview+javainterface but it doesn't work with ordinary applications, the flow is
first I will get my dialog, after I do some process(here the main thread will wait ,dialog need to show,) then I will return the string ,the problem is dialog doesn't show when I called this function instead of that the dialog will showed after my background process finished.
I call this my dialog box like:
String sample=mydialog();
public String mydialog() {
String mystring = null;
try {
myactivity.this.runOnUiThread(ShowDialog);
while (customizeddialog.Getvalue() == null) {
}
mystring = customizeddialog.Getvalue();
customizeddialog.Setvalue(null);
} catch (Exception e) {
return mystring;
}
private Runnable ShowDialog = new Runnable() {
public void run() {
try {
customizeddialog m_dialog = new customizeddialog(myactivity.this);
m_dialog.setCancelable(false);
m_dialog.show();
} catch (Exception e) {
}
}
};
When you enter the synchronized block in mydialog() you acquire this's lock. Inside this synchronized block, you run ShowDialog() on the UI thread, and try to acquire this's lock again when you enter the synchronized block in ShowDialog.
Since the lock has already been acquired, it will wait until it is released in mydialog(), which will never happen because ShowDialog never executes past synchronized(this). What you have is deadlock.

How to get and return user input in the same method on Android

(I know this question has been asked in many different flavors, thanks for considering the specifics of my situation).
I am implementing a 3rd party library. One of the methods requires user input, and the return value of this method needs to be the user's response. Specifically, this method needs to pop up an alert dialog. The user will have 3 buttons to choose from and the return value of this method must be an int identifying the button the user clicked.
The only way I've gotten this working is by calling this alert method from an AsyncTask and from there calling runOnUIThread to pop up the alert and then wait for the response. Where I'm stuck is the case where this alert method is being called from the UI thread. Is there a similar work around to wait on a response in this case?
This is what my code currently looks like... as long as this method is called from an AsyncTask I'm good to go. BUT, I need to be able to call it from the UI thread.
public int getInput(final Object [] args)
{
getActivity().runOnUiThread(new Runnable(){
#Override
public void run()
{
buildDialog(args).show();
}
});
try
{
synchronized(this)
{
wait();
}
}
catch (Exception ex)
{
return 0;
}
return m_Result;
}
public void setRetValue(int result)
{
m_Result = result;
synchronized(this)
{
notify();
}
}
(setRetValue gets called from onClick in the OnClickListeners of the buttons in the dialog.)

SwingWorker ends, PropertyChangeListener listens, but how do I get back to EDT?

I've already browsed many threads on this topic, but nothing seems to fit my specific situation.
I have a swing application which analyzes QR-Codes, extracts the found loginNames and makes DB calls to fetch data for that user. To make sure the capture of the QR-Codes can be canceled and my application is still accessible while capturing, I used a SwingWorker for this purpose. Everything works fine so far, I've included a PropertyChangeListener so the application knows when my SwingWorker successfully read a code. But since I don't want to have the PropertyChangeListener as a nested class within my mainClass (to keep it well structured), I've created a new class for it outside. Now I want to return to my main class from this PropertyChangeListener class to switch to the appropriate panel which displays the fetched data. I have different codes which can be read, so depending on the code I have different panels to switch to (so I can't do a static switch to the same panel over and over again). So how can I delegate the PropertyChangeListener to give the control back to my EDT ?
I've tried using wait() and notify() to let my EDT know the SwingWorker finished. But obviously wait() blocks my EDT and the use of SwingWorker is pointless.
I hope I could explain my problem in enough detail, and some of you have a good idea to deal with this.
For any code snippets please ask, I'll then add the necessary ones. But since my project is a bit more complex I'll just post what is asked for.
Thanks in advance for any help :)
EDIT: Here is a code excerpt to illustrate what my SwingWorker is doing.
SwingWorker class:
public class CodeDetector extends SwingWorker<byte[], String> {
String s; // read String
byte[] completeCode; // byte[] which is returned by doInBackground()
BufferedImage resizedImg;
IplImage img;
JLabel labelForStream;
JLabel result;
FrameGrabber grabber = new VideoInputFrameGrabber(); // using JavaCV.
public CodeDetector(JLabel labelForStream, JLabel result) {
this.labelForStream = labelForStream;
this.resultLabel = result;
}
#Override
protected byte[] doInBackground() throws Exception {
try {
grabber.start(); //
while (true) {
// End if current thread was canceled.
if (Thread.currentThread().isInterrupted()) {
return null;
}
// Grab each image, save it, scan for code and display it.
img = grabber.grab();
resizedImg = // resizing image to fit labelForStream.
// save resizedImg to file
// read barcode from saved file
if (isBadgeCode(tmp) || isDeviceCode(tmp)) {
s = tmp;
} else {
continue;
}
break;
} catch (NotFoundException e) {
// Code could not be encoded yet.
}
...
// end worker after timeout
// show image on window
if (img != null) {
labelForStream.setIcon(new ImageIcon(resizedImg));
}
}
}
} catch (Exception e) {
System.err.println("Error: " + e.getMessage() + " - " + e.getStackTrace() + " - " + e.getClass());
}
return s != null ? s.getBytes() : null;
}
#Override
protected void done() {
try {
completeCode = get();
if (completeCode != null) {
String code = new String(completeCode);
if (isOtherCode(code)) {
resultLabel.setText(code);
} else if (isUsernameCode(code)) {
// Cut userName from read code (if previously verified) and set label text.
resultLabel.setText(verify(code, true) ? code.split(":")[0] : null);
}
} else {
resultLabel.setText(null);
}
resultLabel.setVisible(true);
resultLabel.updateUI();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (CancellationException e) {
return;
} catch (Exception e) {
e.printStackTrace();
}
}
As this SwingWorker doesn't have references to any panels, even though the done()-method is done in EDT, I need to somehow notify my mainClass that a code has been read successfully and that it can change the panl now according to the specific code.
Hope this clears things up a bit.
I think that you misunderstood, for what reasons SwingWorker is there, please read SwingWorker
tutorial, where implementations quite guarentee that output from methods:
done()
process()
publish()
setProgress()
should be done on EDT
The simple swing worker answer is to override the done() method. That is executed on the EDT - SwingWorker takes care of that for you.
You can do it yourself, using SwingUtilities.invokeLater.
For the way you pose your question, I suspect you don't have a full grasp of the threading issues and how you switch between threads. So a good review of the tutorial (if you haven't already) may be in order.
This is wrong:
protected byte[] doInBackground() throws Exception {
// ....
if (img != null) {
labelForStream.setIcon(new ImageIcon(resizedImg));
}
// ....
}
As this shows you making critical Swing calls from within the doInBackground method, something that should never be done. Instead consider publishing the Image or the ImageIcon, and setting the JLabel's Icon from the process method override.
As I note in my comment, sometimes its a good idea to use a PropertyChangeListener with your SwingWorker if it decreases code coupling. This is one reason that SwingWorker has its own PropertyChangeSupport and its own state enum.

Categories

Resources