Creating Global Dialogs

I was trying to find a way to create dialogs for the Android user! Just to surprise him! It would be really fun to do so I guess.

To keep things simple, I do not want to build a new Android OS!

I just want to do this with what I have available.


VIDEO:


How will this be done!
  • Create an invisible Activity .
  • Make this activity show the dialog.
The user will not know of this Activity's existence obviously because it is invisible!

To start! let's create the invisible activity:

  1. Create your new Activity class and call it SuperDialog
  2. Inside /SuperDialog.java
    public class SuperDialog extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    }
    
  3. Declare SuperDialog inside your manifest
  4. Inside /AndroidManifest.xml (in <application>)
    <activity android:name=".SuperDialog"
                      android:label="@string/app_name" android:theme="@style/Theme.Transparent">
              </activity>
    
    Now We have our transparent activity! Great! Lets add some dialogs My idea was to create a static function that will show dialogs and here it is
  5. Declare static inside SuperDialog to create dialogs using it
  6. Inside /SuperDialog class
    public static void createDialog(int dialog, Context context){
         Intent myIntent = new Intent(context, SuperDialog.class);
         Bundle bundle = new Bundle();
         bundle.putInt("dialog", dialog);
         myIntent.putExtras(bundle);
         myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      context.startActivity(myIntent);
        }
    
    Notice that this function not only will start the activity but will also send a bundle that contains an integer! This integer will actually answer the SuperDialog when it asks: Which dialog am I supposed to show! Now let's catch this bundle onCreate of the activity and get this integer value. I will show you how to use this integer shortly.
  7. Get the integer of the bundle in the onCreate() of SuperDialog
  8. Inside /SuperDialog class (edit the onCreate() as follows)
    @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            showDialog(this.getIntent().getExtras().getInt("dialog"));
        }
    
    Ok now we used the showDialog method using the integer passed. I hope it is clear that this.getIntent().getExtras().getInt("dialog") will return the integer which was passed using the static function. Now lets
  9. define some dialogs (as integers)
  10. Inside /SuperDialog class
     public final static int DIALOG_1 = 0;
     public final static int DIALOG_2 = 1;
     public final static int DIALOG_3 = 2;
     public final static int DIALOG_4 = 3;
     public final static int DIALOG_ERROR = 4;
    
    Now Bingo! we call the static method in this way: SuperDialog.createDialog(SuperDialog.DIALOG_1, myContext)! Now we have this function showDialog() called in the onCreate using one of our static integers! This function will call in the execution protected Dialog onCreateDialog(int id) which obviously takes the int that we passed as an argument The function onCreateDialog returns a dialog to be shown
  11. Declare the onCreateDialog(ind id)
  12. Inside /SuperDialog class
    protected Dialog onCreateDialog(int id) {
      Dialog dialog;
      switch(id) {
      case DIALOG_1:
       //create dialog1
       dialog = null;
      break;
      case DIALOG_2:
       //create dialog2
       dialog = null;
       break;
      case DIALOG_3:
       //create dialog3
       dialog = null;
       break;
      case DIALOG_4:
       //create dialog4
       dialog = null;
       break;
      case DIALOG_ERROR:
       //create dialog
       dialog = new AlertDialog.Builder(this).setMessage("ERROR! This is a global dialog\n Brought to you by Sherif").create();
       break;
      default:
       //create a default dialog
       dialog = null;
      }
      return dialog;
     }
    
    Notice that I only create one AlertDialog and the others are all null. You could add/delete as much as you need of the dialogs ... Do what suit you.

Congratz! You class now works fine and you can call it from "a service" to show a dialog.

However one last trick and one last remark are needed:

Inside /SuperDialog class
public class SuperDialog extends Activity implements DialogInterface.OnCancelListener {
@Override
 public void onCancel(DialogInterface arg0) {
  // THIS IS VERY IMPORTANT TO REMOVE THE ACTIVITY WHEN THE DIALOG IS DISMISSED
  // IF NOT ADDED USER SCREEN WILL NOT RECEIVE ANY EVENTS BEFORE USER PRESSES BACK
  finish();
 }
}

AND INSIDE YOUR protected Dialog onCreateDialog(int id)

Add the following line just before returning the dialog:
  dialog.setOnCancelListener(this);
  return dialog;

Why?! simply because we want the Invisible Activity to go away when the dialog is canceled! In my case I used CANCEL! so if you want to dismiss a dialog you created using a button, use cancel!

Please keep in mind that if you forgot to finish() the invisible activity when the dialog is canceled! ;) the user will keep seeing normally but his touches will do nothing! (until he presses back or home or sth)

Full code:
/AndroidManifest.xml
<activity android:name=".SuperDialog"
                  android:label="@string/app_name" android:theme="@style/Theme.Transparent">
          </activity>
/res/value/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <style name="Theme.Transparent" parent="android:Theme">
  <item name="android:windowIsTranslucent">true</item>
  <item name="android:windowBackground">@android:color/transparent</item>
  <item name="android:windowContentOverlay">@null</item>
  <item name="android:windowNoTitle">true</item>
  <item name="android:windowIsFloating">true</item>
  <item name="android:backgroundDimEnabled">false</item>
 </style>
</resources>

/SuperDialog.java
package sherif.android.core;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;


/**
 * @author Sherif
 * 
 * Use this class to create Dialogs
 * 
 * Add as much dialogs as you want
 * 
 * Finally call SuperDialog.createDialog to create a dialog from anywhere
 *
 */
public class SuperDialog extends Activity implements DialogInterface.OnCancelListener {

 //Edit these : Add as much dialogs as you want
 public final static int DIALOG_1 = 0;
 public final static int DIALOG_2 = 1;
 public final static int DIALOG_3 = 2;
 public final static int DIALOG_4 = 3;
 public final static int DIALOG_ERROR = 4;
 
 //Now edit this function
    protected Dialog onCreateDialog(int id) {
  Dialog dialog;
  switch(id) {
  case DIALOG_1:
   //create dialog1
   dialog = null;
  break;
  case DIALOG_2:
   //create dialog2
   dialog = null;
   break;
  case DIALOG_3:
   //create dialog3
   dialog = null;
   break;
  case DIALOG_4:
   //create dialog4
   dialog = null;
   break;
  case DIALOG_ERROR:
   //create dialog
   dialog = new AlertDialog.Builder(this).setMessage("ERROR! This is a global dialog\n Brought to you by Sherif").create();
   break;
  default:
   //create a default dialog
   dialog = null;
  }
  dialog.setOnCancelListener(this);
  return dialog;
 }
    
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        showDialog(this.getIntent().getExtras().getInt("dialog"));
    }
 @Override
 public void onCancel(DialogInterface arg0) {
  // THIS IS VERY IMPORTANT TO REMOVE THE ACTIVITY WHEN THE DIALOG IS DISMISSED
  // IF NOT ADDED USER SCREEN WILL NOT RECEIVE ANY EVENTS BEFORE USER PRESSES BACK
  finish();
 }
    /**
     * @author Sherif
     * @param dialog The dialog you want to show
     * @param context The context from which you are calling
     * 
     * this function will create a global dialog for you
     * the dialog will appear no matter which activity or screen is showing
     */
    public static void createDialog(int dialog, Context context){
     Intent myIntent = new Intent(context, SuperDialog.class);
     Bundle bundle = new Bundle();
     bundle.putInt("dialog", dialog);
     myIntent.putExtras(bundle);
     myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  context.startActivity(myIntent);
    }
}

Click here for Sample Project + Source Code (download)

Click here for Sample Project + Source Code (github)

2 comments:

  1. very tricky,man.but great job! I use it in my tiny toy.Thank you.

    ReplyDelete