Doug
Doug

Reputation: 313

BadTokenException on custom Dialog.show()

Im trying to show a custom dialog and this runtime error pops up depending on the parameters I pass when calling my Confirmation dialog .show() method.

The error log is:

04-16 09:45:03.148: E/AndroidRuntime(13540): FATAL EXCEPTION: main
04-16 09:45:03.148: E/AndroidRuntime(13540): Process: com.moymer, PID: 13540
04-16 09:45:03.148: E/AndroidRuntime(13540): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.view.ViewRootImpl.setView(ViewRootImpl.java:554)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:259)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.app.Dialog.show(Dialog.java:286)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at com.moymer.fragments.AmigosFragmentNovo.showDialogDesfazerAmizade(AmigosFragmentNovo.java:2006)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at com.moymer.fragments.AmigosFragmentNovo$12.onItemLongClick(AmigosFragmentNovo.java:959)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.widget.AbsListView.performLongPress(AbsListView.java:2979)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:2928)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.os.Handler.handleCallback(Handler.java:733)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.os.Handler.dispatchMessage(Handler.java:95)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.os.Looper.loop(Looper.java:136)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at android.app.ActivityThread.main(ActivityThread.java:5086)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at java.lang.reflect.Method.invokeNative(Native Method)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at java.lang.reflect.Method.invoke(Method.java:515)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
04-16 09:45:03.148: E/AndroidRuntime(13540):    at dalvik.system.NativeStart.main(Native Method)

And this is the method setting up the dialogs on my controller.

    public void showDialogDesfazerAmizade(Usuario usuarioRemoverAdapter)
{

    usuarioRemover = usuarioRemoverAdapter;

    confirmacaoDesfazerAmizade = new Confirmacao(superContext,
            "Você deseja mesmo desfazer amizade com", "Desfazer amizade",
            usuarioRemover.getNome().toString());

    confirmacaoDesfazerAmizadeBtns = new ConfirmacaoBtns()
    {
        @Override
        public void positiveBtnClicked()
        {

            if (usuarioLogado != null
                    && usuarioLogado.getIdmoymer() != null
                    && usuarioRemover != null
                    && usuarioRemover.getIdmoymer() != null)
            {
                RemoveAmigoAsyncTask removeAmigoAsyncTask = new RemoveAmigoAsyncTask(
                        AmigosFragmentNovo.this, superContext, 0,
                        usuarioLogado.getIdmoymer(),
                        usuarioRemover.getIdmoymer(), usuarioRemover);
                removeAmigoAsyncTask
                        .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                listaAsyncTasks.add(removeAmigoAsyncTask);
            }

        }

        @Override
        public void negativeBtnClicked()
        {
            if (confirmacaoDesfazerAmizade != null
                    && confirmacaoDesfazerAmizade.isShowing())
            {
                confirmacaoDesfazerAmizade.dismiss();
            }
        }
    };

    confirmacaoDesfazerAmizade
            .setBtnsControl(confirmacaoDesfazerAmizadeBtns);

    if (confirmacaoDesfazerAmizade != null
            && !confirmacaoDesfazerAmizade.isShowing())
    {
        confirmacaoDesfazerAmizade.show();
    }

}

And this is the Confirmation custom dialog.

public class Confirmacao extends Dialog implements android.view.View.OnClickListener {

public Context c;
public Dialog d;
public LinearLayout acaoLL, cancelarLL, perguntaLL;
private String pergunta;
private String perguntaBold;
private String tituloAcao;

private ConfirmacaoBtns btnsControl;

private TextView acaoTV;
private TextView perguntaTV;
private TextView pergunta_boldTV;

public Confirmacao(Context context, String pergunta, String tituloAcao) 
{
    super(context);
    this.tituloAcao = tituloAcao;
    if(pergunta != null)
        this.pergunta = pergunta;
    this.c = context;
}   

public Confirmacao(Context context, String pergunta, String tituloAcao, String perguntaBold) 
{
    super(context);
    this.tituloAcao = tituloAcao;
    if(pergunta != null)
        this.pergunta = pergunta;
    if(perguntaBold != null)
        this.perguntaBold = perguntaBold;
    this.c = context;
}   

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.confirmacao);
    getWindow().setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));  

    acaoLL = (LinearLayout) findViewById(R.id.confirmacao_acao);
    cancelarLL = (LinearLayout) findViewById(R.id.confirmacao_cancelar);
    perguntaLL = (LinearLayout) findViewById(R.id.pergunta_layout);

    Typeface openSansRegular = Typeface.createFromAsset(c.getAssets(), Font.OPENSANS_REGULAR);
    Typeface openSansBold = Typeface.createFromAsset(c.getAssets(), Font.OPENSANS_BOLD);

    acaoTV = (TextView)findViewById(R.id.confirmacao_acao_tv);
    acaoTV.setTypeface(openSansRegular);

    perguntaTV = (TextView)findViewById(R.id.pergunta);
    perguntaTV.setTypeface(openSansRegular);

    pergunta_boldTV = (TextView) findViewById(R.id.pergunta_bold);

    if(perguntaBold != null)
    {   
        pergunta_boldTV.setTypeface(openSansRegular);
        pergunta_boldTV.setText(Html.fromHtml("<b>" + (perguntaBold) + "</b>" + "?"));
    }else
        pergunta_boldTV.setVisibility(View.GONE);

    acaoTV.setTypeface(openSansRegular);
    perguntaTV.setTypeface(openSansRegular);

    if(this.tituloAcao!=null)
        acaoTV.setText(this.tituloAcao);
    if(this.pergunta!=null)
        perguntaTV.setText(this.pergunta);
    else
        perguntaLL.setVisibility(View.GONE);

    acaoLL.setOnClickListener(this);
    cancelarLL.setOnClickListener(this);

    showDialogOnScreenBottom();
}

private void showDialogOnScreenBottom() {
    Window window = getWindow();
    WindowManager.LayoutParams wlp = window.getAttributes();

    wlp.width = LayoutParams.MATCH_PARENT;
    wlp.height = LayoutParams.MATCH_PARENT;
    wlp.gravity = Gravity.BOTTOM;
    wlp.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
    window.setAttributes(wlp);      
}

public void setBtnsControl(ConfirmacaoBtns btnsControl) 
{
    this.btnsControl = btnsControl;
}

@Override
public void onClick(View v) 
{
    switch (v.getId()) {
    case R.id.confirmacao_acao:
    {
        if(btnsControl!=null)
            btnsControl.positiveBtnClicked();
        dismiss();


        break;
    }
    case R.id.confirmacao_cancelar:
    {
        if(btnsControl!=null)
            btnsControl.negativeBtnClicked();
        dismiss();
        break;
    }
    default:
        break;
    }
    dismiss();
}

public void negativeButtonGone()
{
    cancelarLL.setVisibility(View.GONE);
}

public interface ConfirmacaoBtns
{
    public void positiveBtnClicked();
    public void negativeBtnClicked();

}   
}

Upvotes: 1

Views: 535

Answers (3)

Don Chakkappan
Don Chakkappan

Reputation: 7560

The issue is with your Context passing into confirmation dialogue.Try this

confirmacaoDesfazerAmizade = new Confirmacao(CurrentActivity.this,
            "Você deseja mesmo desfazer amizade com", "Desfazer amizade",
            usuarioRemover.getNome().toString());

For fragments getActivity() instead CurrentActivity.this

Upvotes: 0

Doug
Doug

Reputation: 313

The issue was the Context as Fede Bucich and Don Chakkappan answered, but it wasnt possible to reference the activity by its name as 'ActivityName.this' because the method is inside a fragment. So the right answer is to use getActivity() instead of Context:

confirmacaoDesfazerAmizade = new Confirmacao(getActivity(),
        "Você deseja mesmo desfazer amizade com", "Desfazer amizade",
        usuarioRemover.getNome().toString());

Upvotes: 1

arlistan
arlistan

Reputation: 741

I don't know what your superContext variable is, but try sending MyActivityName.this as the Context.

You could also try assigning MyActivityName.this to your superContext variable when your activity starts up.

Upvotes: 0

Related Questions