Android Cancel Toast When Exiting the App and When Toast Is Being Shown

Android cancel Toast when exiting the app and when toast is being shown

The trick is to keep track of the last Toast that was shown, and to cancel that one.

What I have done is to create a Toast wrapper, that contains a static reference to the last Toast displayed.

When I need to show a new one, I first cancel the static reference, before showing the new one (and saving it in the static).

Here's full code of the Boast wrapper I made - it mimics enough of the Toast methods for me to use it. By default the Boast will cancel the previous one, so you don't build up a queue of Toasts waiting to be displayed.

This code can be found in my Github gist:

  • mobiRic/Boast

If you just want to know how to cancel the notifications when exiting your app, you will find lots of help in there. If you have improvements or suggestions, please feel free to fork it and get in touch. This is a very old answer, but code has been stable in production on a few apps for some time.

BTW - this should be a direct drop-in replacement for Toast in most use cases.


package mobi.glowworm.lib.ui.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.Nullable;
import android.widget.Toast;

import java.lang.ref.WeakReference;

/**
* {@link Toast} decorator allowing for easy cancellation of notifications. Use this class if you
* want subsequent Toast notifications to overwrite current ones. </p>
* <p/>
* By default, a current {@link Boast} notification will be cancelled by a subsequent notification.
* This default behaviour can be changed by calling certain methods like {@link #show(boolean)}.
*/
public class Boast {
/**
* Keeps track of certain Boast notifications that may need to be cancelled. This functionality
* is only offered by some of the methods in this class.
* <p>
* Uses a {@link WeakReference} to avoid leaking the activity context used to show the original {@link Toast}.
*/
@Nullable
private volatile static WeakReference<Boast> weakBoast = null;

@Nullable
private static Boast getGlobalBoast() {
if (weakBoast == null) {
return null;
}

return weakBoast.get();
}

private static void setGlobalBoast(@Nullable Boast globalBoast) {
Boast.weakBoast = new WeakReference<>(globalBoast);
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Internal reference to the {@link Toast} object that will be displayed.
*/
private Toast internalToast;

// ////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Private constructor creates a new {@link Boast} from a given {@link Toast}.
*
* @throws NullPointerException if the parameter is <code>null</code>.
*/
private Boast(Toast toast) {
// null check
if (toast == null) {
throw new NullPointerException("Boast.Boast(Toast) requires a non-null parameter.");
}

internalToast = toast;
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Make a standard {@link Boast} that just contains a text view.
*
* @param context The context to use. Usually your {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param text The text to show. Can be formatted text.
* @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or
* {@link Toast#LENGTH_LONG}
*/
@SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text, int duration) {
return new Boast(Toast.makeText(context, text, duration));
}

/**
* Make a standard {@link Boast} that just contains a text view with the text from a resource.
*
* @param context The context to use. Usually your {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param resId The resource id of the string resource to use. Can be formatted text.
* @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or
* {@link Toast#LENGTH_LONG}
* @throws Resources.NotFoundException if the resource can't be found.
*/
@SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId, int duration)
throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, duration));
}

/**
* Make a standard {@link Boast} that just contains a text view. Duration defaults to
* {@link Toast#LENGTH_SHORT}.
*
* @param context The context to use. Usually your {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param text The text to show. Can be formatted text.
*/
@SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text) {
return new Boast(Toast.makeText(context, text, Toast.LENGTH_SHORT));
}

/**
* Make a standard {@link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {@link Toast#LENGTH_SHORT}.
*
* @param context The context to use. Usually your {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param resId The resource id of the string resource to use. Can be formatted text.
* @throws Resources.NotFoundException if the resource can't be found.
*/
@SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId) throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, Toast.LENGTH_SHORT));
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Show a standard {@link Boast} that just contains a text view.
*
* @param context The context to use. Usually your {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param text The text to show. Can be formatted text.
* @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or
* {@link Toast#LENGTH_LONG}
*/
public static void showText(Context context, CharSequence text, int duration) {
Boast.makeText(context, text, duration).show();
}

/**
* Show a standard {@link Boast} that just contains a text view with the text from a resource.
*
* @param context The context to use. Usually your {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param resId The resource id of the string resource to use. Can be formatted text.
* @param duration How long to display the message. Either {@link Toast#LENGTH_SHORT} or
* {@link Toast#LENGTH_LONG}
* @throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId, int duration)
throws Resources.NotFoundException {
Boast.makeText(context, resId, duration).show();
}

/**
* Show a standard {@link Boast} that just contains a text view. Duration defaults to
* {@link Toast#LENGTH_SHORT}.
*
* @param context The context to use. Usually your {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param text The text to show. Can be formatted text.
*/
public static void showText(Context context, CharSequence text) {
Boast.makeText(context, text, Toast.LENGTH_SHORT).show();
}

/**
* Show a standard {@link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {@link Toast#LENGTH_SHORT}.
*
* @param context The context to use. Usually your {@link android.app.Application} or
* {@link android.app.Activity} object.
* @param resId The resource id of the string resource to use. Can be formatted text.
* @throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId) throws Resources.NotFoundException {
Boast.makeText(context, resId, Toast.LENGTH_SHORT).show();
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Close the view if it's showing, or don't show it if it isn't showing yet. You do not normally
* have to call this. Normally view will disappear on its own after the appropriate duration.
*/
public void cancel() {
internalToast.cancel();
}

/**
* Show the view for the specified duration. By default, this method cancels any current
* notification to immediately display the new one. For conventional {@link Toast#show()}
* queueing behaviour, use method {@link #show(boolean)}.
*
* @see #show(boolean)
*/
public void show() {
show(true);
}

/**
* Show the view for the specified duration. This method can be used to cancel the current
* notification, or to queue up notifications.
*
* @param cancelCurrent <code>true</code> to cancel any current notification and replace it with this new
* one
* @see #show()
*/
public void show(boolean cancelCurrent) {
// cancel current
if (cancelCurrent) {
final Boast cachedGlobalBoast = getGlobalBoast();
if ((cachedGlobalBoast != null)) {
cachedGlobalBoast.cancel();
}
}

// save an instance of this current notification
setGlobalBoast(this);

internalToast.show();
}

}

How to kill Toast after exit app?

We can't kill toast when application closes. We can use toast like below code. Toast.LENGTH_SHORT).show(); less duration of toast when your app closes.

Toast.makeText(this, "Press again to exit.. ", Toast.LENGTH_SHORT).show();

Or, you can set Duration of Toast by code below:

Toast toast = Toast.makeText(getApplicationContext(), "Press again to exit..", Toast.LENGTH_SHORT);

toast.show();

Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
toast.cancel();
}
}, 500);

Or, you can use this :

  private Toast toast = null;
toast = Toast.makeText(getApplicationContext(), "", Toast.LENGTH_SHORT);

@Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
//Toast.makeText(this, "Press again to exit..", Toast.LENGTH_SHORT).show();
toast.setText("Press again to exit..");
toast.show();
new Handler().postDelayed(new Runnable() {

@Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}

@Override
protected void onStop () {
super.onStop();
toast.cancel();

}

How to stop displaying message from Toast when Application is closed?

I want if the application is closed then Toast should also stop displaying the message.

In your case call cancel() to Toast object to cancel it within onDestroy() method.

Here is a similar example.

Updated!

I tested OP solution but no result.

.hide() and .cancel() method is available for Toast but seem they are not working. The solution is, you have to create your own custom view which acts like a Toast and then you can cancel all Toasts when the Activity finishes.

Can I cancel previous Toast when I want to show an other Toast?

You need to call method on correct object.

toastObject.cancel()

Cancel a toast android

You have many Toast because they are created in a loop. You just have to cancel them in the onDestroy.

...
mPendingToasts.clear();
for (int pnum = 0; pnum < procInfos.size(); pnum++) {
...
Toast toast = new Toast(getApplicationContext());
...
mPendingToasts.add(toast);
toast.show();

}
}

private ArrayList<Toast> mPendingToasts = new ArrayList<Toast>();
@Override
protected void onDestroy() {
for(Toast toast:mPendingToasts){
toast.cancel();
}
super.onDestroy();

}

Be aware that cancelling the Toast will just prevent them from being shown. The logic in your loop (i.e. killing proc) will be executed anyway. (i.e. showing a Toast is asynchronous)

How to cancel Toast

Toast.makeText returns a Toast object. Call cancel() on this object to cancel it.

Stop all toast messages when going to another screen in Android

Hi I have the same problem. The problem is that the Toast overlaps e.g. if you press 10 times the Toast will stay 10 x LENGTH_SHORT. The only solution I came with was to control the time the Toast is shown by myself. When you show a Toast just keep a track of the last time you show it, it's still on the screen don't show it again. In your worst case the Toast will be visible only LENGTH_SHORT time.



Related Topics



Leave a reply



Submit