Start and cancel a toast programmatically - java

In my app, I've got a procedure that can last between 2 and 15 seconds more or less. What I want is to set a kind of toast that when the procedure starts shows:
Loading values. Wait...
Just now, I've setted the toast duration to SHORT, because if the procedure lasts about 5 or less seconds, a LONG will be just that, very long. But having setted the duration to SHORT, when it lasts more than 10 seconds the toast dissapears and there is no message showing that the app is still processing so the user can start touching things.
What I want is to set something like a toast but that I can programmatically cancel when the procedure is finished. Any ideas?

I would recommend that you simply set the Toast duration to the maximum possible time and then use the Toast object returned from Toast.makeText(...) to cancel it when your process is finished.
Toast t = Toast.makeText(....., YERY_LONG_TOAST_TIME);
t.show();
public void onYourTaskFinished() {
t.cancel();
}
Something like that.
I personally would recommend using a ProgressDialog btw: http://developer.android.com/reference/android/app/ProgressDialog.html

Here's an example:
final Toast toast = Toast.makeText(ctx, "This message will disappear in 1 second", Toast.LENGTH_SHORT);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 1000); //specify delay here that is shorter than Toast.LENGTH_SHORT

final Toast toast = Toast.makeText(ctx, "hello android", Toast.LENGTH_SHORT);
Handler h= new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
toast.show();
}
}, 1000);
h.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 3000);

You can have a handler of the Toast when you create it, pass it to you job and call the show() method when the job starts and call the cancel() method when the job finish.
However, from your description, toast message might not be your best choice. Toast is more like a hint which has little impact if the user misses it. With little background infomation about your app, I think you might need a ProgressDialog if you do not want the user to touch anything while you are loading data, or a ProgressBar if you just want the user to know your job's progress.

Do not use Toast for this purpose. You should use progress dialog or you can add progress indicator to notification bar. So user will be able to see progress even not being inside your app.

Related

How to stack toasts in Android?

A friend is writing an Android app for school and I'm helping him a bit. There is one question that I was not able to solve for like an hour.
He is trying to show 2 toasts after each other, but we were not able to stack them, or even show them at the same time. All we see is the second Toast.
We tried showing it for a shorter time, than the first, to see if it was hiding behind the second, it was not. Then we placed the second in the middle of the screen, but it didn't help either. He said it just works for his friend (I can't confirm that, but also couldn't google anyone having the same issue)
Toast t1 = Toast.makeText(getApplicationContext(), "first", Toast.LENGTH_LONG);
t1.show();
Toast t2 = Toast.makeText(getApplicationContext(), "second", Toast.LENGTH_SHORT);
t2.setGravity(0, 50, 0);
t2.show();
Are we totally missing something? Is it even designed to show two toasts the same time, or stack them?
Use postDelayed(). Show the first Toast and after sometime show the second one:
final Handler handler = new Handler();
handler.postDelayed(
() -> //show the toast here,
1200);
handler.postDelayed(() -> //show second toast,
2400);
}
https://developer.android.com/reference/android/os/Handler
Try a snackbar (They look way better too!)
protected ArrayList<Snackbar> mSnackbarList = new ArrayList<>();
protected Snackbar.Callback mCallback = new Snackbar.Callback() {
#Override
public void onDismissed(Snackbar snackbar, int event) {
mSnackbarList.remove(snackbar);
if (mSnackbarList.size() > 0)
displaySnackbar(mSnackbarList.get(0));
}
};
public void addQueue(Snackbar snackbar){
setLayoutParams(snackbar);
snackbar.setCallback(mCallback);
mSnackbarList.add(snackbar);
if(mSnackbarList.size() == 1)
displaySnackbar(snackbar);
}
public void displaySnackbar(Snackbar snackbar){
snackbar.show();
}

how to show pop up or custom toast in onStop() or onDestroy()?

I have an app how to make some notification when reaching specific time ...
I would to show some pop-up or custom layout when my app is onStop or onDestroy.
I would like this photo.
(click to enlarge)
If you just want to give a message then Toast is enough and easy.
#override
public void onStop() {
Toast.MakeText(context, "Your message here", Toast.LENGTH_LONG).show();
}
#override
public void onDestroy() {
Toast.MakeText(context, "Your message here", Toast.LENGTH_LONG).show();
}
EDIT: I won't recommend you to write long messages in Toast and show it for longer durations, instead consider a Statusbar Notification. Status Bar Notifications can be programmatically canceled when they are no longer relevant.
BUT If you still want to increase the duration of Toast message then here is a workaround.
private Toast mToastToShow;
public void showToast(View view) {
// Set the toast and duration
int toastDurationInMilliSeconds = 10000;
mToastToShow = Toast.makeText(this, "Hello world, I am a toast.", Toast.LENGTH_LONG);
// Set the countdown to display the toast
CountDownTimer toastCountDown;
toastCountDown = new CountDownTimer(toastDurationInMilliSeconds, 1000 /*Tick duration*/) {
public void onTick(long millisUntilFinished) {
mToastToShow.show();
}
public void onFinish() {
mToastToShow.cancel();
}
};
// Show the toast and starts the countdown
mToastToShow.show();
toastCountDown.start();
}
Here is how it works: the countdown has a notification time shorter than the duration for which the toast is displayed according to the flag, so the toast can be shown again if the countdown is not finished. If the toast is shown again while it is still on screen, it will stay there for the whole duration without blinking. When the countdown is finished, the toast is canceled to hide it even if its display duration is not over.
Simplest way would be to use a Toast (easy and immediate). More complex way is that you've to grant 2 special permissions "draw over other apps" and "app with usage access" (which are special permissions, so you need to create your own page to prompt the user to grant it), after which you can add your custom view directly to the windows manager of the system. Last but not least, you should seriously think if there's any benefit for the user to be notified on main screen about something after your main page has been stopped or destroyed, because that goes against the system design quite a lot.

How to start and stop progressbar in android?

I have an activity that calls a second java class. I want after the second class is called to show a progressbar and then return to normal activity execution. I found some other threads but i couldn't make the progressbar to stop.
There's a full example over here.
Quote:
Declare your progress dialog:
ProgressDialog progress;
When you're ready to start the progress dialog:
progress = ProgressDialog.show(this, "dialog title",
"dialog message", true);
and to make it go away when you're done:
progress.dismiss();
Here's a little thread example for you:
// Note: declare ProgressDialog progress as a field in your class.
progress = ProgressDialog.show(this, "dialog title",
"dialog message", true);
new Thread(new Runnable() {
#Override
public void run()
{
// do the thing that takes a long time
runOnUiThread(new Runnable() {
#Override
public void run()
{
progress.dismiss();
}
});
}
}).start();
ProgressDialog is deprecated, so you might want to use a ProgressBar.
I've found this post about deleting one of them.
Well, I think this is rather ridiculous, but here is how I fixed it.
In my xml for the ProgressBar, I added android:visibility="gone"
to hide it by default. Then, in my code, I first told it to display
(View.VISIBLE) before it tried getting the server list, then I told
it to hide (View.GONE) after it was done. This worked (I could see
the progress indicator while the data loaded, then it went away). So
I suppose I couldn't get it to hide in the code because the code is
not what forced it to be visible to begin with... That seems like a
bug to me.
Its very Simple:
to show a Progress
ProgressDialog dialog = ProgressDialog.show(getContext(), "Title", "Message");
and to stop it:
dialog.dismiss();

Android app crashing when toast is run in try catch

I'm creating an android app that has a login screen. What I did was that whenever the user clicks the submit button, it runs a progressdialog. then call a new thread to verify the login. When I try to run a toast on the function inside the login, the app suddenly crashes. What I did with it is this:
loginButton.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
dialog = ProgressDialog.show(MainActivity.this, "",
"Validating user...", true);
new Thread(new Runnable(){
public void run(){
login();
}
}).start();
}
});
then my login function is this:
void login(){
try{
//some code
} catch(Exception e){
dialog.dismiss();
Context context = getApplicationContext();
CharSequence text = "Hello toast!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
But for some reason once it goes to the catch function the app suddenly crashes only when I add the code for the toast. What is wrong with my code and why is it crashing only when I am using toasts?
The toast is in another work thread ?
Can you put the toast in runOnUiThread() ?
Have you tried debugging your code? You probably get null pointer from getApplicationContext() as you are calling it from your thread. Declare a variable context somewhere and use that variable to make Toast(if you need it).

Spam protection onclick()

I'm trying to build a SMS application that sends a SMS with one press on a button, this part is working but now I'm trying to implement a spam protection.
The spam protection means that you only can send 1 SMS per 10 seconds (or higher).
I've tried this:
sentSMS.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Timer timer = new Timer();
int seconds = 10000;
timer.schedule(new TimerTask() {
public void run() {
processClick();
}
}, seconds);
}});
But this is not working when I press the button twice the SMS is also sending twice.
Maybe it's also a idea to make a toast which contains how many seconds the user have to wait, something like this:
Toast.makeText(getBaseContext(), "Spam protection, wait "+secondstowait,
Toast.LENGTH_SHORT).show();
Is this all possible to make?
why dont you just take a timestamp when the button was first clicked then compare the time when the button was clicked again and see if the difference is greater than the allotted amount of time?
Potentially, the easier thing to do in my opinion is to disable the button, and use the built-in handler (on the view object) to re-enable the button.
sentSMS.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final View view = v;
v.setEnabled(false);
v.postDelayed(new Runnable(){
public void run(){
view.setEnabled(true);
}
}, 1000*10);
}});
You need to store when the button was last clicked and then see if 10 seconds have passed.
long lastTimeSent = 0; //start at 0
sentSMS.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(System.currentTimeMillis() > lastTimeSent + 10000){ //if at least 10 secs has passed from last click
processClick();
lastTimeSent = System.currentTimeMillis(); //last time sent is now current time
}else{
Toast.makeText(getBaseContext(), "Spam protection, please wait.",
Toast.LENGTH_SHORT).show();
}
}});
if you want to show a toast message to user, notifying him about how many seconds are left,
you must write the toast.maketext code inside the timer schedule event too
using timestamp will not be easier way, rather it will make task more difficult.
You can also try to disable the button onclick for ten seconds and re-enable it after the time period is expired.

Categories