0

I would like to show the user a message, if something went wrong in a network communication thread.

For this reason it´s necessary to show a dialog from a handler.

Is this the right way?, because I have found no way, how to get a FragmentManager within the handler class.

class ErrorMessageHandler extends Handler
{
    @Override
    public void handleMessage(Message msg) 
    {
        super.handleMessage(msg);

        AlertDialogFragment dialog = new AlertDialogFragment((String) msg.getData().get("MESSAGE"));

        dialog.show(FragmentManager, TAG)

     }  

}
A--C
  • 36,351
  • 10
  • 106
  • 92
Chris
  • 521
  • 1
  • 5
  • 14

3 Answers3

1

After a while I found a really simple solution:

You have to implement this method in your Service class:

void alert(String message) 
{
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(getApplication());
    alertDialog.setMessage(message);
    alertDialog.setNeutralButton("OK", null);
    alertDialog.create().show();
}

Sometimes it can be really easy :)

Chris
  • 521
  • 1
  • 5
  • 14
0

Why not displaying a simple toast message with, as string, the error message you got (or any other message you would like to set)

Maybe i misunderstood your question but for me, it seems to be logical. I am using simple toasts for displaying network error messages or whatewer.

Toast.makeText(context, text, duration).show();

Following your coments, another solution can be suggested:

On error, display a confirm dialog (AlertDialog) and give the possibility to the user to select if he would like to read the help:

    new AlertDialog.Builder(this)
    .setTitle("Network Error")
    .setMessage(An error occured, would you like to read the help section ...)
    .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
          // Open here the new view with the help message etc.
        }

    })
    .setNegativeButton(R.string.no, null)
    .show();

So, in this case, you will not bother the user with long help text immediately. You will first tell him that there were an error produced and if he would like to read the help on how to resolve the issue, he can confirm and go further. This can be good for the designt of your app because, usually, users don't like to read big quantities of text, especialy not some help instructions.

At the end, you can display your Alertdialog with a short error message and propose to check the help. In there, you can invite him to check if his internet connection is enabled, explain how to enable, propose a button to go directly to the page of your phone where he can enable / disable the wifi etc.

Milos Cuculovic
  • 19,631
  • 51
  • 159
  • 265
  • I thought this way before, but I would like to give the user a few suggestions, how he can solve the problem (for example enabling the Wlan). Short: the text I want to show is too long for a toast. – Chris Jan 28 '13 at 14:25
  • What you can to: Display a confirmation dialog with on it the error message and the question if the user would like to read the help. If he clicks ok, then you can display another view with the apropriate help. If he clicks no (or cancel), then simply close the dialog. – Milos Cuculovic Jan 28 '13 at 14:33
  • That seems to be a nice way! I tried this out but unfortunately my app crashes if I do so. I try to open this within a service. Is this possible too, or is this the reason for the crash? – Chris Jan 28 '13 at 14:54
  • It is possible to show a dialog from a service: see here http://stackoverflow.com/questions/4131619/alertdialog-show-silently-ignored-within-a-service What kind of crash are you facing, can you give some logs. Or simply, display the dialog from your main thread if possible. It will be much easier. – Milos Cuculovic Jan 28 '13 at 14:58
  • This is the error: 01-28 15:01:33.725: E/AndroidRuntime(3732): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application 01-28 15:01:33.725: E/AndroidRuntime(3732): at android.view.ViewRootImpl.setView(ViewRootImpl.java:571) 01-28 15:01:33.725: E/AndroidRuntime(3732): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:246) 01-28 15:01:33.725: E/AndroidRuntime(3732): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) – Chris Jan 28 '13 at 15:04
  • The problem in this case is that you are trying to create Dialog with an application context. The dialog should be created with the Activity context: "MyActivity.this", where MyActivity is te name of your activity. – Milos Cuculovic Jan 28 '13 at 15:15
  • You cant refer in a service to an activity (in this way). There a "no enclosing instance" error appears. I am working on a solution including a messenger. I hope this works. I will post my solution, if i have one. – Chris Jan 28 '13 at 15:40
0

So... I have found a way how to solve this issue, but it´s not the perfect way (Further details are on the bottom of this answer).

First create a Messenger:

private Messenger AlertDialogMessenger = new Messenger(new AlertDialogMessageHandler());

Second a handler, which shows up this dialog:

class AlertDialogMessageHandler extends Handler
{

    @Override
    public void handleMessage(Message msg) 
    {
        super.handleMessage(msg);

        AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).create();

        dialog.setTitle("Attention");
        dialog.setMessage((CharSequence) msg.getData().get("MESSAGE"));
        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() 
        {               
            @Override
            public void onCancel(DialogInterface dialog) 
            {
                //Do something
            }
        });
        dialog.setButton(DialogInterface.BUTTON_NEUTRAL, "OK", new DialogInterface.OnClickListener() 
        {               
            @Override
            public void onClick(DialogInterface dialog, int which) 
            {
                //Do something
                dialog.dismiss();
            }
        });

        dialog.show();                              
    }

}

And then you just have to send the messenger to to service:

Intent intent = new Intent(this,MyService.class);
intent.putExtra(MainActivity.EXTRA_FROM_SERVICE_MESSENGER, this.AlertDialogMessenger);
this.bindService(intent, this.conn, Context.BIND_AUTO_CREATE);

At the Service you have to catch the messenger:

@Override
public IBinder onBind(Intent intent) 
{       
    this.AlertDialoMessenger = intent.getParcelableExtra(MainActivity.EXTRA_FROM_SERVICE_MESSENGER);
    return null;
}

And then you can show up the dialog by sending a message:

Message msg = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("MESSAGE", "This is a test message");

msg.setData(bundle);
try 
{
    AlertDialoMessenger.send(msg);
} 
catch (RemoteException e1) 
{
    e1.printStackTrace();
}

And that´s it.

Unfortunately I can´t use this in my case because this is only working, if you have only one Activity (In this case the MainActivity). Because the Dialog will be only showed up in this Activity.

In my project I have more Activities and so it makes no sense to use this.

I decided to show up a short toast message like "Network error" and provide a help page in the OptionsMenu.

Thanks to Milos! and I hope this code helps somebody sometimes :)

Chris
  • 521
  • 1
  • 5
  • 14