Apps

Android Jelly Bean ate my toast, the sequel: Revenge of the toast

If you miss toast messages in Android 4.2, follow this tutorial to learn how to create your own.

I recently wrote about my disappointment over Google's decision to allow users to turn off toast messages as of Android 4.2 (Jelly Bean). I vowed never to use toast messages again. The problem is, I really like toast messages. That got me thinking.

If a toast message is nothing more than a foreground window displayed at an arbitrary location, why couldn't I create my own toast messages? It turns out I can, and now so can you. Feel free to follow along with this tutorial, or, download and import the entire project into Eclipse.

1. Start a new Android project. Be sure to target Android 1.6 or better. Rename the startup activity to Main.java and the corresponding layout to main.xml.

2. In our /res folder, we will create a linear layout that contains two buttons.

main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center" >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Homemade Toast"
        android:id="@+id/homemade_toast_button"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Standard Toast"
        android:id="@+id/standard_toast_button"/>
</LinearLayout>

3. In our /src folder, we begin Main.java by extending the standard application class and implementing the on click listener interface.

Main.java
package com.authorwjf.revengeoftoast;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.graphics.Color;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
public class Main extends Activity implements OnClickListener {
       private PopupWindow popUp=null;
       private Handler h = null;
       private static final int WIDTH = 300;
       private static final int HEIGHT = 80;
       private static final int ONE_SECOND = 1000;
}

4. Override the on create function and wire up our listener to the buttons.

@Override
protected void onCreate(Bundle savedInstanceState) {  
super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       h = new Handler();
findViewById(R.id.homemade_toast_button).setOnClickListener(this);
       findViewById(R.id.standard_toast_button).setOnClickListener(this);
}

5. Finally, the implementation for the on click listener.

@Override
synchronized public void onClick(View v) {
      if (v.getId()==R.id.standard_toast_button) {
                     Toast.makeText(this, "Plain old toast",
Toast.LENGTH_SHORT).show();
      } else {
             if (popUp == null) {
                    popUp = new PopupWindow(this);
                    LinearLayout layout = new LinearLayout(this);
                    LayoutParams params = new
LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
                    layout.setOrientation(LinearLayout.VERTICAL);
                    layout.setGravity(Gravity.CENTER);
layout.setBackgroundColor(Color.DKGRAY);
                    TextView tv = new TextView(this);
                    tv.setTextColor(Color.WHITE);
tv.setTextSize(12);
                    tv.setText("Revenge of toast messages!");
                    layout.addView(tv, params);
                    popUp.setContentView(layout);
                    popUp.showAtLocation(layout, Gravity.BOTTOM, 10, 10);
                    popUp.setAnimationStyle(android.R.style.Animation_Toast);
                    popUp.update(0, 50, WIDTH, HEIGHT);
                    h.postDelayed(new Runnable() {
                           @Override
                           public void run() {
                                  popUp.dismiss();
                                  popUp=null;
                           }
                }, ONE_SECOND);
          }
     }
}

Now you are ready to see the power of the popup. Make sure you load the APK to a device or emulator that is running Android 4.2. From the Settings | Applications menu, turn off notifications and then give the buttons a try. Don't believe it? Toggle the notifications setting back and try again. You can't keep a good toast message down!

About

William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intellige...

2 comments
dounowhoiam
dounowhoiam

Unless your app is disabling the ability to stop notifications messages (such as The Simpsons Tapped Out) or is sending push adverts, there is no need for a user to disable the notifications and then it is the fault of the app developer if another type of notification does not work.

authorwjf
authorwjf

I am with you. There is no reason for a user to disable notifications. But the fact remains that a user can as of Jellybean. And more importantly and inexplicably the notifications flag seems to be tied to toast messages ( a type of common dialog). So disabling notifications means toast messages get disabled as well, even local ones which have nothing to do with push notifications and the notification bar.

Editor's Picks