7

My Problem is similar to this 2 year old question, I am just re posting the same problem to get the updated answers, since a lot has changed in two years.

I am developing for an app for GingerBread+ devices, I have many activities and in background I receive some data from the server. Now based on that data in some cases I need to show a Dialog to the user. Problem is How do I know which the current front most activity ?

What I tried, I have tried giving the getApplicationContext() while Dialog creation, however that is not working. Throwing some exception.

A solution ? (I really hate it), A solution could be to keep track of the currently visible activity by having a variable in Application class, and setting it on onResume() of each activity. I really don't want to do this book keeping if their are smarter ways to achieve this and I am sure their are smarter ways to achieve this,

My simple question is,
How can I display a dialog on Currently visible activity ?, So that I can give that reference to the AlertDialog.Builder, which I think will do my job.. If not than How I can display a dialog on topmost Activity ?

Edit, I create a simple dialog using following code private View.OnClickListener cancelClickListener = new OnClickListener() {

    @Override
    public void onClick(View v) {
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                LoginActivity.this);

        // set title
        alertDialogBuilder.setTitle("Roobroo will exit..");

        // set dialog message
        alertDialogBuilder
                .setMessage("Are you sure you want to exit ?")
                .setCancelable(false)
                .setPositiveButton("Yes",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int id) {
                                // if this button is clicked, close
                                // current activity
                                LoginActivity.this.finish();
                            }
                        })
                .setNegativeButton("No",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int id) {
                                // if this button is clicked, just close
                                // the dialog box and do nothing
                                dialog.cancel();
                            }
                        });

        // create alert dialog
        AlertDialog alertDialog = alertDialogBuilder.create();

        // show it
        alertDialog.show();
        // TODO Write the code to exit from the app, (gracefull exit)
        Log.i(LOG_CAT, "Cancel Button is clicked");
    }
};

Exception using AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( getApplicationContext()); gives me following exception,

06-11 14:09:16.732: E/AndroidRuntime(1005): FATAL EXCEPTION: main
06-11 14:09:16.732: E/AndroidRuntime(1005): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.view.ViewRoot.setView(ViewRoot.java:531)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.app.Dialog.show(Dialog.java:241)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at com.mycompany.myapp.activities.LoginActivity$3.onClick(LoginActivity.java:127)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.view.View.performClick(View.java:2485)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.view.View$PerformClick.run(View.java:9080)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.os.Handler.handleCallback(Handler.java:587)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.os.Handler.dispatchMessage(Handler.java:92)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.os.Looper.loop(Looper.java:123)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at android.app.ActivityThread.main(ActivityThread.java:3683)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at java.lang.reflect.Method.invokeNative(Native Method)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at java.lang.reflect.Method.invoke(Method.java:507)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
06-11 14:09:16.732: E/AndroidRuntime(1005):     at dalvik.system.NativeStart.main(Native Method)
Amit
  • 13,134
  • 17
  • 77
  • 148
  • What exception are you getting with getApplicationContext()? – Raghav Sood Jun 12 '12 at 10:28
  • please show some code . What ever you have done so far? – Dhruvisha Jun 12 '12 at 10:29
  • Well, you can bring an extra activity that is transparent and can show dialog on that activity.Write all codes for the dialog in the activity and whenever you need to show dialog just bring the activity in front. – Rasel Jun 12 '12 at 10:36
  • @Rasel, that may work, but is that the only way to display my dialog to the user ? I am sure their must be some clearer approach to do this simple task. I am sure their must be.. – Amit Jun 12 '12 at 10:42
  • check this out http://stackoverflow.com/questions/3393908/how-to-get-any-identifier-of-the-topmost-activity/26308339#26308339 – Mojtaba Yeganeh Oct 10 '14 at 21:37

3 Answers3

6

Try this if it helps you:

1. Create a Activity with transparent theme and no title.

2. In onCreate() define your alert dialog.

3. Starting this activity from broadcastReceiver will show the alert dialog.

Vineet Shukla
  • 23,865
  • 10
  • 55
  • 63
4

Simply you can create an Activity and set its theme to Dialog in manifest like this :

  <activity
        android:name="Dialog_MsgBox"
        android:launchMode="singleInstance"
        android:theme="@android:style/Theme.Dialog" >
    </activity>

also set launchMode to singleInstance to prevent multiple instance of activity. use whatever layout you want to use for your dialog.

To set different messages, put extra string messages and get them at you Dialog(activity) start up.

Vipul Purohit
  • 9,807
  • 6
  • 53
  • 76
2

Not the best solution but it worked for me..

I created an abstract class MyActivity which extends Activity and placed the setter calls in side OnResume and OnPause of this class. All other activities of my Application simply extend this Custom super class instead of Activity.

Then I created a variable of this class in Application class,

private Activity currentOnTopActivity;

I set/reset this variable inside onResume() and onPause() of MyActivity class.

That done, Whenever I want to show a Dialog to the user, I just do following...

   if (currentOnTopActivity!=null && !currentOnTopActivity.isFinishing()) {
                currentOnTopActivity.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        String msg = "Some msg";
                        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(currentOnTopActivity);
                        AlertDialog invitationDialog = null;

                        // set title
                        alertDialogBuilder.setTitle("Title ");

                        // set dialog message
                        alertDialogBuilder.setMessage(msg).setCancelable(false).setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                         // do something                            }
                        });

                        // create alert dialog
                        invitationDialog = alertDialogBuilder.create();

                        // show it on UI Thread
                        invitationDialog.show();

                    }

                });
            }

Intdroducing a Super Activity class also gives me the flexibility to place common code in this abstract class instead of duplicating that in every other Activity.

Amit
  • 13,134
  • 17
  • 77
  • 148
  • 1
    Dear Downvoter please provide a better way... I am still waiting for the best answer... – Amit Sep 26 '12 at 05:45
  • I didn't down vote you, but the original question contained a form of your solution and rejected it. I suspect that is why you were down voted. You're edit made the rejected solution more palatable, but it is still a form of the rejected solution listed in the original question. – Stephen M -on strike- Jul 06 '18 at 16:21
  • Thanks @StephenM, Corrected the answer to reflect that it is not the best option. Also explained the answer a bit. Accepted the correct answer. – Amit Aug 30 '19 at 20:36
  • 1
    Funny... I didn't realize until now that you were the OP. That puts things in a different light. Thanks for the question and an answer. – Stephen M -on strike- Sep 02 '19 at 18:39